]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_nb_state.c
Merge pull request #12791 from taspelund/loc_rib_json_fix
[mirror_frr.git] / ripd / rip_nb_state.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2018 NetDEF, Inc.
4 * Renato Westphal
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 */
27 const void *ripd_instance_get_next(struct nb_cb_get_next_args *args)
28 {
29 struct rip *rip = (struct rip *)args->list_entry;
30
31 if (args->list_entry == NULL)
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
39 int ripd_instance_get_keys(struct nb_cb_get_keys_args *args)
40 {
41 const struct rip *rip = args->list_entry;
42
43 args->keys->num = 1;
44 strlcpy(args->keys->key[0], rip->vrf_name, sizeof(args->keys->key[0]));
45
46 return NB_OK;
47 }
48
49 const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args)
50 {
51 const char *vrf_name = args->keys->key[0];
52
53 return rip_lookup_by_vrf_name(vrf_name);
54 }
55
56 /*
57 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
58 */
59 const void *ripd_instance_state_neighbors_neighbor_get_next(
60 struct nb_cb_get_next_args *args)
61 {
62 const struct rip *rip = args->parent_list_entry;
63 struct listnode *node;
64
65 if (args->list_entry == NULL)
66 node = listhead(rip->peer_list);
67 else
68 node = listnextnode((struct listnode *)args->list_entry);
69
70 return node;
71 }
72
73 int ripd_instance_state_neighbors_neighbor_get_keys(
74 struct nb_cb_get_keys_args *args)
75 {
76 const struct listnode *node = args->list_entry;
77 const struct rip_peer *peer = listgetdata(node);
78
79 args->keys->num = 1;
80 (void)inet_ntop(AF_INET, &peer->addr, args->keys->key[0],
81 sizeof(args->keys->key[0]));
82
83 return NB_OK;
84 }
85
86 const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
87 struct nb_cb_lookup_entry_args *args)
88 {
89 const struct rip *rip = args->parent_list_entry;
90 struct in_addr address;
91 struct rip_peer *peer;
92 struct listnode *node;
93
94 yang_str2ipv4(args->keys->key[0], &address);
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 */
107 struct yang_data *ripd_instance_state_neighbors_neighbor_address_get_elem(
108 struct nb_cb_get_elem_args *args)
109 {
110 const struct listnode *node = args->list_entry;
111 const struct rip_peer *peer = listgetdata(node);
112
113 return yang_data_new_ipv4(args->xpath, &peer->addr);
114 }
115
116 /*
117 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
118 */
119 struct yang_data *ripd_instance_state_neighbors_neighbor_last_update_get_elem(
120 struct nb_cb_get_elem_args *args)
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 */
129 struct yang_data *
130 ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
131 struct nb_cb_get_elem_args *args)
132 {
133 const struct listnode *node = args->list_entry;
134 const struct rip_peer *peer = listgetdata(node);
135
136 return yang_data_new_uint32(args->xpath, peer->recv_badpackets);
137 }
138
139 /*
140 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
141 */
142 struct yang_data *
143 ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
144 struct nb_cb_get_elem_args *args)
145 {
146 const struct listnode *node = args->list_entry;
147 const struct rip_peer *peer = listgetdata(node);
148
149 return yang_data_new_uint32(args->xpath, peer->recv_badroutes);
150 }
151
152 /*
153 * XPath: /frr-ripd:ripd/instance/state/routes/route
154 */
155 const void *
156 ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args)
157 {
158 const struct rip *rip = args->parent_list_entry;
159 struct route_node *rn;
160
161 if (args->list_entry == NULL)
162 rn = route_top(rip->table);
163 else
164 rn = route_next((struct route_node *)args->list_entry);
165 /* Optimization: skip empty route nodes. */
166 while (rn && rn->info == NULL)
167 rn = route_next(rn);
168
169 return rn;
170 }
171
172 int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args *args)
173 {
174 const struct route_node *rn = args->list_entry;
175
176 args->keys->num = 1;
177 (void)prefix2str(&rn->p, args->keys->key[0],
178 sizeof(args->keys->key[0]));
179
180 return NB_OK;
181 }
182
183 const void *ripd_instance_state_routes_route_lookup_entry(
184 struct nb_cb_lookup_entry_args *args)
185 {
186 const struct rip *rip = args->parent_list_entry;
187 struct prefix prefix;
188 struct route_node *rn;
189
190 yang_str2ipv4p(args->keys->key[0], &prefix);
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 */
204 struct yang_data *ripd_instance_state_routes_route_prefix_get_elem(
205 struct nb_cb_get_elem_args *args)
206 {
207 const struct route_node *rn = args->list_entry;
208 const struct rip_info *rinfo = listnode_head(rn->info);
209
210 return yang_data_new_ipv4p(args->xpath, &rinfo->rp->p);
211 }
212
213 /*
214 * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
215 */
216 struct yang_data *ripd_instance_state_routes_route_next_hop_get_elem(
217 struct nb_cb_get_elem_args *args)
218 {
219 const struct route_node *rn = args->list_entry;
220 const struct rip_info *rinfo = listnode_head(rn->info);
221
222 switch (rinfo->nh.type) {
223 case NEXTHOP_TYPE_IPV4:
224 case NEXTHOP_TYPE_IPV4_IFINDEX:
225 return yang_data_new_ipv4(args->xpath, &rinfo->nh.gate.ipv4);
226 case NEXTHOP_TYPE_IFINDEX:
227 case NEXTHOP_TYPE_IPV6:
228 case NEXTHOP_TYPE_IPV6_IFINDEX:
229 case NEXTHOP_TYPE_BLACKHOLE:
230 return NULL;
231 }
232
233 assert(!"Reached end of function where we do not expect to reach");
234 }
235
236 /*
237 * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
238 */
239 struct yang_data *ripd_instance_state_routes_route_interface_get_elem(
240 struct nb_cb_get_elem_args *args)
241 {
242 const struct route_node *rn = args->list_entry;
243 const struct rip_info *rinfo = listnode_head(rn->info);
244 const struct rip *rip = rip_info_get_instance(rinfo);
245
246 switch (rinfo->nh.type) {
247 case NEXTHOP_TYPE_IFINDEX:
248 case NEXTHOP_TYPE_IPV4_IFINDEX:
249 return yang_data_new_string(
250 args->xpath,
251 ifindex2ifname(rinfo->nh.ifindex, rip->vrf->vrf_id));
252 case NEXTHOP_TYPE_IPV4:
253 case NEXTHOP_TYPE_IPV6:
254 case NEXTHOP_TYPE_IPV6_IFINDEX:
255 case NEXTHOP_TYPE_BLACKHOLE:
256 return NULL;
257 }
258
259 assert(!"Reached end of function where we do not expect to reach");
260 }
261
262 /*
263 * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
264 */
265 struct yang_data *ripd_instance_state_routes_route_metric_get_elem(
266 struct nb_cb_get_elem_args *args)
267 {
268 const struct route_node *rn = args->list_entry;
269 const struct rip_info *rinfo = listnode_head(rn->info);
270
271 return yang_data_new_uint8(args->xpath, rinfo->metric);
272 }