Line data Source code
1 : /*
2 : * Copyright (C) 2018 NetDEF, Inc.
3 : * Renato Westphal
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 :
22 : #include "if.h"
23 : #include "vrf.h"
24 : #include "log.h"
25 : #include "prefix.h"
26 : #include "table.h"
27 : #include "command.h"
28 : #include "routemap.h"
29 : #include "northbound.h"
30 : #include "libfrr.h"
31 :
32 : #include "ripd/ripd.h"
33 : #include "ripd/rip_nb.h"
34 : #include "ripd/rip_debug.h"
35 : #include "ripd/rip_interface.h"
36 :
37 : /*
38 : * XPath: /frr-ripd:ripd/instance
39 : */
40 0 : const void *ripd_instance_get_next(struct nb_cb_get_next_args *args)
41 : {
42 0 : struct rip *rip = (struct rip *)args->list_entry;
43 :
44 0 : if (args->list_entry == NULL)
45 0 : rip = RB_MIN(rip_instance_head, &rip_instances);
46 : else
47 0 : rip = RB_NEXT(rip_instance_head, rip);
48 :
49 0 : return rip;
50 : }
51 :
52 0 : int ripd_instance_get_keys(struct nb_cb_get_keys_args *args)
53 : {
54 0 : const struct rip *rip = args->list_entry;
55 :
56 0 : args->keys->num = 1;
57 0 : strlcpy(args->keys->key[0], rip->vrf_name, sizeof(args->keys->key[0]));
58 :
59 0 : return NB_OK;
60 : }
61 :
62 0 : const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args)
63 : {
64 0 : const char *vrf_name = args->keys->key[0];
65 :
66 0 : return rip_lookup_by_vrf_name(vrf_name);
67 : }
68 :
69 : /*
70 : * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
71 : */
72 0 : const void *ripd_instance_state_neighbors_neighbor_get_next(
73 : struct nb_cb_get_next_args *args)
74 : {
75 0 : const struct rip *rip = args->parent_list_entry;
76 0 : struct listnode *node;
77 :
78 0 : if (args->list_entry == NULL)
79 0 : node = listhead(rip->peer_list);
80 : else
81 0 : node = listnextnode((struct listnode *)args->list_entry);
82 :
83 0 : return node;
84 : }
85 :
86 0 : int ripd_instance_state_neighbors_neighbor_get_keys(
87 : struct nb_cb_get_keys_args *args)
88 : {
89 0 : const struct listnode *node = args->list_entry;
90 0 : const struct rip_peer *peer = listgetdata(node);
91 :
92 0 : args->keys->num = 1;
93 0 : (void)inet_ntop(AF_INET, &peer->addr, args->keys->key[0],
94 : sizeof(args->keys->key[0]));
95 :
96 0 : return NB_OK;
97 : }
98 :
99 0 : const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
100 : struct nb_cb_lookup_entry_args *args)
101 : {
102 0 : const struct rip *rip = args->parent_list_entry;
103 0 : struct in_addr address;
104 0 : struct rip_peer *peer;
105 0 : struct listnode *node;
106 :
107 0 : yang_str2ipv4(args->keys->key[0], &address);
108 :
109 0 : for (ALL_LIST_ELEMENTS_RO(rip->peer_list, node, peer)) {
110 0 : if (IPV4_ADDR_SAME(&peer->addr, &address))
111 0 : return node;
112 : }
113 :
114 : return NULL;
115 : }
116 :
117 : /*
118 : * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address
119 : */
120 0 : struct yang_data *ripd_instance_state_neighbors_neighbor_address_get_elem(
121 : struct nb_cb_get_elem_args *args)
122 : {
123 0 : const struct listnode *node = args->list_entry;
124 0 : const struct rip_peer *peer = listgetdata(node);
125 :
126 0 : return yang_data_new_ipv4(args->xpath, &peer->addr);
127 : }
128 :
129 : /*
130 : * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
131 : */
132 0 : struct yang_data *ripd_instance_state_neighbors_neighbor_last_update_get_elem(
133 : struct nb_cb_get_elem_args *args)
134 : {
135 : /* TODO: yang:date-and-time is tricky */
136 0 : return NULL;
137 : }
138 :
139 : /*
140 : * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd
141 : */
142 : struct yang_data *
143 0 : ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
144 : struct nb_cb_get_elem_args *args)
145 : {
146 0 : const struct listnode *node = args->list_entry;
147 0 : const struct rip_peer *peer = listgetdata(node);
148 :
149 0 : return yang_data_new_uint32(args->xpath, peer->recv_badpackets);
150 : }
151 :
152 : /*
153 : * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
154 : */
155 : struct yang_data *
156 0 : ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
157 : struct nb_cb_get_elem_args *args)
158 : {
159 0 : const struct listnode *node = args->list_entry;
160 0 : const struct rip_peer *peer = listgetdata(node);
161 :
162 0 : return yang_data_new_uint32(args->xpath, peer->recv_badroutes);
163 : }
164 :
165 : /*
166 : * XPath: /frr-ripd:ripd/instance/state/routes/route
167 : */
168 : const void *
169 0 : ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args)
170 : {
171 0 : const struct rip *rip = args->parent_list_entry;
172 0 : struct route_node *rn;
173 :
174 0 : if (args->list_entry == NULL)
175 0 : rn = route_top(rip->table);
176 : else
177 0 : rn = route_next((struct route_node *)args->list_entry);
178 : /* Optimization: skip empty route nodes. */
179 0 : while (rn && rn->info == NULL)
180 0 : rn = route_next(rn);
181 :
182 0 : return rn;
183 : }
184 :
185 0 : int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args *args)
186 : {
187 0 : const struct route_node *rn = args->list_entry;
188 :
189 0 : args->keys->num = 1;
190 0 : (void)prefix2str(&rn->p, args->keys->key[0],
191 : sizeof(args->keys->key[0]));
192 :
193 0 : return NB_OK;
194 : }
195 :
196 0 : const void *ripd_instance_state_routes_route_lookup_entry(
197 : struct nb_cb_lookup_entry_args *args)
198 : {
199 0 : const struct rip *rip = args->parent_list_entry;
200 0 : struct prefix prefix;
201 0 : struct route_node *rn;
202 :
203 0 : yang_str2ipv4p(args->keys->key[0], &prefix);
204 :
205 0 : rn = route_node_lookup(rip->table, &prefix);
206 0 : if (!rn || !rn->info)
207 : return NULL;
208 :
209 0 : route_unlock_node(rn);
210 :
211 0 : return rn;
212 : }
213 :
214 : /*
215 : * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix
216 : */
217 0 : struct yang_data *ripd_instance_state_routes_route_prefix_get_elem(
218 : struct nb_cb_get_elem_args *args)
219 : {
220 0 : const struct route_node *rn = args->list_entry;
221 0 : const struct rip_info *rinfo = listnode_head(rn->info);
222 :
223 0 : return yang_data_new_ipv4p(args->xpath, &rinfo->rp->p);
224 : }
225 :
226 : /*
227 : * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
228 : */
229 0 : struct yang_data *ripd_instance_state_routes_route_next_hop_get_elem(
230 : struct nb_cb_get_elem_args *args)
231 : {
232 0 : const struct route_node *rn = args->list_entry;
233 0 : const struct rip_info *rinfo = listnode_head(rn->info);
234 :
235 0 : switch (rinfo->nh.type) {
236 0 : case NEXTHOP_TYPE_IPV4:
237 : case NEXTHOP_TYPE_IPV4_IFINDEX:
238 0 : return yang_data_new_ipv4(args->xpath, &rinfo->nh.gate.ipv4);
239 : case NEXTHOP_TYPE_IFINDEX:
240 : case NEXTHOP_TYPE_IPV6:
241 : case NEXTHOP_TYPE_IPV6_IFINDEX:
242 : case NEXTHOP_TYPE_BLACKHOLE:
243 : return NULL;
244 : }
245 :
246 0 : assert(!"Reached end of function where we do not expect to reach");
247 : }
248 :
249 : /*
250 : * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
251 : */
252 0 : struct yang_data *ripd_instance_state_routes_route_interface_get_elem(
253 : struct nb_cb_get_elem_args *args)
254 : {
255 0 : const struct route_node *rn = args->list_entry;
256 0 : const struct rip_info *rinfo = listnode_head(rn->info);
257 0 : const struct rip *rip = rip_info_get_instance(rinfo);
258 :
259 0 : switch (rinfo->nh.type) {
260 0 : case NEXTHOP_TYPE_IFINDEX:
261 : case NEXTHOP_TYPE_IPV4_IFINDEX:
262 0 : return yang_data_new_string(
263 : args->xpath,
264 0 : ifindex2ifname(rinfo->nh.ifindex, rip->vrf->vrf_id));
265 : case NEXTHOP_TYPE_IPV4:
266 : case NEXTHOP_TYPE_IPV6:
267 : case NEXTHOP_TYPE_IPV6_IFINDEX:
268 : case NEXTHOP_TYPE_BLACKHOLE:
269 : return NULL;
270 : }
271 :
272 0 : assert(!"Reached end of function where we do not expect to reach");
273 : }
274 :
275 : /*
276 : * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
277 : */
278 0 : struct yang_data *ripd_instance_state_routes_route_metric_get_elem(
279 : struct nb_cb_get_elem_args *args)
280 : {
281 0 : const struct route_node *rn = args->list_entry;
282 0 : const struct rip_info *rinfo = listnode_head(rn->info);
283 :
284 0 : return yang_data_new_uint8(args->xpath, rinfo->metric);
285 : }
|