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