]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_nb_state.c
Merge pull request #7384 from opensourcerouting/nb-dyn-modules
[mirror_frr.git] / zebra / zebra_nb_state.c
CommitLineData
ce45ffe7
CS
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"
09268680 24#include "zebra/interface.h"
9d86e091 25#include "zebra/zebra_router.h"
5a634c34
CS
26#include "zebra/debug.h"
27#include "printfrr.h"
ce45ffe7 28
b00f3e4b
CS
29/*
30 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
31 */
32struct yang_data *
60ee8be1 33lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 34{
60ee8be1 35 const struct interface *ifp = args->list_entry;
09268680
CS
36 struct zebra_if *zebra_if;
37
38 zebra_if = ifp->info;
39
60ee8be1 40 return yang_data_new_uint16(args->xpath, zebra_if->up_count);
b00f3e4b
CS
41}
42
43/*
44 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/down-count
45 */
46struct yang_data *
60ee8be1 47lib_interface_zebra_state_down_count_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 48{
60ee8be1 49 const struct interface *ifp = args->list_entry;
09268680
CS
50 struct zebra_if *zebra_if;
51
52 zebra_if = ifp->info;
53
60ee8be1 54 return yang_data_new_uint16(args->xpath, zebra_if->down_count);
b00f3e4b
CS
55}
56
57/*
58 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/zif-type
59 */
60struct yang_data *
60ee8be1 61lib_interface_zebra_state_zif_type_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b
CS
62{
63 /* TODO: implement me. */
64 return NULL;
65}
66
67/*
68 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/ptm-status
69 */
70struct yang_data *
60ee8be1 71lib_interface_zebra_state_ptm_status_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b
CS
72{
73 /* TODO: implement me. */
74 return NULL;
75}
76
77/*
78 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vlan-id
79 */
80struct yang_data *
60ee8be1 81lib_interface_zebra_state_vlan_id_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 82{
60ee8be1 83 const struct interface *ifp = args->list_entry;
09268680
CS
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
60ee8be1 93 return yang_data_new_uint16(args->xpath, vlan_info->vid);
b00f3e4b
CS
94}
95
96/*
97 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vni-id
98 */
99struct yang_data *
60ee8be1 100lib_interface_zebra_state_vni_id_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 101{
60ee8be1 102 const struct interface *ifp = args->list_entry;
09268680
CS
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
60ee8be1 112 return yang_data_new_uint32(args->xpath, vxlan_info->vni);
b00f3e4b
CS
113}
114
115/*
116 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/remote-vtep
117 */
118struct yang_data *
60ee8be1 119lib_interface_zebra_state_remote_vtep_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 120{
60ee8be1 121 const struct interface *ifp = args->list_entry;
09268680
CS
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
60ee8be1 131 return yang_data_new_ipv4(args->xpath, &vxlan_info->vtep_ip);
b00f3e4b
CS
132}
133
134/*
135 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/mcast-group
136 */
137struct yang_data *
60ee8be1 138lib_interface_zebra_state_mcast_group_get_elem(struct nb_cb_get_elem_args *args)
b00f3e4b 139{
60ee8be1 140 const struct interface *ifp = args->list_entry;
09268680
CS
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
60ee8be1 150 return yang_data_new_ipv4(args->xpath, &vxlan_info->mcast_grp);
b00f3e4b
CS
151}
152
56a88b9e 153const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args)
ce45ffe7 154{
56a88b9e 155 struct vrf *vrf = (struct vrf *)args->parent_list_entry;
9d86e091 156 struct zebra_router_table *zrt =
56a88b9e 157 (struct zebra_router_table *)args->list_entry;
9d86e091
CS
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
56a88b9e 165 if (args->list_entry == NULL) {
9d86e091
CS
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;
ce45ffe7
CS
180}
181
56a88b9e 182int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args)
ce45ffe7 183{
56a88b9e 184 const struct zebra_router_table *zrt = args->list_entry;
9d86e091 185
56a88b9e 186 args->keys->num = 2;
9d86e091 187
755100ac 188 snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%s",
189 yang_afi_safi_value2identity(zrt->afi, zrt->safi));
6cde4b45 190 snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%u",
5a634c34 191 zrt->tableid);
9d86e091 192
ce45ffe7
CS
193 return NB_OK;
194}
195
56a88b9e
CS
196const void *
197lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args)
ce45ffe7 198{
56a88b9e 199 struct vrf *vrf = (struct vrf *)args->parent_list_entry;
9d86e091 200 struct zebra_vrf *zvrf;
5a634c34
CS
201 afi_t afi;
202 safi_t safi;
203 uint32_t table_id = 0;
9d86e091
CS
204
205 zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
206
755100ac 207 yang_afi_safi_identity2value(args->keys->key[0], &afi, &safi);
5a634c34
CS
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);
ce45ffe7
CS
214}
215
216/*
56a88b9e 217 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route
ce45ffe7 218 */
56a88b9e
CS
219const void *
220lib_vrf_zebra_ribs_rib_route_get_next(struct nb_cb_get_next_args *args)
ce45ffe7 221{
56a88b9e 222 const struct zebra_router_table *zrt = args->parent_list_entry;
78769ea2 223 struct route_node *rn = (struct route_node *)args->list_entry;
9d86e091 224
56a88b9e 225 if (args->list_entry == NULL)
9d86e091
CS
226 rn = route_top(zrt->table);
227 else
228 rn = srcdest_route_next((struct route_node *)rn);
78769ea2
RW
229 /* Optimization: skip empty route nodes. */
230 while (rn && rn->info == NULL)
231 rn = route_next(rn);
9d86e091 232
9b4d578f
RW
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
9d86e091 238 return rn;
ce45ffe7
CS
239}
240
56a88b9e 241int lib_vrf_zebra_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args)
ce45ffe7 242{
56a88b9e 243 const struct route_node *rn = args->list_entry;
9d86e091 244
56a88b9e
CS
245 args->keys->num = 1;
246 prefix2str(&rn->p, args->keys->key[0], sizeof(args->keys->key[0]));
9d86e091 247
ce45ffe7
CS
248 return NB_OK;
249}
250
251const void *
56a88b9e 252lib_vrf_zebra_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args)
ce45ffe7 253{
56a88b9e 254 const struct zebra_router_table *zrt = args->parent_list_entry;
9d86e091
CS
255 struct prefix p;
256 struct route_node *rn;
257
56a88b9e 258 yang_str2prefix(args->keys->key[0], &p);
9d86e091
CS
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;
ce45ffe7
CS
268}
269
270/*
56a88b9e 271 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/prefix
ce45ffe7 272 */
60ee8be1 273struct yang_data *
56a88b9e 274lib_vrf_zebra_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args)
ce45ffe7 275{
56a88b9e 276 const struct route_node *rn = args->list_entry;
9d86e091 277
56a88b9e 278 return yang_data_new_prefix(args->xpath, &rn->p);
ce45ffe7
CS
279}
280
281/*
56a88b9e 282 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry
ce45ffe7 283 */
56a88b9e
CS
284const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next(
285 struct nb_cb_get_next_args *args)
ed5abdb2 286{
5a634c34
CS
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);
9d86e091
CS
294
295 return re;
ed5abdb2
CS
296}
297
56a88b9e 298int lib_vrf_zebra_ribs_rib_route_route_entry_get_keys(
60ee8be1 299 struct nb_cb_get_keys_args *args)
ed5abdb2 300{
5a634c34
CS
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
ed5abdb2
CS
308 return NB_OK;
309}
310
56a88b9e 311const void *lib_vrf_zebra_ribs_rib_route_route_entry_lookup_entry(
60ee8be1 312 struct nb_cb_lookup_entry_args *args)
ce45ffe7 313{
5a634c34
CS
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
ce45ffe7
CS
327 return NULL;
328}
329
330/*
56a88b9e 331 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/protocol
ce45ffe7 332 */
56a88b9e 333struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_protocol_get_elem(
60ee8be1 334 struct nb_cb_get_elem_args *args)
ce45ffe7 335{
5a634c34
CS
336 struct route_entry *re = (struct route_entry *)args->list_entry;
337
338 return yang_data_new_enum(args->xpath, re->type);
ce45ffe7
CS
339}
340
341/*
56a88b9e 342 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/instance
ce45ffe7 343 */
56a88b9e 344struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_instance_get_elem(
60ee8be1 345 struct nb_cb_get_elem_args *args)
ce45ffe7 346{
5a634c34
CS
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
ce45ffe7
CS
352 return NULL;
353}
354
355/*
56a88b9e 356 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/distance
ce45ffe7 357 */
56a88b9e 358struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_distance_get_elem(
60ee8be1 359 struct nb_cb_get_elem_args *args)
ce45ffe7 360{
5a634c34
CS
361 struct route_entry *re = (struct route_entry *)args->list_entry;
362
363 return yang_data_new_uint8(args->xpath, re->distance);
ce45ffe7
CS
364}
365
366/*
56a88b9e 367 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/metric
ce45ffe7 368 */
56a88b9e 369struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_metric_get_elem(
60ee8be1 370 struct nb_cb_get_elem_args *args)
ce45ffe7 371{
5a634c34
CS
372 struct route_entry *re = (struct route_entry *)args->list_entry;
373
374 return yang_data_new_uint32(args->xpath, re->metric);
ce45ffe7
CS
375}
376
377/*
56a88b9e 378 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/tag
ce45ffe7 379 */
56a88b9e 380struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_tag_get_elem(
60ee8be1 381 struct nb_cb_get_elem_args *args)
ce45ffe7 382{
5a634c34
CS
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
ce45ffe7
CS
388 return NULL;
389}
390
391/*
56a88b9e 392 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/selected
ce45ffe7 393 */
56a88b9e 394struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_selected_get_elem(
60ee8be1 395 struct nb_cb_get_elem_args *args)
ce45ffe7 396{
5a634c34
CS
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
ce45ffe7
CS
402 return NULL;
403}
404
405/*
56a88b9e 406 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/installed
ce45ffe7 407 */
56a88b9e 408struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_installed_get_elem(
60ee8be1 409 struct nb_cb_get_elem_args *args)
ce45ffe7 410{
5a634c34
CS
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
ce45ffe7
CS
416 return NULL;
417}
418
419/*
56a88b9e 420 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/failed
ce45ffe7 421 */
56a88b9e 422struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_failed_get_elem(
60ee8be1 423 struct nb_cb_get_elem_args *args)
ce45ffe7 424{
5a634c34
CS
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
ce45ffe7
CS
430 return NULL;
431}
432
433/*
56a88b9e 434 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/queued
ce45ffe7 435 */
56a88b9e 436struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_queued_get_elem(
60ee8be1 437 struct nb_cb_get_elem_args *args)
ce45ffe7 438{
5a634c34
CS
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
ce45ffe7
CS
444 return NULL;
445}
446
447/*
56a88b9e
CS
448 * XPath:
449 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/internal-flags
ce45ffe7 450 */
56a88b9e
CS
451struct yang_data *
452lib_vrf_zebra_ribs_rib_route_route_entry_internal_flags_get_elem(
60ee8be1 453 struct nb_cb_get_elem_args *args)
ce45ffe7 454{
5a634c34
CS
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
ce45ffe7
CS
460 return NULL;
461}
462
463/*
56a88b9e
CS
464 * XPath:
465 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/internal-status
ce45ffe7 466 */
56a88b9e
CS
467struct yang_data *
468lib_vrf_zebra_ribs_rib_route_route_entry_internal_status_get_elem(
60ee8be1 469 struct nb_cb_get_elem_args *args)
ce45ffe7 470{
5a634c34
CS
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
ce45ffe7
CS
476 return NULL;
477}
478
479/*
56a88b9e 480 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/uptime
ce45ffe7 481 */
56a88b9e 482struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_get_elem(
60ee8be1 483 struct nb_cb_get_elem_args *args)
ce45ffe7 484{
5a634c34
CS
485 struct route_entry *re = (struct route_entry *)args->list_entry;
486
487 return yang_data_new_date_and_time(args->xpath, re->uptime);
ce45ffe7
CS
488}
489
490/*
56a88b9e 491 * XPath:
2b2282eb 492 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/id
ce45ffe7
CS
493 */
494struct yang_data *
2b2282eb 495lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_id_get_elem(
60ee8be1 496 struct nb_cb_get_elem_args *args)
ce45ffe7 497{
2b2282eb 498 struct route_entry *re = (struct route_entry *)args->list_entry;
5a634c34 499
2b2282eb 500 return yang_data_new_uint32(args->xpath, re->nhe->id);
ce45ffe7
CS
501}
502
503/*
504 * XPath:
2b2282eb 505 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop
ce45ffe7 506 */
ed5abdb2 507const void *
2b2282eb 508lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_next(
60ee8be1 509 struct nb_cb_get_next_args *args)
ce45ffe7 510{
5a634c34 511 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
2b2282eb
CS
512 struct route_entry *re = (struct route_entry *)args->parent_list_entry;
513 struct nhg_hash_entry *nhe = re->nhe;
5a634c34 514
2b2282eb 515 if (args->list_entry == NULL) {
5a634c34 516 nexthop = nhe->nhg.nexthop;
2b2282eb 517 } else
5a634c34
CS
518 nexthop = nexthop_next(nexthop);
519
520 return nexthop;
ce45ffe7
CS
521}
522
2b2282eb 523int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_get_keys(
60ee8be1 524 struct nb_cb_get_keys_args *args)
ce45ffe7 525{
5a634c34
CS
526 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
527
20e310a9 528 args->keys->num = 4;
5a634c34
CS
529
530 strlcpy(args->keys->key[0], yang_nexthop_type2str(nexthop->type),
531 sizeof(args->keys->key[0]));
532
20e310a9
CS
533 snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%" PRIu32,
534 nexthop->vrf_id);
535
5a634c34
CS
536 switch (nexthop->type) {
537 case NEXTHOP_TYPE_IPV4:
538 case NEXTHOP_TYPE_IPV4_IFINDEX:
20e310a9 539 snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
5a634c34
CS
540 "%pI4", &nexthop->gate.ipv4);
541 if (nexthop->ifindex)
20e310a9 542 strlcpy(args->keys->key[3],
5a634c34
CS
543 ifindex2ifname(nexthop->ifindex,
544 nexthop->vrf_id),
20e310a9 545 sizeof(args->keys->key[3]));
5a634c34
CS
546 else
547 /* no ifindex */
20e310a9
CS
548 strlcpy(args->keys->key[3], " ",
549 sizeof(args->keys->key[3]));
5a634c34
CS
550
551 break;
552 case NEXTHOP_TYPE_IPV6:
553 case NEXTHOP_TYPE_IPV6_IFINDEX:
20e310a9 554 snprintfrr(args->keys->key[2], sizeof(args->keys->key[2]),
5a634c34
CS
555 "%pI6", &nexthop->gate.ipv6);
556
557 if (nexthop->ifindex)
20e310a9 558 strlcpy(args->keys->key[3],
5a634c34
CS
559 ifindex2ifname(nexthop->ifindex,
560 nexthop->vrf_id),
20e310a9 561 sizeof(args->keys->key[3]));
5a634c34
CS
562 else
563 /* no ifindex */
20e310a9
CS
564 strlcpy(args->keys->key[3], " ",
565 sizeof(args->keys->key[3]));
5a634c34
CS
566
567 break;
568 case NEXTHOP_TYPE_IFINDEX:
20e310a9
CS
569 strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
570 strlcpy(args->keys->key[3],
5a634c34 571 ifindex2ifname(nexthop->ifindex, nexthop->vrf_id),
20e310a9 572 sizeof(args->keys->key[3]));
5a634c34
CS
573
574 break;
575 case NEXTHOP_TYPE_BLACKHOLE:
576 /* Gateway IP */
20e310a9
CS
577 strlcpy(args->keys->key[2], "", sizeof(args->keys->key[2]));
578 strlcpy(args->keys->key[3], " ", sizeof(args->keys->key[3]));
5a634c34
CS
579 break;
580 default:
581 break;
582 }
583
ce45ffe7
CS
584 return NB_OK;
585}
586
587const void *
2b2282eb 588lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_lookup_entry(
60ee8be1 589 struct nb_cb_lookup_entry_args *args)
ce45ffe7 590{
bf6f7f7d
RW
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
ce45ffe7
CS
657 return NULL;
658}
659
660/*
661 * XPath:
2b2282eb 662 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/nh-type
ce45ffe7
CS
663 */
664struct yang_data *
2b2282eb 665lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_nh_type_get_elem(
60ee8be1 666 struct nb_cb_get_elem_args *args)
ce45ffe7 667{
5a634c34
CS
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
ce45ffe7
CS
690 return NULL;
691}
692
693/*
694 * XPath:
2b2282eb 695 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/vrf
ce45ffe7
CS
696 */
697struct yang_data *
2b2282eb 698lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_vrf_get_elem(
60ee8be1 699 struct nb_cb_get_elem_args *args)
ce45ffe7 700{
5a634c34
CS
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));
ce45ffe7
CS
705}
706
707/*
708 * XPath:
2b2282eb 709 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/gateway
ce45ffe7
CS
710 */
711struct yang_data *
2b2282eb 712lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_gateway_get_elem(
60ee8be1 713 struct nb_cb_get_elem_args *args)
ce45ffe7 714{
5a634c34
CS
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);
ce45ffe7
CS
741}
742
743/*
744 * XPath:
2b2282eb 745 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/interface
ce45ffe7
CS
746 */
747struct yang_data *
2b2282eb 748lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_interface_get_elem(
60ee8be1 749 struct nb_cb_get_elem_args *args)
ce45ffe7 750{
5a634c34
CS
751 struct nexthop *nexthop = (struct nexthop *)args->list_entry;
752
753 if (nexthop->ifindex)
c17a3d0f 754 return yang_data_new_string(
5a634c34
CS
755 args->xpath,
756 ifindex2ifname(nexthop->ifindex, nexthop->vrf_id));
757
ce45ffe7
CS
758 return NULL;
759}
760
761/*
762 * XPath:
2b2282eb 763 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/bh-type
ce45ffe7
CS
764 */
765struct yang_data *
2b2282eb 766lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_bh_type_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 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);
ce45ffe7
CS
791}
792
793/*
794 * XPath:
2b2282eb 795 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/onlink
ce45ffe7
CS
796 */
797struct yang_data *
2b2282eb 798lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_onlink_get_elem(
60ee8be1 799 struct nb_cb_get_elem_args *args)
ce45ffe7 800{
5a634c34
CS
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
ce45ffe7
CS
806 return NULL;
807}
808
065276ae
SM
809/*
810 * XPath:
811 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/srte-color
812 */
813struct yang_data *
814lib_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
ce45ffe7
CS
825/*
826 * XPath:
2b2282eb 827 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry
ce45ffe7
CS
828 */
829const void *
2b2282eb 830lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_next(
60ee8be1 831 struct nb_cb_get_next_args *args)
ce45ffe7
CS
832{
833 /* TODO: implement me. */
834 return NULL;
835}
836
2b2282eb 837int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_get_keys(
60ee8be1 838 struct nb_cb_get_keys_args *args)
ce45ffe7
CS
839{
840 /* TODO: implement me. */
841 return NB_OK;
842}
843
844const void *
2b2282eb 845lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_lookup_entry(
60ee8be1 846 struct nb_cb_lookup_entry_args *args)
ce45ffe7
CS
847{
848 /* TODO: implement me. */
849 return NULL;
850}
851
852/*
853 * XPath:
2b2282eb 854 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/id
ce45ffe7
CS
855 */
856struct yang_data *
2b2282eb 857lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_id_get_elem(
60ee8be1 858 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
859{
860 /* TODO: implement me. */
861 return NULL;
862}
863
864/*
865 * XPath:
2b2282eb 866 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/label
ce45ffe7
CS
867 */
868struct yang_data *
2b2282eb 869lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_label_get_elem(
60ee8be1 870 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
871{
872 /* TODO: implement me. */
873 return NULL;
874}
875
876/*
877 * XPath:
2b2282eb 878 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/ttl
ce45ffe7
CS
879 */
880struct yang_data *
2b2282eb 881lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_ttl_get_elem(
60ee8be1 882 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
883{
884 /* TODO: implement me. */
885 return NULL;
886}
887
888/*
889 * XPath:
2b2282eb 890 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/mpls-label-stack/entry/traffic-class
ce45ffe7
CS
891 */
892struct yang_data *
2b2282eb 893lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_mpls_label_stack_entry_traffic_class_get_elem(
60ee8be1 894 struct nb_cb_get_elem_args *args)
ce45ffe7
CS
895{
896 /* TODO: implement me. */
897 return NULL;
898}
899
900/*
901 * XPath:
2b2282eb 902 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/duplicate
ce45ffe7
CS
903 */
904struct yang_data *
2b2282eb 905lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_duplicate_get_elem(
60ee8be1 906 struct nb_cb_get_elem_args *args)
ce45ffe7 907{
5a634c34
CS
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
ce45ffe7
CS
913 return NULL;
914}
915
916/*
917 * XPath:
2b2282eb 918 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/recursive
ce45ffe7
CS
919 */
920struct yang_data *
2b2282eb 921lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_recursive_get_elem(
60ee8be1 922 struct nb_cb_get_elem_args *args)
ce45ffe7 923{
5a634c34
CS
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
ce45ffe7
CS
929 return NULL;
930}
931
932/*
933 * XPath:
2b2282eb 934 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/active
ce45ffe7
CS
935 */
936struct yang_data *
2b2282eb 937lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_active_get_elem(
60ee8be1 938 struct nb_cb_get_elem_args *args)
ce45ffe7 939{
5a634c34
CS
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
ce45ffe7
CS
945 return NULL;
946}
947
948/*
949 * XPath:
2b2282eb 950 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/fib
ce45ffe7
CS
951 */
952struct yang_data *
2b2282eb 953lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_fib_get_elem(
60ee8be1 954 struct nb_cb_get_elem_args *args)
ce45ffe7 955{
5a634c34
CS
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
ce45ffe7
CS
961 return NULL;
962}
7225e61c
CS
963
964/*
965 * XPath:
2b2282eb 966 * /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop/weight
7225e61c
CS
967 */
968struct yang_data *
2b2282eb 969lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_nexthop_weight_get_elem(
60ee8be1 970 struct nb_cb_get_elem_args *args)
7225e61c 971{
5a634c34
CS
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
7225e61c
CS
977 return NULL;
978}