Line data Source code
1 : /*
2 : * Copyright (C) 2020 Cumulus Networks, Inc.
3 : * Chirag Shah
4 : *
5 : * This program is free software; you can redistribute it and/or modify it
6 : * under the terms of the GNU General Public License as published by the Free
7 : * Software Foundation; either version 2 of the License, or (at your option)
8 : * any later version.
9 : *
10 : * This program is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 : * more details.
14 : *
15 : * You should have received a copy of the GNU General Public License along
16 : * with this program; see the file COPYING; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 : */
19 :
20 : #include <zebra.h>
21 : #include "northbound.h"
22 : #include "libfrr.h"
23 : #include "zebra_nb.h"
24 : #include "zebra/interface.h"
25 : #include "zebra/zebra_router.h"
26 : #include "zebra/debug.h"
27 : #include "printfrr.h"
28 :
29 : /*
30 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
31 : */
32 : struct yang_data *
33 0 : lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args)
34 : {
35 0 : const struct interface *ifp = args->list_entry;
36 0 : struct zebra_if *zebra_if;
37 :
38 0 : zebra_if = ifp->info;
39 :
40 0 : return yang_data_new_uint16(args->xpath, zebra_if->up_count);
41 : }
42 :
43 : /*
44 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/down-count
45 : */
46 : struct yang_data *
47 0 : lib_interface_zebra_state_down_count_get_elem(struct nb_cb_get_elem_args *args)
48 : {
49 0 : const struct interface *ifp = args->list_entry;
50 0 : struct zebra_if *zebra_if;
51 :
52 0 : zebra_if = ifp->info;
53 :
54 0 : return yang_data_new_uint16(args->xpath, zebra_if->down_count);
55 : }
56 :
57 : /*
58 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/zif-type
59 : */
60 : struct yang_data *
61 0 : lib_interface_zebra_state_zif_type_get_elem(struct nb_cb_get_elem_args *args)
62 : {
63 : /* TODO: implement me. */
64 0 : return NULL;
65 : }
66 :
67 : /*
68 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/ptm-status
69 : */
70 : struct yang_data *
71 0 : lib_interface_zebra_state_ptm_status_get_elem(struct nb_cb_get_elem_args *args)
72 : {
73 : /* TODO: implement me. */
74 0 : return NULL;
75 : }
76 :
77 : /*
78 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vlan-id
79 : */
80 : struct yang_data *
81 0 : lib_interface_zebra_state_vlan_id_get_elem(struct nb_cb_get_elem_args *args)
82 : {
83 0 : const struct interface *ifp = args->list_entry;
84 0 : struct zebra_if *zebra_if;
85 0 : struct zebra_l2info_vlan *vlan_info;
86 :
87 0 : if (!IS_ZEBRA_IF_VLAN(ifp))
88 : return NULL;
89 :
90 0 : zebra_if = ifp->info;
91 0 : vlan_info = &zebra_if->l2info.vl;
92 :
93 0 : return yang_data_new_uint16(args->xpath, vlan_info->vid);
94 : }
95 :
96 : /*
97 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vni-id
98 : */
99 : struct yang_data *
100 0 : lib_interface_zebra_state_vni_id_get_elem(struct nb_cb_get_elem_args *args)
101 : {
102 0 : const struct interface *ifp = args->list_entry;
103 0 : struct zebra_if *zebra_if;
104 0 : struct zebra_l2info_vxlan *vxlan_info;
105 :
106 0 : if (!IS_ZEBRA_IF_VXLAN(ifp))
107 : return NULL;
108 :
109 0 : zebra_if = ifp->info;
110 0 : vxlan_info = &zebra_if->l2info.vxl;
111 :
112 0 : return yang_data_new_uint32(args->xpath, vxlan_info->vni);
113 : }
114 :
115 : /*
116 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/remote-vtep
117 : */
118 : struct yang_data *
119 0 : lib_interface_zebra_state_remote_vtep_get_elem(struct nb_cb_get_elem_args *args)
120 : {
121 0 : const struct interface *ifp = args->list_entry;
122 0 : struct zebra_if *zebra_if;
123 0 : struct zebra_l2info_vxlan *vxlan_info;
124 :
125 0 : if (!IS_ZEBRA_IF_VXLAN(ifp))
126 : return NULL;
127 :
128 0 : zebra_if = ifp->info;
129 0 : vxlan_info = &zebra_if->l2info.vxl;
130 :
131 0 : return yang_data_new_ipv4(args->xpath, &vxlan_info->vtep_ip);
132 : }
133 :
134 : /*
135 : * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/mcast-group
136 : */
137 : struct yang_data *
138 0 : lib_interface_zebra_state_mcast_group_get_elem(struct nb_cb_get_elem_args *args)
139 : {
140 0 : const struct interface *ifp = args->list_entry;
141 0 : struct zebra_if *zebra_if;
142 0 : struct zebra_l2info_vxlan *vxlan_info;
143 :
144 0 : if (!IS_ZEBRA_IF_VXLAN(ifp))
145 : return NULL;
146 :
147 0 : zebra_if = ifp->info;
148 0 : vxlan_info = &zebra_if->l2info.vxl;
149 :
150 0 : return yang_data_new_ipv4(args->xpath, &vxlan_info->mcast_grp);
151 : }
152 :
153 0 : const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args)
154 : {
155 0 : struct vrf *vrf = (struct vrf *)args->parent_list_entry;
156 0 : struct zebra_router_table *zrt =
157 : (struct zebra_router_table *)args->list_entry;
158 :
159 0 : struct zebra_vrf *zvrf;
160 0 : afi_t afi;
161 0 : safi_t safi;
162 :
163 0 : zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
164 :
165 0 : if (args->list_entry == NULL) {
166 0 : afi = AFI_IP;
167 0 : safi = SAFI_UNICAST;
168 :
169 0 : zrt = zebra_router_find_zrt(zvrf, zvrf->table_id, afi, safi);
170 0 : if (zrt == NULL)
171 : return NULL;
172 : } else {
173 0 : zrt = RB_NEXT(zebra_router_table_head, zrt);
174 : /* vrf_id/ns_id do not match, only walk for the given VRF */
175 0 : while (zrt && zrt->ns_id != zvrf->zns->ns_id)
176 0 : zrt = RB_NEXT(zebra_router_table_head, zrt);
177 : }
178 :
179 : return zrt;
180 : }
181 :
182 0 : int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args)
183 : {
184 0 : const struct zebra_router_table *zrt = args->list_entry;
185 :
186 0 : args->keys->num = 2;
187 :
188 0 : snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%s",
189 0 : yang_afi_safi_value2identity(zrt->afi, zrt->safi));
190 0 : snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%u",
191 0 : zrt->tableid);
192 :
193 0 : return NB_OK;
194 : }
195 :
196 : const void *
197 0 : lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args)
198 : {
199 0 : struct vrf *vrf = (struct vrf *)args->parent_list_entry;
200 0 : struct zebra_vrf *zvrf;
201 0 : afi_t afi;
202 0 : safi_t safi;
203 0 : uint32_t table_id = 0;
204 :
205 0 : zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
206 :
207 0 : yang_afi_safi_identity2value(args->keys->key[0], &afi, &safi);
208 0 : table_id = yang_str2uint32(args->keys->key[1]);
209 : /* table_id 0 assume vrf's table_id. */
210 0 : if (!table_id)
211 0 : table_id = zvrf->table_id;
212 :
213 0 : return zebra_router_find_zrt(zvrf, table_id, afi, safi);
214 : }
215 :
216 : /*
217 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/afi-safi-name
218 : */
219 : struct yang_data *
220 0 : lib_vrf_zebra_ribs_rib_afi_safi_name_get_elem(struct nb_cb_get_elem_args *args)
221 : {
222 0 : const struct zebra_router_table *zrt = args->list_entry;
223 :
224 0 : return yang_data_new_string(args->xpath,
225 0 : yang_afi_safi_value2identity(zrt->afi, zrt->safi));
226 : }
227 :
228 : /*
229 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/table-id
230 : */
231 : struct yang_data *
232 0 : lib_vrf_zebra_ribs_rib_table_id_get_elem(struct nb_cb_get_elem_args *args)
233 : {
234 0 : const struct zebra_router_table *zrt = args->list_entry;
235 :
236 0 : return yang_data_new_uint32(args->xpath, zrt->tableid);
237 : }
238 :
239 : /*
240 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route
241 : */
242 : const void *
243 0 : lib_vrf_zebra_ribs_rib_route_get_next(struct nb_cb_get_next_args *args)
244 : {
245 0 : const struct zebra_router_table *zrt = args->parent_list_entry;
246 0 : struct route_node *rn = (struct route_node *)args->list_entry;
247 :
248 0 : if (args->list_entry == NULL)
249 0 : rn = route_top(zrt->table);
250 : else
251 0 : rn = srcdest_route_next(rn);
252 : /* Optimization: skip empty route nodes. */
253 0 : while (rn && rn->info == NULL)
254 0 : rn = route_next(rn);
255 :
256 : /* Skip link-local routes. */
257 0 : if (rn && rn->p.family == AF_INET6
258 0 : && IN6_IS_ADDR_LINKLOCAL(&rn->p.u.prefix6))
259 0 : return NULL;
260 :
261 : return rn;
262 : }
263 :
264 0 : int lib_vrf_zebra_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args)
265 : {
266 0 : const struct route_node *rn = args->list_entry;
267 :
268 0 : args->keys->num = 1;
269 0 : prefix2str(&rn->p, args->keys->key[0], sizeof(args->keys->key[0]));
270 :
271 0 : return NB_OK;
272 : }
273 :
274 : const void *
275 0 : lib_vrf_zebra_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args)
276 : {
277 0 : const struct zebra_router_table *zrt = args->parent_list_entry;
278 0 : struct prefix p;
279 0 : struct route_node *rn;
280 :
281 0 : yang_str2prefix(args->keys->key[0], &p);
282 :
283 0 : rn = route_node_lookup(zrt->table, &p);
284 :
285 0 : if (!rn)
286 : return NULL;
287 :
288 0 : route_unlock_node(rn);
289 :
290 0 : return rn;
291 : }
292 :
293 : /*
294 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/prefix
295 : */
296 : struct yang_data *
297 0 : lib_vrf_zebra_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args)
298 : {
299 0 : const struct route_node *rn = args->list_entry;
300 :
301 0 : return yang_data_new_prefix(args->xpath, &rn->p);
302 : }
303 :
304 : /*
305 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry
306 : */
307 0 : const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next(
308 : struct nb_cb_get_next_args *args)
309 : {
310 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
311 0 : struct route_node *rn = (struct route_node *)args->parent_list_entry;
312 :
313 0 : if (args->list_entry == NULL)
314 0 : RNODE_FIRST_RE(rn, re);
315 : else
316 0 : RNODE_NEXT_RE(rn, re);
317 :
318 0 : return re;
319 : }
320 :
321 0 : int lib_vrf_zebra_ribs_rib_route_route_entry_get_keys(
322 : struct nb_cb_get_keys_args *args)
323 : {
324 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
325 :
326 0 : args->keys->num = 1;
327 :
328 0 : strlcpy(args->keys->key[0], zebra_route_string(re->type),
329 : sizeof(args->keys->key[0]));
330 :
331 0 : return NB_OK;
332 : }
333 :
334 0 : const void *lib_vrf_zebra_ribs_rib_route_route_entry_lookup_entry(
335 : struct nb_cb_lookup_entry_args *args)
336 : {
337 0 : struct route_node *rn = (struct route_node *)args->parent_list_entry;
338 0 : struct route_entry *re = NULL;
339 0 : int proto_type = 0;
340 0 : afi_t afi;
341 :
342 0 : afi = family2afi(rn->p.family);
343 0 : proto_type = proto_redistnum(afi, args->keys->key[0]);
344 :
345 0 : RNODE_FOREACH_RE (rn, re) {
346 0 : if (proto_type == re->type)
347 0 : return re;
348 : }
349 :
350 : return NULL;
351 : }
352 :
353 : /*
354 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/protocol
355 : */
356 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_protocol_get_elem(
357 : struct nb_cb_get_elem_args *args)
358 : {
359 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
360 :
361 0 : return yang_data_new_enum(args->xpath, re->type);
362 : }
363 :
364 : /*
365 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/instance
366 : */
367 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_instance_get_elem(
368 : struct nb_cb_get_elem_args *args)
369 : {
370 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
371 :
372 0 : if (re->instance)
373 0 : return yang_data_new_uint16(args->xpath, re->instance);
374 :
375 : return NULL;
376 : }
377 :
378 : /*
379 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/distance
380 : */
381 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_distance_get_elem(
382 : struct nb_cb_get_elem_args *args)
383 : {
384 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
385 :
386 0 : return yang_data_new_uint8(args->xpath, re->distance);
387 : }
388 :
389 : /*
390 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/metric
391 : */
392 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_metric_get_elem(
393 : struct nb_cb_get_elem_args *args)
394 : {
395 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
396 :
397 0 : return yang_data_new_uint32(args->xpath, re->metric);
398 : }
399 :
400 : /*
401 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/tag
402 : */
403 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_tag_get_elem(
404 : struct nb_cb_get_elem_args *args)
405 : {
406 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
407 :
408 0 : if (re->tag)
409 0 : return yang_data_new_uint32(args->xpath, re->tag);
410 :
411 : return NULL;
412 : }
413 :
414 : /*
415 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/selected
416 : */
417 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_selected_get_elem(
418 : struct nb_cb_get_elem_args *args)
419 : {
420 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
421 :
422 0 : if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
423 0 : return yang_data_new_empty(args->xpath);
424 :
425 : return NULL;
426 : }
427 :
428 : /*
429 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/installed
430 : */
431 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_installed_get_elem(
432 : struct nb_cb_get_elem_args *args)
433 : {
434 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
435 :
436 0 : if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
437 0 : return yang_data_new_empty(args->xpath);
438 :
439 : return NULL;
440 : }
441 :
442 : /*
443 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/failed
444 : */
445 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_failed_get_elem(
446 : struct nb_cb_get_elem_args *args)
447 : {
448 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
449 :
450 0 : if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
451 0 : return yang_data_new_empty(args->xpath);
452 :
453 : return NULL;
454 : }
455 :
456 : /*
457 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/queued
458 : */
459 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_queued_get_elem(
460 : struct nb_cb_get_elem_args *args)
461 : {
462 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
463 :
464 0 : if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
465 0 : return yang_data_new_empty(args->xpath);
466 :
467 : return NULL;
468 : }
469 :
470 : /*
471 : * XPath:
472 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/internal-flags
473 : */
474 : struct yang_data *
475 0 : lib_vrf_zebra_ribs_rib_route_route_entry_internal_flags_get_elem(
476 : struct nb_cb_get_elem_args *args)
477 : {
478 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
479 :
480 0 : if (re->flags)
481 0 : return yang_data_new_int32(args->xpath, re->flags);
482 :
483 : return NULL;
484 : }
485 :
486 : /*
487 : * XPath:
488 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/internal-status
489 : */
490 : struct yang_data *
491 0 : lib_vrf_zebra_ribs_rib_route_route_entry_internal_status_get_elem(
492 : struct nb_cb_get_elem_args *args)
493 : {
494 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
495 :
496 0 : if (re->status)
497 0 : return yang_data_new_int32(args->xpath, re->status);
498 :
499 : return NULL;
500 : }
501 :
502 : /*
503 : * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/uptime
504 : */
505 0 : struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_get_elem(
506 : struct nb_cb_get_elem_args *args)
507 : {
508 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
509 :
510 0 : return yang_data_new_date_and_time(args->xpath, re->uptime);
511 : }
512 :
513 : /*
514 : * XPath:
515 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/id
516 : */
517 : struct yang_data *
518 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_id_get_elem(
519 : struct nb_cb_get_elem_args *args)
520 : {
521 0 : struct route_entry *re = (struct route_entry *)args->list_entry;
522 :
523 0 : return yang_data_new_uint32(args->xpath, re->nhe->id);
524 : }
525 :
526 : /*
527 : * XPath:
528 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop
529 : */
530 : const void *
531 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_next(
532 : struct nb_cb_get_next_args *args)
533 : {
534 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
535 0 : struct route_entry *re = (struct route_entry *)args->parent_list_entry;
536 0 : struct nhg_hash_entry *nhe = re->nhe;
537 :
538 0 : if (args->list_entry == NULL) {
539 0 : nexthop = nhe->nhg.nexthop;
540 : } else
541 0 : nexthop = nexthop_next(nexthop);
542 :
543 0 : return nexthop;
544 : }
545 :
546 0 : int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_keys(
547 : struct nb_cb_get_keys_args *args)
548 : {
549 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
550 :
551 0 : args->keys->num = 4;
552 :
553 0 : strlcpy(args->keys->key[0], yang_nexthop_type2str(nexthop->type),
554 : sizeof(args->keys->key[0]));
555 :
556 0 : snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%" PRIu32,
557 : nexthop->vrf_id);
558 :
559 0 : switch (nexthop->type) {
560 0 : case NEXTHOP_TYPE_IPV4:
561 : case NEXTHOP_TYPE_IPV4_IFINDEX:
562 0 : snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
563 : "%pI4", &nexthop->gate.ipv4);
564 0 : if (nexthop->ifindex)
565 0 : strlcpy(args->keys->key[3],
566 : ifindex2ifname(nexthop->ifindex,
567 : nexthop->vrf_id),
568 : sizeof(args->keys->key[3]));
569 : else
570 : /* no ifindex */
571 0 : strlcpy(args->keys->key[3], " ",
572 : sizeof(args->keys->key[3]));
573 :
574 : break;
575 0 : case NEXTHOP_TYPE_IPV6:
576 : case NEXTHOP_TYPE_IPV6_IFINDEX:
577 0 : snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
578 : "%pI6", &nexthop->gate.ipv6);
579 :
580 0 : if (nexthop->ifindex)
581 0 : strlcpy(args->keys->key[3],
582 : ifindex2ifname(nexthop->ifindex,
583 : nexthop->vrf_id),
584 : sizeof(args->keys->key[3]));
585 : else
586 : /* no ifindex */
587 0 : strlcpy(args->keys->key[3], " ",
588 : sizeof(args->keys->key[3]));
589 :
590 : break;
591 0 : case NEXTHOP_TYPE_IFINDEX:
592 0 : strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
593 0 : strlcpy(args->keys->key[3],
594 : ifindex2ifname(nexthop->ifindex, nexthop->vrf_id),
595 : sizeof(args->keys->key[3]));
596 :
597 0 : break;
598 0 : case NEXTHOP_TYPE_BLACKHOLE:
599 : /* Gateway IP */
600 0 : strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
601 0 : strlcpy(args->keys->key[3], " ", sizeof(args->keys->key[3]));
602 0 : break;
603 : default:
604 : break;
605 : }
606 :
607 0 : return NB_OK;
608 : }
609 :
610 : const void *
611 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_lookup_entry(
612 : struct nb_cb_lookup_entry_args *args)
613 : {
614 0 : struct nhg_hash_entry *nhe;
615 0 : struct nexthop nexthop_lookup = {};
616 0 : struct nexthop *nexthop;
617 0 : const char *nh_type_str;
618 :
619 0 : nhe = (struct nhg_hash_entry *)args->parent_list_entry;
620 0 : nexthop_lookup.vrf_id = nhe->vrf_id;
621 :
622 : /*
623 : * Get nexthop type.
624 : * TODO: use yang_str2enum() instead.
625 : */
626 0 : nh_type_str = args->keys->key[0];
627 0 : if (strmatch(nh_type_str, "ifindex"))
628 0 : nexthop_lookup.type = NEXTHOP_TYPE_IFINDEX;
629 0 : else if (strmatch(nh_type_str, "ip4"))
630 0 : nexthop_lookup.type = NEXTHOP_TYPE_IPV4;
631 0 : else if (strmatch(nh_type_str, "ip4-ifindex"))
632 0 : nexthop_lookup.type = NEXTHOP_TYPE_IPV4_IFINDEX;
633 0 : else if (strmatch(nh_type_str, "ip6"))
634 0 : nexthop_lookup.type = NEXTHOP_TYPE_IPV6;
635 0 : else if (strmatch(nh_type_str, "ip6-ifindex"))
636 0 : nexthop_lookup.type = NEXTHOP_TYPE_IPV6_IFINDEX;
637 0 : else if (strmatch(nh_type_str, "blackhole"))
638 0 : nexthop_lookup.type = NEXTHOP_TYPE_BLACKHOLE;
639 : else
640 : /* unexpected */
641 : return NULL;
642 :
643 : /* Get nexthop address. */
644 0 : switch (nexthop_lookup.type) {
645 0 : case NEXTHOP_TYPE_IPV4:
646 : case NEXTHOP_TYPE_IPV4_IFINDEX:
647 0 : yang_str2ipv4(args->keys->key[1], &nexthop_lookup.gate.ipv4);
648 0 : break;
649 0 : case NEXTHOP_TYPE_IPV6:
650 : case NEXTHOP_TYPE_IPV6_IFINDEX:
651 0 : yang_str2ipv6(args->keys->key[1], &nexthop_lookup.gate.ipv6);
652 0 : break;
653 : case NEXTHOP_TYPE_IFINDEX:
654 : case NEXTHOP_TYPE_BLACKHOLE:
655 : break;
656 : }
657 :
658 : /* Get nexthop interface. */
659 0 : switch (nexthop_lookup.type) {
660 0 : case NEXTHOP_TYPE_IPV4_IFINDEX:
661 : case NEXTHOP_TYPE_IPV6_IFINDEX:
662 : case NEXTHOP_TYPE_IFINDEX:
663 0 : nexthop_lookup.ifindex =
664 0 : ifname2ifindex(args->keys->key[2], nhe->vrf_id);
665 0 : break;
666 : case NEXTHOP_TYPE_IPV4:
667 : case NEXTHOP_TYPE_IPV6:
668 : case NEXTHOP_TYPE_BLACKHOLE:
669 : break;
670 : }
671 :
672 : /* Lookup requested nexthop (ignore weight and metric). */
673 0 : for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
674 0 : nexthop_lookup.weight = nexthop->weight;
675 0 : nexthop_lookup.src = nexthop->src;
676 0 : if (nexthop_same_no_labels(&nexthop_lookup, nexthop))
677 0 : return nexthop;
678 : }
679 :
680 : return NULL;
681 : }
682 :
683 : /*
684 : * XPath:
685 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/nh-type
686 : */
687 : struct yang_data *
688 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_nh_type_get_elem(
689 : struct nb_cb_get_elem_args *args)
690 : {
691 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
692 :
693 0 : switch (nexthop->type) {
694 0 : case NEXTHOP_TYPE_IFINDEX:
695 0 : return yang_data_new_string(args->xpath, "ifindex");
696 0 : break;
697 0 : case NEXTHOP_TYPE_IPV4:
698 0 : return yang_data_new_string(args->xpath, "ip4");
699 0 : break;
700 0 : case NEXTHOP_TYPE_IPV4_IFINDEX:
701 0 : return yang_data_new_string(args->xpath, "ip4-ifindex");
702 0 : break;
703 0 : case NEXTHOP_TYPE_IPV6:
704 0 : return yang_data_new_string(args->xpath, "ip6");
705 0 : break;
706 0 : case NEXTHOP_TYPE_IPV6_IFINDEX:
707 0 : return yang_data_new_string(args->xpath, "ip6-ifindex");
708 : break;
709 : case NEXTHOP_TYPE_BLACKHOLE:
710 : break;
711 : }
712 :
713 : return NULL;
714 : }
715 :
716 : /*
717 : * XPath:
718 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/vrf
719 : */
720 : struct yang_data *
721 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_vrf_get_elem(
722 : struct nb_cb_get_elem_args *args)
723 : {
724 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
725 :
726 0 : return yang_data_new_string(args->xpath,
727 : vrf_id_to_name(nexthop->vrf_id));
728 : }
729 :
730 : /*
731 : * XPath:
732 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/gateway
733 : */
734 : struct yang_data *
735 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_gateway_get_elem(
736 : struct nb_cb_get_elem_args *args)
737 : {
738 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
739 0 : struct ipaddr addr;
740 :
741 0 : switch (nexthop->type) {
742 0 : case NEXTHOP_TYPE_IPV4:
743 : case NEXTHOP_TYPE_IPV4_IFINDEX:
744 0 : addr.ipa_type = IPADDR_V4;
745 0 : memcpy(&addr.ipaddr_v4, &(nexthop->gate.ipv4),
746 : sizeof(struct in_addr));
747 0 : break;
748 0 : case NEXTHOP_TYPE_IPV6:
749 : case NEXTHOP_TYPE_IPV6_IFINDEX:
750 0 : addr.ipa_type = IPADDR_V6;
751 0 : memcpy(&addr.ipaddr_v6, &(nexthop->gate.ipv6),
752 : sizeof(struct in6_addr));
753 0 : break;
754 0 : case NEXTHOP_TYPE_BLACKHOLE:
755 : case NEXTHOP_TYPE_IFINDEX:
756 : /* No addr here */
757 0 : return yang_data_new_string(args->xpath, "");
758 : break;
759 : default:
760 : break;
761 : }
762 :
763 0 : return yang_data_new_ip(args->xpath, &addr);
764 : }
765 :
766 : /*
767 : * XPath:
768 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/interface
769 : */
770 : struct yang_data *
771 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_interface_get_elem(
772 : struct nb_cb_get_elem_args *args)
773 : {
774 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
775 :
776 0 : if (nexthop->ifindex)
777 0 : return yang_data_new_string(
778 : args->xpath,
779 : ifindex2ifname(nexthop->ifindex, nexthop->vrf_id));
780 :
781 : return NULL;
782 : }
783 :
784 : /*
785 : * XPath:
786 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/bh-type
787 : */
788 : struct yang_data *
789 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_bh_type_get_elem(
790 : struct nb_cb_get_elem_args *args)
791 : {
792 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
793 0 : const char *type_str = "";
794 :
795 0 : if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)
796 : return NULL;
797 :
798 0 : switch (nexthop->bh_type) {
799 0 : case BLACKHOLE_NULL:
800 0 : type_str = "null";
801 0 : break;
802 0 : case BLACKHOLE_REJECT:
803 0 : type_str = "reject";
804 0 : break;
805 0 : case BLACKHOLE_ADMINPROHIB:
806 0 : type_str = "prohibited";
807 0 : break;
808 0 : case BLACKHOLE_UNSPEC:
809 0 : type_str = "unspec";
810 0 : break;
811 : }
812 :
813 0 : return yang_data_new_string(args->xpath, type_str);
814 : }
815 :
816 : /*
817 : * XPath:
818 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/onlink
819 : */
820 : struct yang_data *
821 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem(
822 : struct nb_cb_get_elem_args *args)
823 : {
824 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
825 :
826 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
827 0 : return yang_data_new_bool(args->xpath, true);
828 :
829 : return NULL;
830 : }
831 :
832 : /*
833 : * XPath:
834 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/srte-color
835 : */
836 : struct yang_data *
837 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_color_get_elem(
838 : struct nb_cb_get_elem_args *args)
839 : {
840 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
841 :
842 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE))
843 0 : return yang_data_new_uint32(args->xpath, nexthop->srte_color);
844 :
845 : return NULL;
846 : }
847 :
848 : /*
849 : * XPath:
850 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry
851 : */
852 : const void *
853 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_next(
854 : struct nb_cb_get_next_args *args)
855 : {
856 : /* TODO: implement me. */
857 0 : return NULL;
858 : }
859 :
860 0 : int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_keys(
861 : struct nb_cb_get_keys_args *args)
862 : {
863 : /* TODO: implement me. */
864 0 : return NB_OK;
865 : }
866 :
867 : const void *
868 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_lookup_entry(
869 : struct nb_cb_lookup_entry_args *args)
870 : {
871 : /* TODO: implement me. */
872 0 : return NULL;
873 : }
874 :
875 : /*
876 : * XPath:
877 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/id
878 : */
879 : struct yang_data *
880 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_id_get_elem(
881 : struct nb_cb_get_elem_args *args)
882 : {
883 : /* TODO: implement me. */
884 0 : return NULL;
885 : }
886 :
887 : /*
888 : * XPath:
889 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/label
890 : */
891 : struct yang_data *
892 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_label_get_elem(
893 : struct nb_cb_get_elem_args *args)
894 : {
895 : /* TODO: implement me. */
896 0 : return NULL;
897 : }
898 :
899 : /*
900 : * XPath:
901 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/ttl
902 : */
903 : struct yang_data *
904 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_ttl_get_elem(
905 : struct nb_cb_get_elem_args *args)
906 : {
907 : /* TODO: implement me. */
908 0 : return NULL;
909 : }
910 :
911 : /*
912 : * XPath:
913 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/traffic-class
914 : */
915 : struct yang_data *
916 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_traffic_class_get_elem(
917 : struct nb_cb_get_elem_args *args)
918 : {
919 : /* TODO: implement me. */
920 0 : return NULL;
921 : }
922 :
923 : /*
924 : * XPath:
925 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/duplicate
926 : */
927 : struct yang_data *
928 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_duplicate_get_elem(
929 : struct nb_cb_get_elem_args *args)
930 : {
931 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
932 :
933 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
934 0 : return yang_data_new_empty(args->xpath);
935 :
936 : return NULL;
937 : }
938 :
939 : /*
940 : * XPath:
941 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/recursive
942 : */
943 : struct yang_data *
944 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_recursive_get_elem(
945 : struct nb_cb_get_elem_args *args)
946 : {
947 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
948 :
949 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
950 0 : return yang_data_new_empty(args->xpath);
951 :
952 : return NULL;
953 : }
954 :
955 : /*
956 : * XPath:
957 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/active
958 : */
959 : struct yang_data *
960 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_active_get_elem(
961 : struct nb_cb_get_elem_args *args)
962 : {
963 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
964 :
965 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
966 0 : return yang_data_new_empty(args->xpath);
967 :
968 : return NULL;
969 : }
970 :
971 : /*
972 : * XPath:
973 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/fib
974 : */
975 : struct yang_data *
976 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_fib_get_elem(
977 : struct nb_cb_get_elem_args *args)
978 : {
979 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
980 :
981 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
982 0 : return yang_data_new_empty(args->xpath);
983 :
984 : return NULL;
985 : }
986 :
987 : /*
988 : * XPath:
989 : * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/weight
990 : */
991 : struct yang_data *
992 0 : lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_weight_get_elem(
993 : struct nb_cb_get_elem_args *args)
994 : {
995 0 : struct nexthop *nexthop = (struct nexthop *)args->list_entry;
996 :
997 0 : if (nexthop->weight)
998 0 : return yang_data_new_uint8(args->xpath, nexthop->weight);
999 :
1000 : return NULL;
1001 : }
|