]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_nb_state.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / zebra / zebra_nb_state.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
ce45ffe7
CS
2/*
3 * Copyright (C) 2020 Cumulus Networks, Inc.
4 * Chirag Shah
ce45ffe7
CS
5 */
6
7#include <zebra.h>
8#include "northbound.h"
9#include "libfrr.h"
10#include "zebra_nb.h"
09268680 11#include "zebra/interface.h"
9d86e091 12#include "zebra/zebra_router.h"
5a634c34
CS
13#include "zebra/debug.h"
14#include "printfrr.h"
8d30ff3b 15#include "zebra/zebra_vxlan.h"
0adeb5fd 16#include "zebra/zebra_vxlan_if.h"
ce45ffe7 17
b00f3e4b
CS
18/*
19 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
20 */
21struct yang_data *
60ee8be1 22lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 23{
60ee8be1 24 const struct interface *ifp = args->list_entry;
09268680
CS
25 struct zebra_if *zebra_if;
26
27 zebra_if = ifp->info;
28
60ee8be1 29 return yang_data_new_uint16(args->xpath, zebra_if->up_count);
b00f3e4b
CS
30}
31
32/*
33 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/down-count
34 */
35struct yang_data *
60ee8be1 36lib_interface_zebra_state_down_count_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 37{
60ee8be1 38 const struct interface *ifp = args->list_entry;
09268680
CS
39 struct zebra_if *zebra_if;
40
41 zebra_if = ifp->info;
42
60ee8be1 43 return yang_data_new_uint16(args->xpath, zebra_if->down_count);
b00f3e4b
CS
44}
45
46/*
47 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/zif-type
48 */
49struct yang_data *
60ee8be1 50lib_interface_zebra_state_zif_type_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b
CS
51{
52 /* TODO: implement me. */
53 return NULL;
54}
55
56/*
57 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/ptm-status
58 */
59struct yang_data *
60ee8be1 60lib_interface_zebra_state_ptm_status_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b
CS
61{
62 /* TODO: implement me. */
63 return NULL;
64}
65
66/*
67 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vlan-id
68 */
69struct yang_data *
60ee8be1 70lib_interface_zebra_state_vlan_id_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 71{
60ee8be1 72 const struct interface *ifp = args->list_entry;
09268680
CS
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
60ee8be1 82 return yang_data_new_uint16(args->xpath, vlan_info->vid);
b00f3e4b
CS
83}
84
85/*
86 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vni-id
87 */
88struct yang_data *
60ee8be1 89lib_interface_zebra_state_vni_id_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 90{
60ee8be1 91 const struct interface *ifp = args->list_entry;
09268680 92 struct zebra_if *zebra_if;
8d30ff3b 93 struct zebra_vxlan_vni *vni;
09268680
CS
94
95 if (!IS_ZEBRA_IF_VXLAN(ifp))
96 return NULL;
97
98 zebra_if = ifp->info;
09268680 99
8d30ff3b
SR
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);
b00f3e4b
CS
105}
106
107/*
108 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/remote-vtep
109 */
110struct yang_data *
60ee8be1 111lib_interface_zebra_state_remote_vtep_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 112{
60ee8be1 113 const struct interface *ifp = args->list_entry;
09268680
CS
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
60ee8be1 123 return yang_data_new_ipv4(args->xpath, &vxlan_info->vtep_ip);
b00f3e4b
CS
124}
125
126/*
127 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/mcast-group
128 */
129struct yang_data *
60ee8be1 130lib_interface_zebra_state_mcast_group_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 131{
60ee8be1 132 const struct interface *ifp = args->list_entry;
09268680 133 struct zebra_if *zebra_if;
8d30ff3b 134 struct zebra_vxlan_vni *vni;
09268680
CS
135
136 if (!IS_ZEBRA_IF_VXLAN(ifp))
137 return NULL;
138
139 zebra_if = ifp->info;
09268680 140
8d30ff3b
SR
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);
b00f3e4b
CS
146}
147
56a88b9e 148const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args)
ce45ffe7 149{
56a88b9e 150 struct vrf *vrf = (struct vrf *)args->parent_list_entry;
9d86e091 151 struct zebra_router_table *zrt =
56a88b9e 152 (struct zebra_router_table *)args->list_entry;
9d86e091
CS
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
56a88b9e 160 if (args->list_entry == NULL) {
9d86e091
CS
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;
ce45ffe7
CS
175}
176
56a88b9e 177int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args)
ce45ffe7 178{
56a88b9e 179 const struct zebra_router_table *zrt = args->list_entry;
9d86e091 180
56a88b9e 181 args->keys->num = 2;
9d86e091 182
755100ac 183 snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%s",
184 yang_afi_safi_value2identity(zrt->afi, zrt->safi));
6cde4b45 185 snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%u",
5a634c34 186 zrt->tableid);
9d86e091 187
ce45ffe7
CS
188 return NB_OK;
189}
190
56a88b9e
CS
191const void *
192lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args)
ce45ffe7 193{
56a88b9e 194 struct vrf *vrf = (struct vrf *)args->parent_list_entry;
9d86e091 195 struct zebra_vrf *zvrf;
5a634c34
CS
196 afi_t afi;
197 safi_t safi;
198 uint32_t table_id = 0;
9d86e091
CS
199
200 zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
201
755100ac 202 yang_afi_safi_identity2value(args->keys->key[0], &afi, &safi);
5a634c34
CS
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);
ce45ffe7
CS
209}
210
6c380957
IR
211/*
212 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/afi-safi-name
213 */
214struct yang_data *
215lib_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 */
226struct yang_data *
227lib_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
ce45ffe7 234/*
56a88b9e 235 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route
ce45ffe7 236 */
56a88b9e
CS
237const void *
238lib_vrf_zebra_ribs_rib_route_get_next(struct nb_cb_get_next_args *args)
ce45ffe7 239{
56a88b9e 240 const struct zebra_router_table *zrt = args->parent_list_entry;
78769ea2 241 struct route_node *rn = (struct route_node *)args->list_entry;
9d86e091 242
56a88b9e 243 if (args->list_entry == NULL)
9d86e091
CS
244 rn = route_top(zrt->table);
245 else
8998807f 246 rn = srcdest_route_next(rn);
78769ea2
RW
247 /* Optimization: skip empty route nodes. */
248 while (rn && rn->info == NULL)
249 rn = route_next(rn);
9d86e091 250
9b4d578f
RW
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
9d86e091 256 return rn;
ce45ffe7
CS
257}
258
56a88b9e 259int lib_vrf_zebra_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args)
ce45ffe7 260{
56a88b9e 261 const struct route_node *rn = args->list_entry;
9d86e091 262
56a88b9e
CS
263 args->keys->num = 1;
264 prefix2str(&rn->p, args->keys->key[0], sizeof(args->keys->key[0]));
9d86e091 265
ce45ffe7
CS
266 return NB_OK;
267}
268
269const void *
56a88b9e 270lib_vrf_zebra_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args)
ce45ffe7 271{
56a88b9e 272 const struct zebra_router_table *zrt = args->parent_list_entry;
9d86e091
CS
273 struct prefix p;
274 struct route_node *rn;
275
56a88b9e 276 yang_str2prefix(args->keys->key[0], &p);
9d86e091
CS
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;
ce45ffe7
CS
286}
287
288/*
56a88b9e 289 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/prefix
ce45ffe7 290 */
60ee8be1 291struct yang_data *
56a88b9e 292lib_vrf_zebra_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args)
ce45ffe7 293{
56a88b9e 294 const struct route_node *rn = args->list_entry;
9d86e091 295
56a88b9e 296 return yang_data_new_prefix(args->xpath, &rn->p);
ce45ffe7
CS
297}
298
299/*
56a88b9e 300 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry
ce45ffe7 301 */
56a88b9e
CS
302const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next(
303 struct nb_cb_get_next_args *args)
ed5abdb2 304{
5a634c34
CS
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);
9d86e091
CS
312
313 return re;
ed5abdb2
CS
314}
315
56a88b9e 316int lib_vrf_zebra_ribs_rib_route_route_entry_get_keys(
60ee8be1 317 struct nb_cb_get_keys_args *args)
ed5abdb2 318{
5a634c34
CS
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
ed5abdb2
CS
326 return NB_OK;
327}
328
56a88b9e 329const void *lib_vrf_zebra_ribs_rib_route_route_entry_lookup_entry(
60ee8be1 330 struct nb_cb_lookup_entry_args *args)
ce45ffe7 331{
5a634c34
CS
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
ce45ffe7
CS
345 return NULL;
346}
347
348/*
56a88b9e 349 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/protocol
ce45ffe7 350 */
56a88b9e 351struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_protocol_get_elem(
60ee8be1 352 struct nb_cb_get_elem_args *args)
ce45ffe7 353{
5a634c34
CS
354 struct route_entry *re = (struct route_entry *)args->list_entry;
355
356 return yang_data_new_enum(args->xpath, re->type);
ce45ffe7
CS
357}
358
359/*
56a88b9e 360 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/instance
ce45ffe7 361 */
56a88b9e 362struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_instance_get_elem(
60ee8be1 363 struct nb_cb_get_elem_args *args)
ce45ffe7 364{
5a634c34
CS
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
ce45ffe7
CS
370 return NULL;
371}
372
373/*
56a88b9e 374 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/distance
ce45ffe7 375 */
56a88b9e 376struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_distance_get_elem(
60ee8be1 377 struct nb_cb_get_elem_args *args)
ce45ffe7 378{
5a634c34
CS
379 struct route_entry *re = (struct route_entry *)args->list_entry;
380
381 return yang_data_new_uint8(args->xpath, re->distance);
ce45ffe7
CS
382}
383
384/*
56a88b9e 385 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/metric
ce45ffe7 386 */
56a88b9e 387struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_metric_get_elem(
60ee8be1 388 struct nb_cb_get_elem_args *args)
ce45ffe7 389{
5a634c34
CS
390 struct route_entry *re = (struct route_entry *)args->list_entry;
391
392 return yang_data_new_uint32(args->xpath, re->metric);
ce45ffe7
CS
393}
394
395/*
56a88b9e 396 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/tag
ce45ffe7 397 */
56a88b9e 398struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_tag_get_elem(
60ee8be1 399 struct nb_cb_get_elem_args *args)
ce45ffe7 400{
5a634c34
CS
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
ce45ffe7
CS
406 return NULL;
407}
408
409/*
56a88b9e 410 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/selected
ce45ffe7 411 */
56a88b9e 412struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_selected_get_elem(
60ee8be1 413 struct nb_cb_get_elem_args *args)
ce45ffe7 414{
5a634c34
CS
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
ce45ffe7
CS
420 return NULL;
421}
422
423/*
56a88b9e 424 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/installed
ce45ffe7 425 */
56a88b9e 426struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_installed_get_elem(
60ee8be1 427 struct nb_cb_get_elem_args *args)
ce45ffe7 428{
5a634c34
CS
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
ce45ffe7
CS
434 return NULL;
435}
436
437/*
56a88b9e 438 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/failed
ce45ffe7 439 */
56a88b9e 440struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_failed_get_elem(
60ee8be1 441 struct nb_cb_get_elem_args *args)
ce45ffe7 442{
5a634c34
CS
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
ce45ffe7
CS
448 return NULL;
449}
450
451/*
56a88b9e 452 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/queued
ce45ffe7 453 */
56a88b9e 454struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_queued_get_elem(
60ee8be1 455 struct nb_cb_get_elem_args *args)
ce45ffe7 456{
5a634c34
CS
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
ce45ffe7
CS
462 return NULL;
463}
464
465/*
56a88b9e
CS
466 * XPath:
467 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/internal-flags
ce45ffe7 468 */
56a88b9e
CS
469struct yang_data *
470lib_vrf_zebra_ribs_rib_route_route_entry_internal_flags_get_elem(
60ee8be1 471 struct nb_cb_get_elem_args *args)
ce45ffe7 472{
5a634c34
CS
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
ce45ffe7
CS
478 return NULL;
479}
480
481/*
56a88b9e
CS
482 * XPath:
483 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/internal-status
ce45ffe7 484 */
56a88b9e
CS
485struct yang_data *
486lib_vrf_zebra_ribs_rib_route_route_entry_internal_status_get_elem(
60ee8be1 487 struct nb_cb_get_elem_args *args)
ce45ffe7 488{
5a634c34
CS
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
ce45ffe7
CS
494 return NULL;
495}
496
497/*
56a88b9e 498 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/uptime
ce45ffe7 499 */
56a88b9e 500struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_get_elem(
60ee8be1 501 struct nb_cb_get_elem_args *args)
ce45ffe7 502{
5a634c34
CS
503 struct route_entry *re = (struct route_entry *)args->list_entry;
504
505 return yang_data_new_date_and_time(args->xpath, re->uptime);
ce45ffe7
CS
506}
507
508/*
56a88b9e 509 * XPath:
2b2282eb 510 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/id
ce45ffe7
CS
511 */
512struct yang_data *
2b2282eb 513lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_id_get_elem(
60ee8be1 514 struct nb_cb_get_elem_args *args)
ce45ffe7 515{
2b2282eb 516 struct route_entry *re = (struct route_entry *)args->list_entry;
5a634c34 517
2b2282eb 518 return yang_data_new_uint32(args->xpath, re->nhe->id);
ce45ffe7
CS
519}
520
521/*
522 * XPath:
2b2282eb 523 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop
ce45ffe7 524 */
ed5abdb2 525const void *
2b2282eb 526lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_next(
60ee8be1 527 struct nb_cb_get_next_args *args)
ce45ffe7 528{
5a634c34 529 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
2b2282eb
CS
530 struct route_entry *re = (struct route_entry *)args->parent_list_entry;
531 struct nhg_hash_entry *nhe = re->nhe;
5a634c34 532
2b2282eb 533 if (args->list_entry == NULL) {
5a634c34 534 nexthop = nhe->nhg.nexthop;
2b2282eb 535 } else
5a634c34
CS
536 nexthop = nexthop_next(nexthop);
537
538 return nexthop;
ce45ffe7
CS
539}
540
2b2282eb 541int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_keys(
60ee8be1 542 struct nb_cb_get_keys_args *args)
ce45ffe7 543{
5a634c34
CS
544 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
545
20e310a9 546 args->keys->num = 4;
5a634c34
CS
547
548 strlcpy(args->keys->key[0], yang_nexthop_type2str(nexthop->type),
549 sizeof(args->keys->key[0]));
550
20e310a9
CS
551 snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%" PRIu32,
552 nexthop->vrf_id);
553
5a634c34
CS
554 switch (nexthop->type) {
555 case NEXTHOP_TYPE_IPV4:
556 case NEXTHOP_TYPE_IPV4_IFINDEX:
20e310a9 557 snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
5a634c34
CS
558 "%pI4", &nexthop->gate.ipv4);
559 if (nexthop->ifindex)
20e310a9 560 strlcpy(args->keys->key[3],
5a634c34
CS
561 ifindex2ifname(nexthop->ifindex,
562 nexthop->vrf_id),
20e310a9 563 sizeof(args->keys->key[3]));
5a634c34
CS
564 else
565 /* no ifindex */
20e310a9
CS
566 strlcpy(args->keys->key[3], " ",
567 sizeof(args->keys->key[3]));
5a634c34
CS
568
569 break;
570 case NEXTHOP_TYPE_IPV6:
571 case NEXTHOP_TYPE_IPV6_IFINDEX:
20e310a9 572 snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
5a634c34
CS
573 "%pI6", &nexthop->gate.ipv6);
574
575 if (nexthop->ifindex)
20e310a9 576 strlcpy(args->keys->key[3],
5a634c34
CS
577 ifindex2ifname(nexthop->ifindex,
578 nexthop->vrf_id),
20e310a9 579 sizeof(args->keys->key[3]));
5a634c34
CS
580 else
581 /* no ifindex */
20e310a9
CS
582 strlcpy(args->keys->key[3], " ",
583 sizeof(args->keys->key[3]));
5a634c34
CS
584
585 break;
586 case NEXTHOP_TYPE_IFINDEX:
20e310a9
CS
587 strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
588 strlcpy(args->keys->key[3],
5a634c34 589 ifindex2ifname(nexthop->ifindex, nexthop->vrf_id),
20e310a9 590 sizeof(args->keys->key[3]));
5a634c34
CS
591
592 break;
593 case NEXTHOP_TYPE_BLACKHOLE:
594 /* Gateway IP */
20e310a9
CS
595 strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
596 strlcpy(args->keys->key[3], " ", sizeof(args->keys->key[3]));
5a634c34
CS
597 break;
598 default:
599 break;
600 }
601
ce45ffe7
CS
602 return NB_OK;
603}
604
605const void *
2b2282eb 606lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_lookup_entry(
60ee8be1 607 struct nb_cb_lookup_entry_args *args)
ce45ffe7 608{
bf6f7f7d
RW
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
ce45ffe7
CS
675 return NULL;
676}
677
678/*
679 * XPath:
2b2282eb 680 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/nh-type
ce45ffe7
CS
681 */
682struct yang_data *
2b2282eb 683lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_nh_type_get_elem(
60ee8be1 684 struct nb_cb_get_elem_args *args)
ce45ffe7 685{
5a634c34
CS
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;
a98701f0 704 case NEXTHOP_TYPE_BLACKHOLE:
5a634c34
CS
705 break;
706 }
707
ce45ffe7
CS
708 return NULL;
709}
710
711/*
712 * XPath:
2b2282eb 713 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/vrf
ce45ffe7
CS
714 */
715struct yang_data *
2b2282eb 716lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_vrf_get_elem(
60ee8be1 717 struct nb_cb_get_elem_args *args)
ce45ffe7 718{
5a634c34
CS
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));
ce45ffe7
CS
723}
724
725/*
726 * XPath:
2b2282eb 727 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/gateway
ce45ffe7
CS
728 */
729struct yang_data *
2b2282eb 730lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_gateway_get_elem(
60ee8be1 731 struct nb_cb_get_elem_args *args)
ce45ffe7 732{
5a634c34
CS
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);
ce45ffe7
CS
759}
760
761/*
762 * XPath:
2b2282eb 763 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/interface
ce45ffe7
CS
764 */
765struct yang_data *
2b2282eb 766lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_interface_get_elem(
60ee8be1 767 struct nb_cb_get_elem_args *args)
ce45ffe7 768{
5a634c34
CS
769 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
770
771 if (nexthop->ifindex)
c17a3d0f 772 return yang_data_new_string(
5a634c34
CS
773 args->xpath,
774 ifindex2ifname(nexthop->ifindex, nexthop->vrf_id));
775
ce45ffe7
CS
776 return NULL;
777}
778
779/*
780 * XPath:
2b2282eb 781 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/bh-type
ce45ffe7
CS
782 */
783struct yang_data *
2b2282eb 784lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_bh_type_get_elem(
60ee8be1 785 struct nb_cb_get_elem_args *args)
ce45ffe7 786{
5a634c34
CS
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);
ce45ffe7
CS
809}
810
811/*
812 * XPath:
2b2282eb 813 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/onlink
ce45ffe7
CS
814 */
815struct yang_data *
2b2282eb 816lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem(
60ee8be1 817 struct nb_cb_get_elem_args *args)
ce45ffe7 818{
5a634c34
CS
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
ce45ffe7
CS
824 return NULL;
825}
826
065276ae
SM
827/*
828 * XPath:
829 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/srte-color
830 */
831struct yang_data *
832lib_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
ce45ffe7
CS
843/*
844 * XPath:
2b2282eb 845 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry
ce45ffe7
CS
846 */
847const void *
2b2282eb 848lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_next(
60ee8be1 849 struct nb_cb_get_next_args *args)
ce45ffe7
CS
850{
851 /* TODO: implement me. */
852 return NULL;
853}
854
2b2282eb 855int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_keys(
60ee8be1 856 struct nb_cb_get_keys_args *args)
ce45ffe7
CS
857{
858 /* TODO: implement me. */
859 return NB_OK;
860}
861
862const void *
2b2282eb 863lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_lookup_entry(
60ee8be1 864 struct nb_cb_lookup_entry_args *args)
ce45ffe7
CS
865{
866 /* TODO: implement me. */
867 return NULL;
868}
869
870/*
871 * XPath:
2b2282eb 872 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/id
ce45ffe7
CS
873 */
874struct yang_data *
2b2282eb 875lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_id_get_elem(
60ee8be1 876 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
877{
878 /* TODO: implement me. */
879 return NULL;
880}
881
882/*
883 * XPath:
2b2282eb 884 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/label
ce45ffe7
CS
885 */
886struct yang_data *
2b2282eb 887lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_label_get_elem(
60ee8be1 888 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
889{
890 /* TODO: implement me. */
891 return NULL;
892}
893
894/*
895 * XPath:
2b2282eb 896 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/ttl
ce45ffe7
CS
897 */
898struct yang_data *
2b2282eb 899lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_ttl_get_elem(
60ee8be1 900 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
901{
902 /* TODO: implement me. */
903 return NULL;
904}
905
906/*
907 * XPath:
2b2282eb 908 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/traffic-class
ce45ffe7
CS
909 */
910struct yang_data *
2b2282eb 911lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_traffic_class_get_elem(
60ee8be1 912 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
913{
914 /* TODO: implement me. */
915 return NULL;
916}
917
918/*
919 * XPath:
2b2282eb 920 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/duplicate
ce45ffe7
CS
921 */
922struct yang_data *
2b2282eb 923lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_duplicate_get_elem(
60ee8be1 924 struct nb_cb_get_elem_args *args)
ce45ffe7 925{
5a634c34
CS
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
ce45ffe7
CS
931 return NULL;
932}
933
934/*
935 * XPath:
2b2282eb 936 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/recursive
ce45ffe7
CS
937 */
938struct yang_data *
2b2282eb 939lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_recursive_get_elem(
60ee8be1 940 struct nb_cb_get_elem_args *args)
ce45ffe7 941{
5a634c34
CS
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
ce45ffe7
CS
947 return NULL;
948}
949
950/*
951 * XPath:
2b2282eb 952 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/active
ce45ffe7
CS
953 */
954struct yang_data *
2b2282eb 955lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_active_get_elem(
60ee8be1 956 struct nb_cb_get_elem_args *args)
ce45ffe7 957{
5a634c34
CS
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
ce45ffe7
CS
963 return NULL;
964}
965
966/*
967 * XPath:
2b2282eb 968 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/fib
ce45ffe7
CS
969 */
970struct yang_data *
2b2282eb 971lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_fib_get_elem(
60ee8be1 972 struct nb_cb_get_elem_args *args)
ce45ffe7 973{
5a634c34
CS
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
ce45ffe7
CS
979 return NULL;
980}
7225e61c
CS
981
982/*
983 * XPath:
2b2282eb 984 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/weight
7225e61c
CS
985 */
986struct yang_data *
2b2282eb 987lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_weight_get_elem(
60ee8be1 988 struct nb_cb_get_elem_args *args)
7225e61c 989{
5a634c34
CS
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
7225e61c
CS
995 return NULL;
996}