]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_nb_state.c
Merge pull request #13484 from sri-mohan1/srib-ldpd
[mirror_frr.git] / ripd / rip_nb_state.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
f80ec39e
RW
2/*
3 * Copyright (C) 2018 NetDEF, Inc.
4 * Renato Westphal
f80ec39e
RW
5 */
6
7#include <zebra.h>
8
9#include "if.h"
10#include "vrf.h"
11#include "log.h"
12#include "prefix.h"
13#include "table.h"
14#include "command.h"
15#include "routemap.h"
16#include "northbound.h"
17#include "libfrr.h"
18
19#include "ripd/ripd.h"
20#include "ripd/rip_nb.h"
21#include "ripd/rip_debug.h"
22#include "ripd/rip_interface.h"
23
24/*
25 * XPath: /frr-ripd:ripd/instance
26 */
60ee8be1 27const void *ripd_instance_get_next(struct nb_cb_get_next_args *args)
f80ec39e 28{
60ee8be1 29 struct rip *rip = (struct rip *)args->list_entry;
f80ec39e 30
60ee8be1 31 if (args->list_entry == NULL)
f80ec39e
RW
32 rip = RB_MIN(rip_instance_head, &rip_instances);
33 else
34 rip = RB_NEXT(rip_instance_head, rip);
35
36 return rip;
37}
38
60ee8be1 39int ripd_instance_get_keys(struct nb_cb_get_keys_args *args)
f80ec39e 40{
60ee8be1 41 const struct rip *rip = args->list_entry;
f80ec39e 42
60ee8be1
RW
43 args->keys->num = 1;
44 strlcpy(args->keys->key[0], rip->vrf_name, sizeof(args->keys->key[0]));
f80ec39e
RW
45
46 return NB_OK;
47}
48
60ee8be1 49const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args)
f80ec39e 50{
60ee8be1 51 const char *vrf_name = args->keys->key[0];
f80ec39e
RW
52
53 return rip_lookup_by_vrf_name(vrf_name);
54}
55
56/*
57 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
58 */
60ee8be1
RW
59const void *ripd_instance_state_neighbors_neighbor_get_next(
60 struct nb_cb_get_next_args *args)
f80ec39e 61{
60ee8be1 62 const struct rip *rip = args->parent_list_entry;
f80ec39e
RW
63 struct listnode *node;
64
60ee8be1 65 if (args->list_entry == NULL)
f80ec39e
RW
66 node = listhead(rip->peer_list);
67 else
60ee8be1 68 node = listnextnode((struct listnode *)args->list_entry);
f80ec39e
RW
69
70 return node;
71}
72
60ee8be1
RW
73int ripd_instance_state_neighbors_neighbor_get_keys(
74 struct nb_cb_get_keys_args *args)
f80ec39e 75{
60ee8be1 76 const struct listnode *node = args->list_entry;
f80ec39e
RW
77 const struct rip_peer *peer = listgetdata(node);
78
60ee8be1
RW
79 args->keys->num = 1;
80 (void)inet_ntop(AF_INET, &peer->addr, args->keys->key[0],
81 sizeof(args->keys->key[0]));
f80ec39e
RW
82
83 return NB_OK;
84}
85
86const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
60ee8be1 87 struct nb_cb_lookup_entry_args *args)
f80ec39e 88{
60ee8be1 89 const struct rip *rip = args->parent_list_entry;
f80ec39e
RW
90 struct in_addr address;
91 struct rip_peer *peer;
92 struct listnode *node;
93
60ee8be1 94 yang_str2ipv4(args->keys->key[0], &address);
f80ec39e
RW
95
96 for (ALL_LIST_ELEMENTS_RO(rip->peer_list, node, peer)) {
97 if (IPV4_ADDR_SAME(&peer->addr, &address))
98 return node;
99 }
100
101 return NULL;
102}
103
104/*
105 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address
106 */
60ee8be1
RW
107struct yang_data *ripd_instance_state_neighbors_neighbor_address_get_elem(
108 struct nb_cb_get_elem_args *args)
f80ec39e 109{
60ee8be1 110 const struct listnode *node = args->list_entry;
f80ec39e
RW
111 const struct rip_peer *peer = listgetdata(node);
112
60ee8be1 113 return yang_data_new_ipv4(args->xpath, &peer->addr);
f80ec39e
RW
114}
115
116/*
117 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
118 */
119struct yang_data *ripd_instance_state_neighbors_neighbor_last_update_get_elem(
60ee8be1 120 struct nb_cb_get_elem_args *args)
f80ec39e
RW
121{
122 /* TODO: yang:date-and-time is tricky */
123 return NULL;
124}
125
126/*
127 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd
128 */
129struct yang_data *
130ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
60ee8be1 131 struct nb_cb_get_elem_args *args)
f80ec39e 132{
60ee8be1 133 const struct listnode *node = args->list_entry;
f80ec39e
RW
134 const struct rip_peer *peer = listgetdata(node);
135
60ee8be1 136 return yang_data_new_uint32(args->xpath, peer->recv_badpackets);
f80ec39e
RW
137}
138
139/*
140 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
141 */
142struct yang_data *
143ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
60ee8be1 144 struct nb_cb_get_elem_args *args)
f80ec39e 145{
60ee8be1 146 const struct listnode *node = args->list_entry;
f80ec39e
RW
147 const struct rip_peer *peer = listgetdata(node);
148
60ee8be1 149 return yang_data_new_uint32(args->xpath, peer->recv_badroutes);
f80ec39e
RW
150}
151
152/*
153 * XPath: /frr-ripd:ripd/instance/state/routes/route
154 */
155const void *
60ee8be1 156ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args)
f80ec39e 157{
60ee8be1 158 const struct rip *rip = args->parent_list_entry;
f80ec39e
RW
159 struct route_node *rn;
160
60ee8be1 161 if (args->list_entry == NULL)
f80ec39e
RW
162 rn = route_top(rip->table);
163 else
60ee8be1 164 rn = route_next((struct route_node *)args->list_entry);
78769ea2 165 /* Optimization: skip empty route nodes. */
f80ec39e
RW
166 while (rn && rn->info == NULL)
167 rn = route_next(rn);
168
169 return rn;
170}
171
60ee8be1 172int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args *args)
f80ec39e 173{
60ee8be1 174 const struct route_node *rn = args->list_entry;
f80ec39e 175
60ee8be1
RW
176 args->keys->num = 1;
177 (void)prefix2str(&rn->p, args->keys->key[0],
178 sizeof(args->keys->key[0]));
f80ec39e
RW
179
180 return NB_OK;
181}
182
60ee8be1
RW
183const void *ripd_instance_state_routes_route_lookup_entry(
184 struct nb_cb_lookup_entry_args *args)
f80ec39e 185{
60ee8be1 186 const struct rip *rip = args->parent_list_entry;
f80ec39e
RW
187 struct prefix prefix;
188 struct route_node *rn;
189
60ee8be1 190 yang_str2ipv4p(args->keys->key[0], &prefix);
f80ec39e
RW
191
192 rn = route_node_lookup(rip->table, &prefix);
193 if (!rn || !rn->info)
194 return NULL;
195
196 route_unlock_node(rn);
197
198 return rn;
199}
200
201/*
202 * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix
203 */
60ee8be1
RW
204struct yang_data *ripd_instance_state_routes_route_prefix_get_elem(
205 struct nb_cb_get_elem_args *args)
f80ec39e 206{
60ee8be1 207 const struct route_node *rn = args->list_entry;
f80ec39e
RW
208 const struct rip_info *rinfo = listnode_head(rn->info);
209
7fd2ffb9 210 assert(rinfo);
60ee8be1 211 return yang_data_new_ipv4p(args->xpath, &rinfo->rp->p);
f80ec39e
RW
212}
213
0b7f0e35
CH
214/*
215 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop
216 */
217const void *ripd_instance_state_routes_route_nexthops_nexthop_get_next(
218 struct nb_cb_get_next_args *args)
219{
7fd2ffb9
CH
220 const struct route_node *rn = args->parent_list_entry;
221 const struct listnode *node = args->list_entry;
222
223 assert(rn);
224 if (node)
225 return listnextnode(node);
226 assert(rn->info);
227 return listhead((struct list *)rn->info);
228}
229
230static inline const struct rip_info *get_rip_info(const void *info)
231{
232 return (const struct rip_info *)listgetdata(
233 (const struct listnode *)info);
0b7f0e35
CH
234}
235
236/*
237 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/nh-type
238 */
239struct yang_data *
240ripd_instance_state_routes_route_nexthops_nexthop_nh_type_get_elem(
241 struct nb_cb_get_elem_args *args)
242{
7fd2ffb9
CH
243 const struct rip_info *rinfo = get_rip_info(args->list_entry);
244
245 assert(rinfo);
246 return yang_data_new_enum(args->xpath, rinfo->nh.type);
0b7f0e35
CH
247}
248
249/*
250 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/protocol
251 */
252struct yang_data *
253ripd_instance_state_routes_route_nexthops_nexthop_protocol_get_elem(
254 struct nb_cb_get_elem_args *args)
255{
7fd2ffb9
CH
256 const struct rip_info *rinfo = get_rip_info(args->list_entry);
257
258 assert(rinfo);
259 return yang_data_new_enum(args->xpath, rinfo->type);
0b7f0e35
CH
260}
261
262/*
263 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/rip-type
264 */
265struct yang_data *
266ripd_instance_state_routes_route_nexthops_nexthop_rip_type_get_elem(
267 struct nb_cb_get_elem_args *args)
268{
7fd2ffb9
CH
269 const struct rip_info *rinfo = get_rip_info(args->list_entry);
270
271 assert(rinfo);
272 return yang_data_new_enum(args->xpath, rinfo->sub_type);
0b7f0e35
CH
273}
274
275/*
276 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/gateway
277 */
278struct yang_data *
279ripd_instance_state_routes_route_nexthops_nexthop_gateway_get_elem(
280 struct nb_cb_get_elem_args *args)
281{
7fd2ffb9
CH
282 const struct rip_info *rinfo = get_rip_info(args->list_entry);
283
284 if (rinfo->nh.type != NEXTHOP_TYPE_IPV4 &&
285 rinfo->nh.type != NEXTHOP_TYPE_IPV4_IFINDEX)
286 return NULL;
287
288 return yang_data_new_ipv4(args->xpath, &rinfo->nh.gate.ipv4);
0b7f0e35
CH
289}
290
291/*
292 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/interface
293 */
294struct yang_data *
295ripd_instance_state_routes_route_nexthops_nexthop_interface_get_elem(
296 struct nb_cb_get_elem_args *args)
297{
7fd2ffb9
CH
298 const struct rip_info *rinfo = get_rip_info(args->list_entry);
299 const struct rip *rip = rip_info_get_instance(rinfo);
300
301 if (rinfo->nh.type != NEXTHOP_TYPE_IFINDEX &&
302 rinfo->nh.type != NEXTHOP_TYPE_IPV4_IFINDEX)
303 return NULL;
304
305 return yang_data_new_string(
306 args->xpath,
307 ifindex2ifname(rinfo->nh.ifindex, rip->vrf->vrf_id));
0b7f0e35
CH
308}
309
310/*
311 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/from
312 */
313struct yang_data *
314ripd_instance_state_routes_route_nexthops_nexthop_from_get_elem(
315 struct nb_cb_get_elem_args *args)
316{
7fd2ffb9
CH
317 const struct rip_info *rinfo = get_rip_info(args->list_entry);
318
319 if (rinfo->type != ZEBRA_ROUTE_RIP || rinfo->sub_type != RIP_ROUTE_RTE)
320 return NULL;
321
322 return yang_data_new_ipv4(args->xpath, &rinfo->from);
0b7f0e35
CH
323}
324
325/*
326 * XPath: /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/tag
327 */
328struct yang_data *
329ripd_instance_state_routes_route_nexthops_nexthop_tag_get_elem(
330 struct nb_cb_get_elem_args *args)
331{
7fd2ffb9
CH
332 const struct rip_info *rinfo = get_rip_info(args->list_entry);
333
334 return yang_data_new_uint32(args->xpath, rinfo->tag);
0b7f0e35
CH
335}
336
337/*
338 * XPath:
339 * /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/external-metric
340 */
341struct yang_data *
342ripd_instance_state_routes_route_nexthops_nexthop_external_metric_get_elem(
343 struct nb_cb_get_elem_args *args)
344{
7fd2ffb9
CH
345 const struct rip_info *rinfo = get_rip_info(args->list_entry);
346
347 if ((rinfo->type == ZEBRA_ROUTE_RIP &&
348 rinfo->sub_type == RIP_ROUTE_RTE) ||
349 rinfo->metric == RIP_METRIC_INFINITY || rinfo->external_metric == 0)
350 return NULL;
351 return yang_data_new_uint32(args->xpath, rinfo->external_metric);
0b7f0e35
CH
352}
353
354/*
355 * XPath:
356 * /frr-ripd:ripd/instance/state/routes/route/nexthops/nexthop/expire-time
357 */
358struct yang_data *
359ripd_instance_state_routes_route_nexthops_nexthop_expire_time_get_elem(
360 struct nb_cb_get_elem_args *args)
361{
7fd2ffb9
CH
362 const struct rip_info *rinfo = get_rip_info(args->list_entry);
363 struct event *event;
364
365 if ((event = rinfo->t_timeout) == NULL)
366 event = rinfo->t_garbage_collect;
367 if (!event)
368 return NULL;
369
370 return yang_data_new_uint32(args->xpath,
371 event_timer_remain_second(event));
0b7f0e35
CH
372}
373
f80ec39e
RW
374/*
375 * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
376 */
60ee8be1
RW
377struct yang_data *ripd_instance_state_routes_route_next_hop_get_elem(
378 struct nb_cb_get_elem_args *args)
f80ec39e 379{
60ee8be1 380 const struct route_node *rn = args->list_entry;
f80ec39e
RW
381 const struct rip_info *rinfo = listnode_head(rn->info);
382
383 switch (rinfo->nh.type) {
384 case NEXTHOP_TYPE_IPV4:
385 case NEXTHOP_TYPE_IPV4_IFINDEX:
60ee8be1 386 return yang_data_new_ipv4(args->xpath, &rinfo->nh.gate.ipv4);
ec378ba0
DS
387 case NEXTHOP_TYPE_IFINDEX:
388 case NEXTHOP_TYPE_IPV6:
389 case NEXTHOP_TYPE_IPV6_IFINDEX:
390 case NEXTHOP_TYPE_BLACKHOLE:
f80ec39e
RW
391 return NULL;
392 }
ec378ba0
DS
393
394 assert(!"Reached end of function where we do not expect to reach");
f80ec39e
RW
395}
396
397/*
398 * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
399 */
60ee8be1
RW
400struct yang_data *ripd_instance_state_routes_route_interface_get_elem(
401 struct nb_cb_get_elem_args *args)
f80ec39e 402{
60ee8be1 403 const struct route_node *rn = args->list_entry;
f80ec39e
RW
404 const struct rip_info *rinfo = listnode_head(rn->info);
405 const struct rip *rip = rip_info_get_instance(rinfo);
406
407 switch (rinfo->nh.type) {
408 case NEXTHOP_TYPE_IFINDEX:
409 case NEXTHOP_TYPE_IPV4_IFINDEX:
410 return yang_data_new_string(
60ee8be1 411 args->xpath,
f80ec39e 412 ifindex2ifname(rinfo->nh.ifindex, rip->vrf->vrf_id));
ec378ba0
DS
413 case NEXTHOP_TYPE_IPV4:
414 case NEXTHOP_TYPE_IPV6:
415 case NEXTHOP_TYPE_IPV6_IFINDEX:
416 case NEXTHOP_TYPE_BLACKHOLE:
f80ec39e
RW
417 return NULL;
418 }
ec378ba0
DS
419
420 assert(!"Reached end of function where we do not expect to reach");
f80ec39e
RW
421}
422
423/*
424 * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
425 */
60ee8be1
RW
426struct yang_data *ripd_instance_state_routes_route_metric_get_elem(
427 struct nb_cb_get_elem_args *args)
f80ec39e 428{
60ee8be1 429 const struct route_node *rn = args->list_entry;
f80ec39e
RW
430 const struct rip_info *rinfo = listnode_head(rn->info);
431
60ee8be1 432 return yang_data_new_uint8(args->xpath, rinfo->metric);
f80ec39e 433}