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