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