1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2018 NetDEF, Inc.
16 #include "northbound.h"
19 #include "ripd/ripd.h"
20 #include "ripd/rip_nb.h"
21 #include "ripd/rip_debug.h"
22 #include "ripd/rip_interface.h"
25 * XPath: /frr-ripd:ripd/instance
27 const void *ripd_instance_get_next(struct nb_cb_get_next_args
*args
)
29 struct rip
*rip
= (struct rip
*)args
->list_entry
;
31 if (args
->list_entry
== NULL
)
32 rip
= RB_MIN(rip_instance_head
, &rip_instances
);
34 rip
= RB_NEXT(rip_instance_head
, rip
);
39 int ripd_instance_get_keys(struct nb_cb_get_keys_args
*args
)
41 const struct rip
*rip
= args
->list_entry
;
44 strlcpy(args
->keys
->key
[0], rip
->vrf_name
, sizeof(args
->keys
->key
[0]));
49 const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args
*args
)
51 const char *vrf_name
= args
->keys
->key
[0];
53 return rip_lookup_by_vrf_name(vrf_name
);
57 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
59 const void *ripd_instance_state_neighbors_neighbor_get_next(
60 struct nb_cb_get_next_args
*args
)
62 const struct rip
*rip
= args
->parent_list_entry
;
63 struct listnode
*node
;
65 if (args
->list_entry
== NULL
)
66 node
= listhead(rip
->peer_list
);
68 node
= listnextnode((struct listnode
*)args
->list_entry
);
73 int ripd_instance_state_neighbors_neighbor_get_keys(
74 struct nb_cb_get_keys_args
*args
)
76 const struct listnode
*node
= args
->list_entry
;
77 const struct rip_peer
*peer
= listgetdata(node
);
80 (void)inet_ntop(AF_INET
, &peer
->addr
, args
->keys
->key
[0],
81 sizeof(args
->keys
->key
[0]));
86 const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
87 struct nb_cb_lookup_entry_args
*args
)
89 const struct rip
*rip
= args
->parent_list_entry
;
90 struct in_addr address
;
91 struct rip_peer
*peer
;
92 struct listnode
*node
;
94 yang_str2ipv4(args
->keys
->key
[0], &address
);
96 for (ALL_LIST_ELEMENTS_RO(rip
->peer_list
, node
, peer
)) {
97 if (IPV4_ADDR_SAME(&peer
->addr
, &address
))
105 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address
107 struct yang_data
*ripd_instance_state_neighbors_neighbor_address_get_elem(
108 struct nb_cb_get_elem_args
*args
)
110 const struct listnode
*node
= args
->list_entry
;
111 const struct rip_peer
*peer
= listgetdata(node
);
113 return yang_data_new_ipv4(args
->xpath
, &peer
->addr
);
117 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
119 struct yang_data
*ripd_instance_state_neighbors_neighbor_last_update_get_elem(
120 struct nb_cb_get_elem_args
*args
)
122 /* TODO: yang:date-and-time is tricky */
127 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd
130 ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
131 struct nb_cb_get_elem_args
*args
)
133 const struct listnode
*node
= args
->list_entry
;
134 const struct rip_peer
*peer
= listgetdata(node
);
136 return yang_data_new_uint32(args
->xpath
, peer
->recv_badpackets
);
140 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
143 ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
144 struct nb_cb_get_elem_args
*args
)
146 const struct listnode
*node
= args
->list_entry
;
147 const struct rip_peer
*peer
= listgetdata(node
);
149 return yang_data_new_uint32(args
->xpath
, peer
->recv_badroutes
);
153 * XPath: /frr-ripd:ripd/instance/state/routes/route
156 ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args
*args
)
158 const struct rip
*rip
= args
->parent_list_entry
;
159 struct route_node
*rn
;
161 if (args
->list_entry
== NULL
)
162 rn
= route_top(rip
->table
);
164 rn
= route_next((struct route_node
*)args
->list_entry
);
165 /* Optimization: skip empty route nodes. */
166 while (rn
&& rn
->info
== NULL
)
172 int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args
*args
)
174 const struct route_node
*rn
= args
->list_entry
;
177 (void)prefix2str(&rn
->p
, args
->keys
->key
[0],
178 sizeof(args
->keys
->key
[0]));
183 const void *ripd_instance_state_routes_route_lookup_entry(
184 struct nb_cb_lookup_entry_args
*args
)
186 const struct rip
*rip
= args
->parent_list_entry
;
187 struct prefix prefix
;
188 struct route_node
*rn
;
190 yang_str2ipv4p(args
->keys
->key
[0], &prefix
);
192 rn
= route_node_lookup(rip
->table
, &prefix
);
193 if (!rn
|| !rn
->info
)
196 route_unlock_node(rn
);
202 * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix
204 struct yang_data
*ripd_instance_state_routes_route_prefix_get_elem(
205 struct nb_cb_get_elem_args
*args
)
207 const struct route_node
*rn
= args
->list_entry
;
208 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
211 return yang_data_new_ipv4p(args
->xpath
, &rinfo
->rp
->p
);
215 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop
217 const void *ripd_instance_state_routes_route_nexthops_nexthop_get_next(
218 struct nb_cb_get_next_args
*args
)
220 const struct route_node
*rn
= args
->parent_list_entry
;
221 const struct listnode
*node
= args
->list_entry
;
225 return listnextnode(node
);
227 return listhead((struct list
*)rn
->info
);
230 static inline const struct rip_info
*get_rip_info(const void *info
)
232 return (const struct rip_info
*)listgetdata(
233 (const struct listnode
*)info
);
237 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/nh-type
240 ripd_instance_state_routes_route_nexthops_nexthop_nh_type_get_elem(
241 struct nb_cb_get_elem_args
*args
)
243 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
246 return yang_data_new_enum(args
->xpath
, rinfo
->nh
.type
);
250 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/protocol
253 ripd_instance_state_routes_route_nexthops_nexthop_protocol_get_elem(
254 struct nb_cb_get_elem_args
*args
)
256 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
259 return yang_data_new_enum(args
->xpath
, rinfo
->type
);
263 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/rip-type
266 ripd_instance_state_routes_route_nexthops_nexthop_rip_type_get_elem(
267 struct nb_cb_get_elem_args
*args
)
269 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
272 return yang_data_new_enum(args
->xpath
, rinfo
->sub_type
);
276 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/gateway
279 ripd_instance_state_routes_route_nexthops_nexthop_gateway_get_elem(
280 struct nb_cb_get_elem_args
*args
)
282 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
284 if (rinfo
->nh
.type
!= NEXTHOP_TYPE_IPV4
&&
285 rinfo
->nh
.type
!= NEXTHOP_TYPE_IPV4_IFINDEX
)
288 return yang_data_new_ipv4(args
->xpath
, &rinfo
->nh
.gate
.ipv4
);
292 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/interface
295 ripd_instance_state_routes_route_nexthops_nexthop_interface_get_elem(
296 struct nb_cb_get_elem_args
*args
)
298 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
299 const struct rip
*rip
= rip_info_get_instance(rinfo
);
301 if (rinfo
->nh
.type
!= NEXTHOP_TYPE_IFINDEX
&&
302 rinfo
->nh
.type
!= NEXTHOP_TYPE_IPV4_IFINDEX
)
305 return yang_data_new_string(
307 ifindex2ifname(rinfo
->nh
.ifindex
, rip
->vrf
->vrf_id
));
311 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/from
314 ripd_instance_state_routes_route_nexthops_nexthop_from_get_elem(
315 struct nb_cb_get_elem_args
*args
)
317 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
319 if (rinfo
->type
!= ZEBRA_ROUTE_RIP
|| rinfo
->sub_type
!= RIP_ROUTE_RTE
)
322 return yang_data_new_ipv4(args
->xpath
, &rinfo
->from
);
326 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/tag
329 ripd_instance_state_routes_route_nexthops_nexthop_tag_get_elem(
330 struct nb_cb_get_elem_args
*args
)
332 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
334 return yang_data_new_uint32(args
->xpath
, rinfo
->tag
);
339 * /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/external-metric
342 ripd_instance_state_routes_route_nexthops_nexthop_external_metric_get_elem(
343 struct nb_cb_get_elem_args
*args
)
345 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
347 if ((rinfo
->type
== ZEBRA_ROUTE_RIP
&&
348 rinfo
->sub_type
== RIP_ROUTE_RTE
) ||
349 rinfo
->metric
== RIP_METRIC_INFINITY
|| rinfo
->external_metric
== 0)
351 return yang_data_new_uint32(args
->xpath
, rinfo
->external_metric
);
356 * /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/expire-time
359 ripd_instance_state_routes_route_nexthops_nexthop_expire_time_get_elem(
360 struct nb_cb_get_elem_args
*args
)
362 const struct rip_info
*rinfo
= get_rip_info(args
->list_entry
);
365 if ((event
= rinfo
->t_timeout
) == NULL
)
366 event
= rinfo
->t_garbage_collect
;
370 return yang_data_new_uint32(args
->xpath
,
371 event_timer_remain_second(event
));
375 * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
377 struct yang_data
*ripd_instance_state_routes_route_next_hop_get_elem(
378 struct nb_cb_get_elem_args
*args
)
380 const struct route_node
*rn
= args
->list_entry
;
381 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
383 switch (rinfo
->nh
.type
) {
384 case NEXTHOP_TYPE_IPV4
:
385 case NEXTHOP_TYPE_IPV4_IFINDEX
:
386 return yang_data_new_ipv4(args
->xpath
, &rinfo
->nh
.gate
.ipv4
);
387 case NEXTHOP_TYPE_IFINDEX
:
388 case NEXTHOP_TYPE_IPV6
:
389 case NEXTHOP_TYPE_IPV6_IFINDEX
:
390 case NEXTHOP_TYPE_BLACKHOLE
:
394 assert(!"Reached end of function where we do not expect to reach");
398 * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
400 struct yang_data
*ripd_instance_state_routes_route_interface_get_elem(
401 struct nb_cb_get_elem_args
*args
)
403 const struct route_node
*rn
= args
->list_entry
;
404 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
405 const struct rip
*rip
= rip_info_get_instance(rinfo
);
407 switch (rinfo
->nh
.type
) {
408 case NEXTHOP_TYPE_IFINDEX
:
409 case NEXTHOP_TYPE_IPV4_IFINDEX
:
410 return yang_data_new_string(
412 ifindex2ifname(rinfo
->nh
.ifindex
, rip
->vrf
->vrf_id
));
413 case NEXTHOP_TYPE_IPV4
:
414 case NEXTHOP_TYPE_IPV6
:
415 case NEXTHOP_TYPE_IPV6_IFINDEX
:
416 case NEXTHOP_TYPE_BLACKHOLE
:
420 assert(!"Reached end of function where we do not expect to reach");
424 * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
426 struct yang_data
*ripd_instance_state_routes_route_metric_get_elem(
427 struct nb_cb_get_elem_args
*args
)
429 const struct route_node
*rn
= args
->list_entry
;
430 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
432 return yang_data_new_uint8(args
->xpath
, rinfo
->metric
);