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