]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_nb_state.c
*: Avoid casting to the same type as on the left
[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/afi-safi-name
218 */
219 struct yang_data *
220 lib_vrf_zebra_ribs_rib_afi_safi_name_get_elem(struct nb_cb_get_elem_args *args)
221 {
222 const struct zebra_router_table *zrt = args->list_entry;
223
224 return yang_data_new_string(args->xpath,
225 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 lib_vrf_zebra_ribs_rib_table_id_get_elem(struct nb_cb_get_elem_args *args)
233 {
234 const struct zebra_router_table *zrt = args->list_entry;
235
236 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 lib_vrf_zebra_ribs_rib_route_get_next(struct nb_cb_get_next_args *args)
244 {
245 const struct zebra_router_table *zrt = args->parent_list_entry;
246 struct route_node *rn = (struct route_node *)args->list_entry;
247
248 if (args->list_entry == NULL)
249 rn = route_top(zrt->table);
250 else
251 rn = srcdest_route_next(rn);
252 /* Optimization: skip empty route nodes. */
253 while (rn && rn->info == NULL)
254 rn = route_next(rn);
255
256 /* Skip link-local routes. */
257 if (rn && rn->p.family == AF_INET6
258 && IN6_IS_ADDR_LINKLOCAL(&rn->p.u.prefix6))
259 return NULL;
260
261 return rn;
262 }
263
264 int lib_vrf_zebra_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args)
265 {
266 const struct route_node *rn = args->list_entry;
267
268 args->keys->num = 1;
269 prefix2str(&rn->p, args->keys->key[0], sizeof(args->keys->key[0]));
270
271 return NB_OK;
272 }
273
274 const void *
275 lib_vrf_zebra_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args)
276 {
277 const struct zebra_router_table *zrt = args->parent_list_entry;
278 struct prefix p;
279 struct route_node *rn;
280
281 yang_str2prefix(args->keys->key[0], &p);
282
283 rn = route_node_lookup(zrt->table, &p);
284
285 if (!rn)
286 return NULL;
287
288 route_unlock_node(rn);
289
290 return rn;
291 }
292
293 /*
294 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/prefix
295 */
296 struct yang_data *
297 lib_vrf_zebra_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args)
298 {
299 const struct route_node *rn = args->list_entry;
300
301 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 const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next(
308 struct nb_cb_get_next_args *args)
309 {
310 struct route_entry *re = (struct route_entry *)args->list_entry;
311 struct route_node *rn = (struct route_node *)args->parent_list_entry;
312
313 if (args->list_entry == NULL)
314 RNODE_FIRST_RE(rn, re);
315 else
316 RNODE_NEXT_RE(rn, re);
317
318 return re;
319 }
320
321 int lib_vrf_zebra_ribs_rib_route_route_entry_get_keys(
322 struct nb_cb_get_keys_args *args)
323 {
324 struct route_entry *re = (struct route_entry *)args->list_entry;
325
326 args->keys->num = 1;
327
328 strlcpy(args->keys->key[0], zebra_route_string(re->type),
329 sizeof(args->keys->key[0]));
330
331 return NB_OK;
332 }
333
334 const void *lib_vrf_zebra_ribs_rib_route_route_entry_lookup_entry(
335 struct nb_cb_lookup_entry_args *args)
336 {
337 struct route_node *rn = (struct route_node *)args->parent_list_entry;
338 struct route_entry *re = NULL;
339 int proto_type = 0;
340 afi_t afi;
341
342 afi = family2afi(rn->p.family);
343 proto_type = proto_redistnum(afi, args->keys->key[0]);
344
345 RNODE_FOREACH_RE (rn, re) {
346 if (proto_type == re->type)
347 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_protocol_get_elem(
357 struct nb_cb_get_elem_args *args)
358 {
359 struct route_entry *re = (struct route_entry *)args->list_entry;
360
361 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_instance_get_elem(
368 struct nb_cb_get_elem_args *args)
369 {
370 struct route_entry *re = (struct route_entry *)args->list_entry;
371
372 if (re->instance)
373 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_distance_get_elem(
382 struct nb_cb_get_elem_args *args)
383 {
384 struct route_entry *re = (struct route_entry *)args->list_entry;
385
386 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_metric_get_elem(
393 struct nb_cb_get_elem_args *args)
394 {
395 struct route_entry *re = (struct route_entry *)args->list_entry;
396
397 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_tag_get_elem(
404 struct nb_cb_get_elem_args *args)
405 {
406 struct route_entry *re = (struct route_entry *)args->list_entry;
407
408 if (re->tag)
409 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_selected_get_elem(
418 struct nb_cb_get_elem_args *args)
419 {
420 struct route_entry *re = (struct route_entry *)args->list_entry;
421
422 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
423 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_installed_get_elem(
432 struct nb_cb_get_elem_args *args)
433 {
434 struct route_entry *re = (struct route_entry *)args->list_entry;
435
436 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
437 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_failed_get_elem(
446 struct nb_cb_get_elem_args *args)
447 {
448 struct route_entry *re = (struct route_entry *)args->list_entry;
449
450 if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
451 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_queued_get_elem(
460 struct nb_cb_get_elem_args *args)
461 {
462 struct route_entry *re = (struct route_entry *)args->list_entry;
463
464 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
465 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 lib_vrf_zebra_ribs_rib_route_route_entry_internal_flags_get_elem(
476 struct nb_cb_get_elem_args *args)
477 {
478 struct route_entry *re = (struct route_entry *)args->list_entry;
479
480 if (re->flags)
481 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 lib_vrf_zebra_ribs_rib_route_route_entry_internal_status_get_elem(
492 struct nb_cb_get_elem_args *args)
493 {
494 struct route_entry *re = (struct route_entry *)args->list_entry;
495
496 if (re->status)
497 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 struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_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_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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_id_get_elem(
519 struct nb_cb_get_elem_args *args)
520 {
521 struct route_entry *re = (struct route_entry *)args->list_entry;
522
523 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_next(
532 struct nb_cb_get_next_args *args)
533 {
534 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
535 struct route_entry *re = (struct route_entry *)args->parent_list_entry;
536 struct nhg_hash_entry *nhe = re->nhe;
537
538 if (args->list_entry == NULL) {
539 nexthop = nhe->nhg.nexthop;
540 } else
541 nexthop = nexthop_next(nexthop);
542
543 return nexthop;
544 }
545
546 int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_keys(
547 struct nb_cb_get_keys_args *args)
548 {
549 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
550
551 args->keys->num = 4;
552
553 strlcpy(args->keys->key[0], yang_nexthop_type2str(nexthop->type),
554 sizeof(args->keys->key[0]));
555
556 snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%" PRIu32,
557 nexthop->vrf_id);
558
559 switch (nexthop->type) {
560 case NEXTHOP_TYPE_IPV4:
561 case NEXTHOP_TYPE_IPV4_IFINDEX:
562 snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
563 "%pI4", &nexthop->gate.ipv4);
564 if (nexthop->ifindex)
565 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 strlcpy(args->keys->key[3], " ",
572 sizeof(args->keys->key[3]));
573
574 break;
575 case NEXTHOP_TYPE_IPV6:
576 case NEXTHOP_TYPE_IPV6_IFINDEX:
577 snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
578 "%pI6", &nexthop->gate.ipv6);
579
580 if (nexthop->ifindex)
581 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 strlcpy(args->keys->key[3], " ",
588 sizeof(args->keys->key[3]));
589
590 break;
591 case NEXTHOP_TYPE_IFINDEX:
592 strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
593 strlcpy(args->keys->key[3],
594 ifindex2ifname(nexthop->ifindex, nexthop->vrf_id),
595 sizeof(args->keys->key[3]));
596
597 break;
598 case NEXTHOP_TYPE_BLACKHOLE:
599 /* Gateway IP */
600 strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
601 strlcpy(args->keys->key[3], " ", sizeof(args->keys->key[3]));
602 break;
603 default:
604 break;
605 }
606
607 return NB_OK;
608 }
609
610 const void *
611 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_lookup_entry(
612 struct nb_cb_lookup_entry_args *args)
613 {
614 struct nhg_hash_entry *nhe;
615 struct nexthop nexthop_lookup = {};
616 struct nexthop *nexthop;
617 const char *nh_type_str;
618
619 nhe = (struct nhg_hash_entry *)args->parent_list_entry;
620 nexthop_lookup.vrf_id = nhe->vrf_id;
621
622 /*
623 * Get nexthop type.
624 * TODO: use yang_str2enum() instead.
625 */
626 nh_type_str = args->keys->key[0];
627 if (strmatch(nh_type_str, "ifindex"))
628 nexthop_lookup.type = NEXTHOP_TYPE_IFINDEX;
629 else if (strmatch(nh_type_str, "ip4"))
630 nexthop_lookup.type = NEXTHOP_TYPE_IPV4;
631 else if (strmatch(nh_type_str, "ip4-ifindex"))
632 nexthop_lookup.type = NEXTHOP_TYPE_IPV4_IFINDEX;
633 else if (strmatch(nh_type_str, "ip6"))
634 nexthop_lookup.type = NEXTHOP_TYPE_IPV6;
635 else if (strmatch(nh_type_str, "ip6-ifindex"))
636 nexthop_lookup.type = NEXTHOP_TYPE_IPV6_IFINDEX;
637 else if (strmatch(nh_type_str, "blackhole"))
638 nexthop_lookup.type = NEXTHOP_TYPE_BLACKHOLE;
639 else
640 /* unexpected */
641 return NULL;
642
643 /* Get nexthop address. */
644 switch (nexthop_lookup.type) {
645 case NEXTHOP_TYPE_IPV4:
646 case NEXTHOP_TYPE_IPV4_IFINDEX:
647 yang_str2ipv4(args->keys->key[1], &nexthop_lookup.gate.ipv4);
648 break;
649 case NEXTHOP_TYPE_IPV6:
650 case NEXTHOP_TYPE_IPV6_IFINDEX:
651 yang_str2ipv6(args->keys->key[1], &nexthop_lookup.gate.ipv6);
652 break;
653 case NEXTHOP_TYPE_IFINDEX:
654 case NEXTHOP_TYPE_BLACKHOLE:
655 break;
656 }
657
658 /* Get nexthop interface. */
659 switch (nexthop_lookup.type) {
660 case NEXTHOP_TYPE_IPV4_IFINDEX:
661 case NEXTHOP_TYPE_IPV6_IFINDEX:
662 case NEXTHOP_TYPE_IFINDEX:
663 nexthop_lookup.ifindex =
664 ifname2ifindex(args->keys->key[2], nhe->vrf_id);
665 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 for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
674 nexthop_lookup.weight = nexthop->weight;
675 nexthop_lookup.src = nexthop->src;
676 if (nexthop_same_no_labels(&nexthop_lookup, nexthop))
677 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 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 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
692
693 switch (nexthop->type) {
694 case NEXTHOP_TYPE_IFINDEX:
695 return yang_data_new_string(args->xpath, "ifindex");
696 break;
697 case NEXTHOP_TYPE_IPV4:
698 return yang_data_new_string(args->xpath, "ip4");
699 break;
700 case NEXTHOP_TYPE_IPV4_IFINDEX:
701 return yang_data_new_string(args->xpath, "ip4-ifindex");
702 break;
703 case NEXTHOP_TYPE_IPV6:
704 return yang_data_new_string(args->xpath, "ip6");
705 break;
706 case NEXTHOP_TYPE_IPV6_IFINDEX:
707 return yang_data_new_string(args->xpath, "ip6-ifindex");
708 break;
709 default:
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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_vrf_get_elem(
722 struct nb_cb_get_elem_args *args)
723 {
724 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
725
726 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_gateway_get_elem(
736 struct nb_cb_get_elem_args *args)
737 {
738 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
739 struct ipaddr addr;
740
741 switch (nexthop->type) {
742 case NEXTHOP_TYPE_IPV4:
743 case NEXTHOP_TYPE_IPV4_IFINDEX:
744 addr.ipa_type = IPADDR_V4;
745 memcpy(&addr.ipaddr_v4, &(nexthop->gate.ipv4),
746 sizeof(struct in_addr));
747 break;
748 case NEXTHOP_TYPE_IPV6:
749 case NEXTHOP_TYPE_IPV6_IFINDEX:
750 addr.ipa_type = IPADDR_V6;
751 memcpy(&addr.ipaddr_v6, &(nexthop->gate.ipv6),
752 sizeof(struct in6_addr));
753 break;
754 case NEXTHOP_TYPE_BLACKHOLE:
755 case NEXTHOP_TYPE_IFINDEX:
756 /* No addr here */
757 return yang_data_new_string(args->xpath, "");
758 break;
759 default:
760 break;
761 }
762
763 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_interface_get_elem(
772 struct nb_cb_get_elem_args *args)
773 {
774 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
775
776 if (nexthop->ifindex)
777 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 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 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
793 const char *type_str = "";
794
795 if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)
796 return NULL;
797
798 switch (nexthop->bh_type) {
799 case BLACKHOLE_NULL:
800 type_str = "null";
801 break;
802 case BLACKHOLE_REJECT:
803 type_str = "reject";
804 break;
805 case BLACKHOLE_ADMINPROHIB:
806 type_str = "prohibited";
807 break;
808 case BLACKHOLE_UNSPEC:
809 type_str = "unspec";
810 break;
811 }
812
813 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem(
822 struct nb_cb_get_elem_args *args)
823 {
824 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
825
826 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
827 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_color_get_elem(
838 struct nb_cb_get_elem_args *args)
839 {
840 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
841
842 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE))
843 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 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 return NULL;
858 }
859
860 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 return NB_OK;
865 }
866
867 const void *
868 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 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 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 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 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 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 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 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 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 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_duplicate_get_elem(
929 struct nb_cb_get_elem_args *args)
930 {
931 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
932
933 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
934 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_recursive_get_elem(
945 struct nb_cb_get_elem_args *args)
946 {
947 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
948
949 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
950 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_active_get_elem(
961 struct nb_cb_get_elem_args *args)
962 {
963 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
964
965 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
966 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_fib_get_elem(
977 struct nb_cb_get_elem_args *args)
978 {
979 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
980
981 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
982 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 lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_weight_get_elem(
993 struct nb_cb_get_elem_args *args)
994 {
995 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
996
997 if (nexthop->weight)
998 return yang_data_new_uint8(args->xpath, nexthop->weight);
999
1000 return NULL;
1001 }