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