]>
Commit | Line | Data |
---|---|---|
f80ec39e RW |
1 | /* |
2 | * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org> | |
3 | * Copyright (C) 2018 NetDEF, Inc. | |
4 | * Renato Westphal | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the Free | |
8 | * Software Foundation; either version 2 of the License, or (at your option) | |
9 | * any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
14 | * more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License along | |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | */ | |
20 | ||
21 | #include <zebra.h> | |
22 | ||
23 | #include "if.h" | |
24 | #include "vrf.h" | |
25 | #include "log.h" | |
26 | #include "prefix.h" | |
27 | #include "table.h" | |
28 | #include "command.h" | |
29 | #include "routemap.h" | |
30 | #include "northbound.h" | |
31 | #include "libfrr.h" | |
32 | ||
33 | #include "ripd/ripd.h" | |
34 | #include "ripd/rip_nb.h" | |
35 | #include "ripd/rip_debug.h" | |
36 | #include "ripd/rip_interface.h" | |
37 | ||
38 | /* | |
39 | * XPath: /frr-ripd:ripd/instance | |
40 | */ | |
60ee8be1 | 41 | int ripd_instance_create(struct nb_cb_create_args *args) |
f80ec39e RW |
42 | { |
43 | struct rip *rip; | |
44 | struct vrf *vrf; | |
45 | const char *vrf_name; | |
46 | int socket; | |
47 | ||
60ee8be1 | 48 | vrf_name = yang_dnode_get_string(args->dnode, "./vrf"); |
f80ec39e RW |
49 | vrf = vrf_lookup_by_name(vrf_name); |
50 | ||
51 | /* | |
52 | * Try to create a RIP socket only if the VRF is enabled, otherwise | |
53 | * create a disabled RIP instance and wait for the VRF to be enabled. | |
54 | */ | |
60ee8be1 | 55 | switch (args->event) { |
f80ec39e RW |
56 | case NB_EV_VALIDATE: |
57 | break; | |
58 | case NB_EV_PREPARE: | |
59 | if (!vrf || !vrf_is_enabled(vrf)) | |
60 | break; | |
61 | ||
62 | socket = rip_create_socket(vrf); | |
63 | if (socket < 0) | |
64 | return NB_ERR_RESOURCE; | |
60ee8be1 | 65 | args->resource->fd = socket; |
f80ec39e RW |
66 | break; |
67 | case NB_EV_ABORT: | |
68 | if (!vrf || !vrf_is_enabled(vrf)) | |
69 | break; | |
70 | ||
60ee8be1 | 71 | socket = args->resource->fd; |
f80ec39e RW |
72 | close(socket); |
73 | break; | |
74 | case NB_EV_APPLY: | |
75 | if (vrf && vrf_is_enabled(vrf)) | |
60ee8be1 | 76 | socket = args->resource->fd; |
f80ec39e RW |
77 | else |
78 | socket = -1; | |
79 | ||
80 | rip = rip_create(vrf_name, vrf, socket); | |
60ee8be1 | 81 | nb_running_set_entry(args->dnode, rip); |
f80ec39e RW |
82 | break; |
83 | } | |
84 | ||
85 | return NB_OK; | |
86 | } | |
87 | ||
60ee8be1 | 88 | int ripd_instance_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
89 | { |
90 | struct rip *rip; | |
91 | ||
60ee8be1 | 92 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
93 | return NB_OK; |
94 | ||
60ee8be1 | 95 | rip = nb_running_unset_entry(args->dnode); |
f80ec39e RW |
96 | rip_clean(rip); |
97 | ||
98 | return NB_OK; | |
99 | } | |
100 | ||
101 | /* | |
102 | * XPath: /frr-ripd:ripd/instance/allow-ecmp | |
103 | */ | |
60ee8be1 | 104 | int ripd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
105 | { |
106 | struct rip *rip; | |
107 | ||
60ee8be1 | 108 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
109 | return NB_OK; |
110 | ||
60ee8be1 RW |
111 | rip = nb_running_get_entry(args->dnode, NULL, true); |
112 | rip->ecmp = yang_dnode_get_bool(args->dnode, NULL); | |
f80ec39e RW |
113 | if (!rip->ecmp) |
114 | rip_ecmp_disable(rip); | |
115 | ||
116 | return NB_OK; | |
117 | } | |
118 | ||
119 | /* | |
120 | * XPath: /frr-ripd:ripd/instance/default-information-originate | |
121 | */ | |
122 | int ripd_instance_default_information_originate_modify( | |
60ee8be1 | 123 | struct nb_cb_modify_args *args) |
f80ec39e RW |
124 | { |
125 | struct rip *rip; | |
126 | bool default_information; | |
127 | struct prefix_ipv4 p; | |
128 | ||
60ee8be1 | 129 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
130 | return NB_OK; |
131 | ||
60ee8be1 RW |
132 | rip = nb_running_get_entry(args->dnode, NULL, true); |
133 | default_information = yang_dnode_get_bool(args->dnode, NULL); | |
f80ec39e RW |
134 | |
135 | memset(&p, 0, sizeof(struct prefix_ipv4)); | |
136 | p.family = AF_INET; | |
137 | if (default_information) { | |
138 | struct nexthop nh; | |
139 | ||
140 | memset(&nh, 0, sizeof(nh)); | |
141 | nh.type = NEXTHOP_TYPE_IPV4; | |
142 | rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, | |
143 | &p, &nh, 0, 0, 0); | |
144 | } else { | |
145 | rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, | |
146 | &p, 0); | |
147 | } | |
148 | ||
149 | return NB_OK; | |
150 | } | |
151 | ||
152 | /* | |
153 | * XPath: /frr-ripd:ripd/instance/default-metric | |
154 | */ | |
60ee8be1 | 155 | int ripd_instance_default_metric_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
156 | { |
157 | struct rip *rip; | |
158 | ||
60ee8be1 | 159 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
160 | return NB_OK; |
161 | ||
60ee8be1 RW |
162 | rip = nb_running_get_entry(args->dnode, NULL, true); |
163 | rip->default_metric = yang_dnode_get_uint8(args->dnode, NULL); | |
f80ec39e RW |
164 | /* rip_update_default_metric (); */ |
165 | ||
166 | return NB_OK; | |
167 | } | |
168 | ||
169 | /* | |
170 | * XPath: /frr-ripd:ripd/instance/distance/default | |
171 | */ | |
60ee8be1 | 172 | int ripd_instance_distance_default_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
173 | { |
174 | struct rip *rip; | |
175 | ||
60ee8be1 | 176 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
177 | return NB_OK; |
178 | ||
60ee8be1 RW |
179 | rip = nb_running_get_entry(args->dnode, NULL, true); |
180 | rip->distance = yang_dnode_get_uint8(args->dnode, NULL); | |
f80ec39e RW |
181 | |
182 | return NB_OK; | |
183 | } | |
184 | ||
185 | /* | |
186 | * XPath: /frr-ripd:ripd/instance/distance/source | |
187 | */ | |
60ee8be1 | 188 | int ripd_instance_distance_source_create(struct nb_cb_create_args *args) |
f80ec39e RW |
189 | { |
190 | struct rip *rip; | |
191 | struct prefix_ipv4 prefix; | |
192 | struct route_node *rn; | |
193 | ||
60ee8be1 | 194 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
195 | return NB_OK; |
196 | ||
60ee8be1 | 197 | yang_dnode_get_ipv4p(&prefix, args->dnode, "./prefix"); |
f80ec39e RW |
198 | apply_mask_ipv4(&prefix); |
199 | ||
200 | /* Get RIP distance node. */ | |
60ee8be1 | 201 | rip = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
202 | rn = route_node_get(rip->distance_table, (struct prefix *)&prefix); |
203 | rn->info = rip_distance_new(); | |
60ee8be1 | 204 | nb_running_set_entry(args->dnode, rn); |
f80ec39e RW |
205 | |
206 | return NB_OK; | |
207 | } | |
208 | ||
60ee8be1 | 209 | int ripd_instance_distance_source_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
210 | { |
211 | struct route_node *rn; | |
212 | struct rip_distance *rdistance; | |
213 | ||
60ee8be1 | 214 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
215 | return NB_OK; |
216 | ||
60ee8be1 | 217 | rn = nb_running_unset_entry(args->dnode); |
f80ec39e RW |
218 | rdistance = rn->info; |
219 | rip_distance_free(rdistance); | |
220 | rn->info = NULL; | |
221 | route_unlock_node(rn); | |
222 | ||
223 | return NB_OK; | |
224 | } | |
225 | ||
226 | /* | |
227 | * XPath: /frr-ripd:ripd/instance/distance/source/distance | |
228 | */ | |
60ee8be1 RW |
229 | int ripd_instance_distance_source_distance_modify( |
230 | struct nb_cb_modify_args *args) | |
f80ec39e RW |
231 | { |
232 | struct route_node *rn; | |
233 | uint8_t distance; | |
234 | struct rip_distance *rdistance; | |
235 | ||
60ee8be1 | 236 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
237 | return NB_OK; |
238 | ||
239 | /* Set distance value. */ | |
60ee8be1 RW |
240 | rn = nb_running_get_entry(args->dnode, NULL, true); |
241 | distance = yang_dnode_get_uint8(args->dnode, NULL); | |
f80ec39e RW |
242 | rdistance = rn->info; |
243 | rdistance->distance = distance; | |
244 | ||
245 | return NB_OK; | |
246 | } | |
247 | ||
248 | /* | |
249 | * XPath: /frr-ripd:ripd/instance/distance/source/access-list | |
250 | */ | |
251 | int ripd_instance_distance_source_access_list_modify( | |
60ee8be1 | 252 | struct nb_cb_modify_args *args) |
f80ec39e RW |
253 | { |
254 | const char *acl_name; | |
255 | struct route_node *rn; | |
256 | struct rip_distance *rdistance; | |
257 | ||
60ee8be1 | 258 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
259 | return NB_OK; |
260 | ||
60ee8be1 | 261 | acl_name = yang_dnode_get_string(args->dnode, NULL); |
f80ec39e RW |
262 | |
263 | /* Set access-list */ | |
60ee8be1 | 264 | rn = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
265 | rdistance = rn->info; |
266 | if (rdistance->access_list) | |
267 | free(rdistance->access_list); | |
268 | rdistance->access_list = strdup(acl_name); | |
269 | ||
270 | return NB_OK; | |
271 | } | |
272 | ||
273 | int ripd_instance_distance_source_access_list_destroy( | |
60ee8be1 | 274 | struct nb_cb_destroy_args *args) |
f80ec39e RW |
275 | { |
276 | struct route_node *rn; | |
277 | struct rip_distance *rdistance; | |
278 | ||
60ee8be1 | 279 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
280 | return NB_OK; |
281 | ||
282 | /* Reset access-list configuration. */ | |
60ee8be1 | 283 | rn = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
284 | rdistance = rn->info; |
285 | free(rdistance->access_list); | |
286 | rdistance->access_list = NULL; | |
287 | ||
288 | return NB_OK; | |
289 | } | |
290 | ||
291 | /* | |
292 | * XPath: /frr-ripd:ripd/instance/explicit-neighbor | |
293 | */ | |
60ee8be1 | 294 | int ripd_instance_explicit_neighbor_create(struct nb_cb_create_args *args) |
f80ec39e RW |
295 | { |
296 | struct rip *rip; | |
297 | struct prefix_ipv4 p; | |
298 | ||
60ee8be1 | 299 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
300 | return NB_OK; |
301 | ||
60ee8be1 | 302 | rip = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
303 | p.family = AF_INET; |
304 | p.prefixlen = IPV4_MAX_BITLEN; | |
60ee8be1 | 305 | yang_dnode_get_ipv4(&p.prefix, args->dnode, NULL); |
f80ec39e RW |
306 | |
307 | return rip_neighbor_add(rip, &p); | |
308 | } | |
309 | ||
60ee8be1 | 310 | int ripd_instance_explicit_neighbor_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
311 | { |
312 | struct rip *rip; | |
313 | struct prefix_ipv4 p; | |
314 | ||
60ee8be1 | 315 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
316 | return NB_OK; |
317 | ||
60ee8be1 | 318 | rip = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
319 | p.family = AF_INET; |
320 | p.prefixlen = IPV4_MAX_BITLEN; | |
60ee8be1 | 321 | yang_dnode_get_ipv4(&p.prefix, args->dnode, NULL); |
f80ec39e RW |
322 | |
323 | return rip_neighbor_delete(rip, &p); | |
324 | } | |
325 | ||
326 | /* | |
327 | * XPath: /frr-ripd:ripd/instance/network | |
328 | */ | |
60ee8be1 | 329 | int ripd_instance_network_create(struct nb_cb_create_args *args) |
f80ec39e RW |
330 | { |
331 | struct rip *rip; | |
332 | struct prefix p; | |
333 | ||
60ee8be1 | 334 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
335 | return NB_OK; |
336 | ||
60ee8be1 RW |
337 | rip = nb_running_get_entry(args->dnode, NULL, true); |
338 | yang_dnode_get_ipv4p(&p, args->dnode, NULL); | |
f80ec39e RW |
339 | apply_mask_ipv4((struct prefix_ipv4 *)&p); |
340 | ||
341 | return rip_enable_network_add(rip, &p); | |
342 | } | |
343 | ||
60ee8be1 | 344 | int ripd_instance_network_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
345 | { |
346 | struct rip *rip; | |
347 | struct prefix p; | |
348 | ||
60ee8be1 | 349 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
350 | return NB_OK; |
351 | ||
60ee8be1 RW |
352 | rip = nb_running_get_entry(args->dnode, NULL, true); |
353 | yang_dnode_get_ipv4p(&p, args->dnode, NULL); | |
f80ec39e RW |
354 | apply_mask_ipv4((struct prefix_ipv4 *)&p); |
355 | ||
356 | return rip_enable_network_delete(rip, &p); | |
357 | } | |
358 | ||
359 | /* | |
360 | * XPath: /frr-ripd:ripd/instance/interface | |
361 | */ | |
60ee8be1 | 362 | int ripd_instance_interface_create(struct nb_cb_create_args *args) |
f80ec39e RW |
363 | { |
364 | struct rip *rip; | |
365 | const char *ifname; | |
366 | ||
60ee8be1 | 367 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
368 | return NB_OK; |
369 | ||
60ee8be1 RW |
370 | rip = nb_running_get_entry(args->dnode, NULL, true); |
371 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
372 | |
373 | return rip_enable_if_add(rip, ifname); | |
374 | } | |
375 | ||
60ee8be1 | 376 | int ripd_instance_interface_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
377 | { |
378 | struct rip *rip; | |
379 | const char *ifname; | |
380 | ||
60ee8be1 | 381 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
382 | return NB_OK; |
383 | ||
60ee8be1 RW |
384 | rip = nb_running_get_entry(args->dnode, NULL, true); |
385 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
386 | |
387 | return rip_enable_if_delete(rip, ifname); | |
388 | } | |
389 | ||
390 | /* | |
391 | * XPath: /frr-ripd:ripd/instance/offset-list | |
392 | */ | |
60ee8be1 | 393 | int ripd_instance_offset_list_create(struct nb_cb_create_args *args) |
f80ec39e RW |
394 | { |
395 | struct rip *rip; | |
396 | const char *ifname; | |
397 | struct rip_offset_list *offset; | |
398 | ||
60ee8be1 | 399 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
400 | return NB_OK; |
401 | ||
60ee8be1 RW |
402 | rip = nb_running_get_entry(args->dnode, NULL, true); |
403 | ifname = yang_dnode_get_string(args->dnode, "./interface"); | |
f80ec39e RW |
404 | |
405 | offset = rip_offset_list_new(rip, ifname); | |
60ee8be1 | 406 | nb_running_set_entry(args->dnode, offset); |
f80ec39e RW |
407 | |
408 | return NB_OK; | |
409 | } | |
410 | ||
60ee8be1 | 411 | int ripd_instance_offset_list_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
412 | { |
413 | int direct; | |
414 | struct rip_offset_list *offset; | |
415 | ||
60ee8be1 | 416 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
417 | return NB_OK; |
418 | ||
60ee8be1 | 419 | direct = yang_dnode_get_enum(args->dnode, "./direction"); |
f80ec39e | 420 | |
60ee8be1 | 421 | offset = nb_running_unset_entry(args->dnode); |
f80ec39e RW |
422 | if (offset->direct[direct].alist_name) { |
423 | free(offset->direct[direct].alist_name); | |
424 | offset->direct[direct].alist_name = NULL; | |
425 | } | |
426 | if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL | |
427 | && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL) | |
428 | offset_list_del(offset); | |
429 | ||
430 | return NB_OK; | |
431 | } | |
432 | ||
433 | /* | |
434 | * XPath: /frr-ripd:ripd/instance/offset-list/access-list | |
435 | */ | |
60ee8be1 | 436 | int ripd_instance_offset_list_access_list_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
437 | { |
438 | int direct; | |
439 | struct rip_offset_list *offset; | |
440 | const char *alist_name; | |
441 | ||
60ee8be1 | 442 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
443 | return NB_OK; |
444 | ||
60ee8be1 RW |
445 | direct = yang_dnode_get_enum(args->dnode, "../direction"); |
446 | alist_name = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e | 447 | |
60ee8be1 | 448 | offset = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
449 | if (offset->direct[direct].alist_name) |
450 | free(offset->direct[direct].alist_name); | |
451 | offset->direct[direct].alist_name = strdup(alist_name); | |
452 | ||
453 | return NB_OK; | |
454 | } | |
455 | ||
456 | /* | |
457 | * XPath: /frr-ripd:ripd/instance/offset-list/metric | |
458 | */ | |
60ee8be1 | 459 | int ripd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
460 | { |
461 | int direct; | |
462 | uint8_t metric; | |
463 | struct rip_offset_list *offset; | |
464 | ||
60ee8be1 | 465 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
466 | return NB_OK; |
467 | ||
60ee8be1 RW |
468 | direct = yang_dnode_get_enum(args->dnode, "../direction"); |
469 | metric = yang_dnode_get_uint8(args->dnode, NULL); | |
f80ec39e | 470 | |
60ee8be1 | 471 | offset = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
472 | offset->direct[direct].metric = metric; |
473 | ||
474 | return NB_OK; | |
475 | } | |
476 | ||
477 | /* | |
478 | * XPath: /frr-ripd:ripd/instance/passive-default | |
479 | */ | |
60ee8be1 | 480 | int ripd_instance_passive_default_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
481 | { |
482 | struct rip *rip; | |
483 | ||
60ee8be1 | 484 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
485 | return NB_OK; |
486 | ||
60ee8be1 RW |
487 | rip = nb_running_get_entry(args->dnode, NULL, true); |
488 | rip->passive_default = yang_dnode_get_bool(args->dnode, NULL); | |
f80ec39e RW |
489 | rip_passive_nondefault_clean(rip); |
490 | ||
491 | return NB_OK; | |
492 | } | |
493 | ||
494 | /* | |
495 | * XPath: /frr-ripd:ripd/instance/passive-interface | |
496 | */ | |
60ee8be1 | 497 | int ripd_instance_passive_interface_create(struct nb_cb_create_args *args) |
f80ec39e RW |
498 | { |
499 | struct rip *rip; | |
500 | const char *ifname; | |
501 | ||
60ee8be1 | 502 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
503 | return NB_OK; |
504 | ||
60ee8be1 RW |
505 | rip = nb_running_get_entry(args->dnode, NULL, true); |
506 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
507 | |
508 | return rip_passive_nondefault_set(rip, ifname); | |
509 | } | |
510 | ||
60ee8be1 | 511 | int ripd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
512 | { |
513 | struct rip *rip; | |
514 | const char *ifname; | |
515 | ||
60ee8be1 | 516 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
517 | return NB_OK; |
518 | ||
60ee8be1 RW |
519 | rip = nb_running_get_entry(args->dnode, NULL, true); |
520 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
521 | |
522 | return rip_passive_nondefault_unset(rip, ifname); | |
523 | } | |
524 | ||
525 | /* | |
526 | * XPath: /frr-ripd:ripd/instance/non-passive-interface | |
527 | */ | |
60ee8be1 | 528 | int ripd_instance_non_passive_interface_create(struct nb_cb_create_args *args) |
f80ec39e RW |
529 | { |
530 | struct rip *rip; | |
531 | const char *ifname; | |
532 | ||
60ee8be1 | 533 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
534 | return NB_OK; |
535 | ||
60ee8be1 RW |
536 | rip = nb_running_get_entry(args->dnode, NULL, true); |
537 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
538 | |
539 | return rip_passive_nondefault_unset(rip, ifname); | |
540 | } | |
541 | ||
60ee8be1 | 542 | int ripd_instance_non_passive_interface_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
543 | { |
544 | struct rip *rip; | |
545 | const char *ifname; | |
546 | ||
60ee8be1 | 547 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
548 | return NB_OK; |
549 | ||
60ee8be1 RW |
550 | rip = nb_running_get_entry(args->dnode, NULL, true); |
551 | ifname = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
552 | |
553 | return rip_passive_nondefault_set(rip, ifname); | |
554 | } | |
555 | ||
556 | /* | |
557 | * XPath: /frr-ripd:ripd/instance/redistribute | |
558 | */ | |
60ee8be1 | 559 | int ripd_instance_redistribute_create(struct nb_cb_create_args *args) |
f80ec39e RW |
560 | { |
561 | struct rip *rip; | |
562 | int type; | |
563 | ||
60ee8be1 | 564 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
565 | return NB_OK; |
566 | ||
60ee8be1 RW |
567 | rip = nb_running_get_entry(args->dnode, NULL, true); |
568 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
f80ec39e RW |
569 | |
570 | rip->redist[type].enabled = true; | |
571 | ||
572 | return NB_OK; | |
573 | } | |
574 | ||
60ee8be1 | 575 | int ripd_instance_redistribute_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
576 | { |
577 | struct rip *rip; | |
578 | int type; | |
579 | ||
60ee8be1 | 580 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
581 | return NB_OK; |
582 | ||
60ee8be1 RW |
583 | rip = nb_running_get_entry(args->dnode, NULL, true); |
584 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
f80ec39e RW |
585 | |
586 | rip->redist[type].enabled = false; | |
587 | if (rip->redist[type].route_map.name) { | |
588 | free(rip->redist[type].route_map.name); | |
589 | rip->redist[type].route_map.name = NULL; | |
590 | rip->redist[type].route_map.map = NULL; | |
591 | } | |
592 | rip->redist[type].metric_config = false; | |
593 | rip->redist[type].metric = 0; | |
594 | ||
595 | if (rip->enabled) | |
596 | rip_redistribute_conf_delete(rip, type); | |
597 | ||
598 | return NB_OK; | |
599 | } | |
600 | ||
60ee8be1 RW |
601 | void ripd_instance_redistribute_apply_finish( |
602 | struct nb_cb_apply_finish_args *args) | |
f80ec39e RW |
603 | { |
604 | struct rip *rip; | |
605 | int type; | |
606 | ||
60ee8be1 RW |
607 | rip = nb_running_get_entry(args->dnode, NULL, true); |
608 | type = yang_dnode_get_enum(args->dnode, "./protocol"); | |
f80ec39e RW |
609 | |
610 | if (rip->enabled) | |
611 | rip_redistribute_conf_update(rip, type); | |
612 | } | |
613 | ||
614 | /* | |
615 | * XPath: /frr-ripd:ripd/instance/redistribute/route-map | |
616 | */ | |
60ee8be1 | 617 | int ripd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
618 | { |
619 | struct rip *rip; | |
620 | int type; | |
621 | const char *rmap_name; | |
622 | ||
60ee8be1 | 623 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
624 | return NB_OK; |
625 | ||
60ee8be1 RW |
626 | rip = nb_running_get_entry(args->dnode, NULL, true); |
627 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
628 | rmap_name = yang_dnode_get_string(args->dnode, NULL); | |
f80ec39e RW |
629 | |
630 | if (rip->redist[type].route_map.name) | |
631 | free(rip->redist[type].route_map.name); | |
632 | rip->redist[type].route_map.name = strdup(rmap_name); | |
633 | rip->redist[type].route_map.map = route_map_lookup_by_name(rmap_name); | |
634 | ||
635 | return NB_OK; | |
636 | } | |
637 | ||
60ee8be1 RW |
638 | int ripd_instance_redistribute_route_map_destroy( |
639 | struct nb_cb_destroy_args *args) | |
f80ec39e RW |
640 | { |
641 | struct rip *rip; | |
642 | int type; | |
643 | ||
60ee8be1 | 644 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
645 | return NB_OK; |
646 | ||
60ee8be1 RW |
647 | rip = nb_running_get_entry(args->dnode, NULL, true); |
648 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
f80ec39e RW |
649 | |
650 | free(rip->redist[type].route_map.name); | |
651 | rip->redist[type].route_map.name = NULL; | |
652 | rip->redist[type].route_map.map = NULL; | |
653 | ||
654 | return NB_OK; | |
655 | } | |
656 | ||
657 | /* | |
658 | * XPath: /frr-ripd:ripd/instance/redistribute/metric | |
659 | */ | |
60ee8be1 | 660 | int ripd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
661 | { |
662 | struct rip *rip; | |
663 | int type; | |
664 | uint8_t metric; | |
665 | ||
60ee8be1 | 666 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
667 | return NB_OK; |
668 | ||
60ee8be1 RW |
669 | rip = nb_running_get_entry(args->dnode, NULL, true); |
670 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
671 | metric = yang_dnode_get_uint8(args->dnode, NULL); | |
f80ec39e RW |
672 | |
673 | rip->redist[type].metric_config = true; | |
674 | rip->redist[type].metric = metric; | |
675 | ||
676 | return NB_OK; | |
677 | } | |
678 | ||
60ee8be1 | 679 | int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
680 | { |
681 | struct rip *rip; | |
682 | int type; | |
683 | ||
60ee8be1 | 684 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
685 | return NB_OK; |
686 | ||
60ee8be1 RW |
687 | rip = nb_running_get_entry(args->dnode, NULL, true); |
688 | type = yang_dnode_get_enum(args->dnode, "../protocol"); | |
f80ec39e RW |
689 | |
690 | rip->redist[type].metric_config = false; | |
691 | rip->redist[type].metric = 0; | |
692 | ||
693 | return NB_OK; | |
694 | } | |
695 | ||
696 | /* | |
697 | * XPath: /frr-ripd:ripd/instance/static-route | |
698 | */ | |
60ee8be1 | 699 | int ripd_instance_static_route_create(struct nb_cb_create_args *args) |
f80ec39e RW |
700 | { |
701 | struct rip *rip; | |
702 | struct nexthop nh; | |
703 | struct prefix_ipv4 p; | |
704 | ||
60ee8be1 | 705 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
706 | return NB_OK; |
707 | ||
60ee8be1 RW |
708 | rip = nb_running_get_entry(args->dnode, NULL, true); |
709 | yang_dnode_get_ipv4p(&p, args->dnode, NULL); | |
f80ec39e RW |
710 | apply_mask_ipv4(&p); |
711 | ||
712 | memset(&nh, 0, sizeof(nh)); | |
713 | nh.type = NEXTHOP_TYPE_IPV4; | |
714 | rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0, | |
715 | 0, 0); | |
716 | ||
717 | return NB_OK; | |
718 | } | |
719 | ||
60ee8be1 | 720 | int ripd_instance_static_route_destroy(struct nb_cb_destroy_args *args) |
f80ec39e RW |
721 | { |
722 | struct rip *rip; | |
723 | struct prefix_ipv4 p; | |
724 | ||
60ee8be1 | 725 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
726 | return NB_OK; |
727 | ||
60ee8be1 RW |
728 | rip = nb_running_get_entry(args->dnode, NULL, true); |
729 | yang_dnode_get_ipv4p(&p, args->dnode, NULL); | |
f80ec39e RW |
730 | apply_mask_ipv4(&p); |
731 | ||
732 | rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); | |
733 | ||
734 | return NB_OK; | |
735 | } | |
736 | ||
737 | /* | |
738 | * XPath: /frr-ripd:ripd/instance/timers/ | |
739 | */ | |
60ee8be1 | 740 | void ripd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args) |
f80ec39e RW |
741 | { |
742 | struct rip *rip; | |
743 | ||
60ee8be1 | 744 | rip = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
745 | |
746 | /* Reset update timer thread. */ | |
747 | rip_event(rip, RIP_UPDATE_EVENT, 0); | |
748 | } | |
749 | ||
750 | /* | |
751 | * XPath: /frr-ripd:ripd/instance/timers/flush-interval | |
752 | */ | |
60ee8be1 | 753 | int ripd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
754 | { |
755 | struct rip *rip; | |
756 | ||
60ee8be1 | 757 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
758 | return NB_OK; |
759 | ||
60ee8be1 RW |
760 | rip = nb_running_get_entry(args->dnode, NULL, true); |
761 | rip->garbage_time = yang_dnode_get_uint32(args->dnode, NULL); | |
f80ec39e RW |
762 | |
763 | return NB_OK; | |
764 | } | |
765 | ||
766 | /* | |
767 | * XPath: /frr-ripd:ripd/instance/timers/holddown-interval | |
768 | */ | |
60ee8be1 RW |
769 | int ripd_instance_timers_holddown_interval_modify( |
770 | struct nb_cb_modify_args *args) | |
f80ec39e RW |
771 | { |
772 | struct rip *rip; | |
773 | ||
60ee8be1 | 774 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
775 | return NB_OK; |
776 | ||
60ee8be1 RW |
777 | rip = nb_running_get_entry(args->dnode, NULL, true); |
778 | rip->timeout_time = yang_dnode_get_uint32(args->dnode, NULL); | |
f80ec39e RW |
779 | |
780 | return NB_OK; | |
781 | } | |
782 | ||
783 | /* | |
784 | * XPath: /frr-ripd:ripd/instance/timers/update-interval | |
785 | */ | |
60ee8be1 | 786 | int ripd_instance_timers_update_interval_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
787 | { |
788 | struct rip *rip; | |
789 | ||
60ee8be1 | 790 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
791 | return NB_OK; |
792 | ||
60ee8be1 RW |
793 | rip = nb_running_get_entry(args->dnode, NULL, true); |
794 | rip->update_time = yang_dnode_get_uint32(args->dnode, NULL); | |
f80ec39e RW |
795 | |
796 | return NB_OK; | |
797 | } | |
798 | ||
799 | /* | |
800 | * XPath: /frr-ripd:ripd/instance/version/receive | |
801 | */ | |
60ee8be1 | 802 | int ripd_instance_version_receive_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
803 | { |
804 | struct rip *rip; | |
805 | ||
60ee8be1 | 806 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
807 | return NB_OK; |
808 | ||
60ee8be1 RW |
809 | rip = nb_running_get_entry(args->dnode, NULL, true); |
810 | rip->version_recv = yang_dnode_get_enum(args->dnode, NULL); | |
f80ec39e RW |
811 | |
812 | return NB_OK; | |
813 | } | |
814 | ||
815 | /* | |
816 | * XPath: /frr-ripd:ripd/instance/version/send | |
817 | */ | |
60ee8be1 | 818 | int ripd_instance_version_send_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
819 | { |
820 | struct rip *rip; | |
821 | ||
60ee8be1 | 822 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
823 | return NB_OK; |
824 | ||
60ee8be1 RW |
825 | rip = nb_running_get_entry(args->dnode, NULL, true); |
826 | rip->version_send = yang_dnode_get_enum(args->dnode, NULL); | |
f80ec39e RW |
827 | |
828 | return NB_OK; | |
829 | } | |
830 | ||
831 | /* | |
832 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon | |
833 | */ | |
60ee8be1 | 834 | int lib_interface_rip_split_horizon_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
835 | { |
836 | struct interface *ifp; | |
837 | struct rip_interface *ri; | |
838 | ||
60ee8be1 | 839 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
840 | return NB_OK; |
841 | ||
60ee8be1 | 842 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e | 843 | ri = ifp->info; |
60ee8be1 | 844 | ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL); |
f80ec39e RW |
845 | |
846 | return NB_OK; | |
847 | } | |
848 | ||
849 | /* | |
850 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast | |
851 | */ | |
60ee8be1 | 852 | int lib_interface_rip_v2_broadcast_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
853 | { |
854 | struct interface *ifp; | |
855 | struct rip_interface *ri; | |
856 | ||
60ee8be1 | 857 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
858 | return NB_OK; |
859 | ||
60ee8be1 | 860 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e | 861 | ri = ifp->info; |
60ee8be1 | 862 | ri->v2_broadcast = yang_dnode_get_bool(args->dnode, NULL); |
f80ec39e RW |
863 | |
864 | return NB_OK; | |
865 | } | |
866 | ||
867 | /* | |
868 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive | |
869 | */ | |
60ee8be1 | 870 | int lib_interface_rip_version_receive_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
871 | { |
872 | struct interface *ifp; | |
873 | struct rip_interface *ri; | |
874 | ||
60ee8be1 | 875 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
876 | return NB_OK; |
877 | ||
60ee8be1 | 878 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e | 879 | ri = ifp->info; |
60ee8be1 | 880 | ri->ri_receive = yang_dnode_get_enum(args->dnode, NULL); |
f80ec39e RW |
881 | |
882 | return NB_OK; | |
883 | } | |
884 | ||
885 | /* | |
886 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send | |
887 | */ | |
60ee8be1 | 888 | int lib_interface_rip_version_send_modify(struct nb_cb_modify_args *args) |
f80ec39e RW |
889 | { |
890 | struct interface *ifp; | |
891 | struct rip_interface *ri; | |
892 | ||
60ee8be1 | 893 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
894 | return NB_OK; |
895 | ||
60ee8be1 | 896 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e | 897 | ri = ifp->info; |
60ee8be1 | 898 | ri->ri_send = yang_dnode_get_enum(args->dnode, NULL); |
f80ec39e RW |
899 | |
900 | return NB_OK; | |
901 | } | |
902 | ||
903 | /* | |
904 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode | |
905 | */ | |
906 | int lib_interface_rip_authentication_scheme_mode_modify( | |
60ee8be1 | 907 | struct nb_cb_modify_args *args) |
f80ec39e RW |
908 | { |
909 | struct interface *ifp; | |
910 | struct rip_interface *ri; | |
911 | ||
60ee8be1 | 912 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
913 | return NB_OK; |
914 | ||
60ee8be1 | 915 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e | 916 | ri = ifp->info; |
60ee8be1 | 917 | ri->auth_type = yang_dnode_get_enum(args->dnode, NULL); |
f80ec39e RW |
918 | |
919 | return NB_OK; | |
920 | } | |
921 | ||
922 | /* | |
923 | * XPath: | |
924 | * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length | |
925 | */ | |
926 | int lib_interface_rip_authentication_scheme_md5_auth_length_modify( | |
60ee8be1 | 927 | struct nb_cb_modify_args *args) |
f80ec39e RW |
928 | { |
929 | struct interface *ifp; | |
930 | struct rip_interface *ri; | |
931 | ||
60ee8be1 | 932 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
933 | return NB_OK; |
934 | ||
60ee8be1 | 935 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e | 936 | ri = ifp->info; |
60ee8be1 | 937 | ri->md5_auth_len = yang_dnode_get_enum(args->dnode, NULL); |
f80ec39e RW |
938 | |
939 | return NB_OK; | |
940 | } | |
941 | ||
942 | int lib_interface_rip_authentication_scheme_md5_auth_length_destroy( | |
60ee8be1 | 943 | struct nb_cb_destroy_args *args) |
f80ec39e RW |
944 | { |
945 | struct interface *ifp; | |
946 | struct rip_interface *ri; | |
947 | ||
60ee8be1 | 948 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
949 | return NB_OK; |
950 | ||
60ee8be1 | 951 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
952 | ri = ifp->info; |
953 | ri->md5_auth_len = yang_get_default_enum( | |
954 | "%s/authentication-scheme/md5-auth-length", RIP_IFACE); | |
955 | ||
956 | return NB_OK; | |
957 | } | |
958 | ||
959 | /* | |
960 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password | |
961 | */ | |
962 | int lib_interface_rip_authentication_password_modify( | |
60ee8be1 | 963 | struct nb_cb_modify_args *args) |
f80ec39e RW |
964 | { |
965 | struct interface *ifp; | |
966 | struct rip_interface *ri; | |
967 | ||
60ee8be1 | 968 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
969 | return NB_OK; |
970 | ||
60ee8be1 | 971 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
972 | ri = ifp->info; |
973 | XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); | |
974 | ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING, | |
60ee8be1 | 975 | yang_dnode_get_string(args->dnode, NULL)); |
f80ec39e RW |
976 | |
977 | return NB_OK; | |
978 | } | |
979 | ||
980 | int lib_interface_rip_authentication_password_destroy( | |
60ee8be1 | 981 | struct nb_cb_destroy_args *args) |
f80ec39e RW |
982 | { |
983 | struct interface *ifp; | |
984 | struct rip_interface *ri; | |
985 | ||
60ee8be1 | 986 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
987 | return NB_OK; |
988 | ||
60ee8be1 | 989 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
990 | ri = ifp->info; |
991 | XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); | |
992 | ||
993 | return NB_OK; | |
994 | } | |
995 | ||
996 | /* | |
997 | * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain | |
998 | */ | |
999 | int lib_interface_rip_authentication_key_chain_modify( | |
60ee8be1 | 1000 | struct nb_cb_modify_args *args) |
f80ec39e RW |
1001 | { |
1002 | struct interface *ifp; | |
1003 | struct rip_interface *ri; | |
1004 | ||
60ee8be1 | 1005 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
1006 | return NB_OK; |
1007 | ||
60ee8be1 | 1008 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
1009 | ri = ifp->info; |
1010 | XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); | |
1011 | ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING, | |
60ee8be1 | 1012 | yang_dnode_get_string(args->dnode, NULL)); |
f80ec39e RW |
1013 | |
1014 | return NB_OK; | |
1015 | } | |
1016 | ||
1017 | int lib_interface_rip_authentication_key_chain_destroy( | |
60ee8be1 | 1018 | struct nb_cb_destroy_args *args) |
f80ec39e RW |
1019 | { |
1020 | struct interface *ifp; | |
1021 | struct rip_interface *ri; | |
1022 | ||
60ee8be1 | 1023 | if (args->event != NB_EV_APPLY) |
f80ec39e RW |
1024 | return NB_OK; |
1025 | ||
60ee8be1 | 1026 | ifp = nb_running_get_entry(args->dnode, NULL, true); |
f80ec39e RW |
1027 | ri = ifp->info; |
1028 | XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); | |
1029 | ||
1030 | return NB_OK; | |
1031 | } |