1 /*
2 * FRR filter northbound implementation.
3 *
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
5 * Rafael Zalamena
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23 #include "zebra.h"
24
25 #include "lib/northbound.h"
26 #include "lib/prefix.h"
27 #include "lib/printfrr.h"
28
29 #include "lib/filter.h"
30 #include "lib/plist.h"
31 #include "lib/plist_int.h"
32 #include "lib/routemap.h"
33
34 /* Helper function. */
acl_notify_route_map(struct access_list * acl,int route_map_event)35 static void acl_notify_route_map(struct access_list *acl, int route_map_event)
36 {
37 switch (route_map_event) {
38 case RMAP_EVENT_FILTER_ADDED:
39 if (acl->master->add_hook)
40 (*acl->master->add_hook)(acl);
41 break;
42 case RMAP_EVENT_FILTER_DELETED:
43 if (acl->master->delete_hook)
44 (*acl->master->delete_hook)(acl);
45 break;
46 }
47
48 route_map_notify_dependencies(acl->name, route_map_event);
49 }
50
prefix_list_length_validate(struct nb_cb_modify_args * args)51 static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args)
52 {
53 int type = yang_dnode_get_enum(args->dnode, "../../type");
54 const char *xpath_le = NULL, *xpath_ge = NULL;
55 struct prefix p;
56 uint8_t le, ge;
57
58 if (type == YPLT_IPV4) {
59 yang_dnode_get_prefix(&p, args->dnode, "../ipv4-prefix");
60 xpath_le = "../ipv4-prefix-length-lesser-or-equal";
61 xpath_ge = "../ipv4-prefix-length-greater-or-equal";
62 } else {
63 yang_dnode_get_prefix(&p, args->dnode, "../ipv6-prefix");
64 xpath_le = "../ipv6-prefix-length-lesser-or-equal";
65 xpath_ge = "../ipv6-prefix-length-greater-or-equal";
66 }
67
68 /*
69 * Check rule:
70 * prefix length <= le.
71 */
72 if (yang_dnode_exists(args->dnode, xpath_le)) {
73 le = yang_dnode_get_uint8(args->dnode, xpath_le);
74 if (p.prefixlen > le)
75 goto log_and_fail;
76 }
77
78 /*
79 * Check rule:
80 * prefix length <= ge.
81 */
82 if (yang_dnode_exists(args->dnode, xpath_ge)) {
83 ge = yang_dnode_get_uint8(args->dnode, xpath_ge);
84 if (p.prefixlen > ge)
85 goto log_and_fail;
86 }
87
88 /*
89 * Check rule:
90 * ge <= le.
91 */
92 if (yang_dnode_exists(args->dnode, xpath_le)
93 && yang_dnode_exists(args->dnode, xpath_ge)) {
94 le = yang_dnode_get_uint8(args->dnode, xpath_le);
95 ge = yang_dnode_get_uint8(args->dnode, xpath_ge);
96 if (ge > le)
97 goto log_and_fail;
98 }
99
100 return NB_OK;
101
102 log_and_fail:
103 snprintfrr(
104 args->errmsg, args->errmsg_len,
105 "Invalid prefix range for %pFX: Make sure that mask length <= ge <= le",
106 &p);
107 return NB_ERR_VALIDATION;
108 }
109
110 /**
111 * Sets prefix list entry to blank value.
112 *
113 * \param[out] ple prefix list entry to modify.
114 */
prefix_list_entry_set_empty(struct prefix_list_entry * ple)115 static void prefix_list_entry_set_empty(struct prefix_list_entry *ple)
116 {
117 ple->any = false;
118 memset(&ple->prefix, 0, sizeof(ple->prefix));
119 ple->ge = 0;
120 ple->le = 0;
121 }
122
123 /**
124 * Unsets the cisco style rule for addresses so it becomes disabled (the
125 * equivalent of setting: `0.0.0.0/32`).
126 *
127 * \param addr address part.
128 * \param mask mask part.
129 */
cisco_unset_addr_mask(struct in_addr * addr,struct in_addr * mask)130 static void cisco_unset_addr_mask(struct in_addr *addr, struct in_addr *mask)
131 {
132 addr->s_addr = INADDR_ANY;
133 mask->s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
134 }
135
_acl_is_dup(const struct lyd_node * dnode,void * arg)136 static int _acl_is_dup(const struct lyd_node *dnode, void *arg)
137 {
138 struct acl_dup_args *ada = arg;
139 int idx;
140
141 /* This entry is the caller, so skip it. */
142 if (ada->ada_entry_dnode
143 && ada->ada_entry_dnode == dnode)
144 return YANG_ITER_CONTINUE;
145
146 /* Check if all values match. */
147 for (idx = 0; idx < ADA_MAX_VALUES; idx++) {
148 /* No more values. */
149 if (ada->ada_xpath[idx] == NULL)
150 break;
151
152 /* Not same type, just skip it. */
153 if (!yang_dnode_exists(dnode, ada->ada_xpath[idx]))
154 return YANG_ITER_CONTINUE;
155
156 /* Check if different value. */
157 if (strcmp(yang_dnode_get_string(dnode, ada->ada_xpath[idx]),
158 ada->ada_value[idx]))
159 return YANG_ITER_CONTINUE;
160 }
161
162 ada->ada_found = true;
163
164 return YANG_ITER_STOP;
165 }
166
acl_is_dup(const struct lyd_node * dnode,struct acl_dup_args * ada)167 bool acl_is_dup(const struct lyd_node *dnode, struct acl_dup_args *ada)
168 {
169 ada->ada_found = false;
170
171 yang_dnode_iterate(
172 _acl_is_dup, ada, dnode,
173 "/frr-filter:lib/access-list[type='%s'][name='%s']/entry",
174 ada->ada_type, ada->ada_name);
175
176 return ada->ada_found;
177 }
178
acl_cisco_is_dup(const struct lyd_node * dnode)179 static bool acl_cisco_is_dup(const struct lyd_node *dnode)
180 {
181 const struct lyd_node *entry_dnode =
182 yang_dnode_get_parent(dnode, "entry");
183 struct acl_dup_args ada = {};
184 int idx = 0, arg_idx = 0;
185 static const char *cisco_entries[] = {
186 "./host",
187 "./network/address",
188 "./network/mask",
189 "./source-any",
190 "./destination-host",
191 "./destination-network/address",
192 "./destination-network/mask",
193 "./destination-any",
194 NULL
195 };
196
197 /* Initialize. */
198 ada.ada_type = "ipv4";
199 ada.ada_name = yang_dnode_get_string(entry_dnode, "../name");
200 ada.ada_entry_dnode = entry_dnode;
201
202 /* Load all values/XPaths. */
203 while (cisco_entries[idx] != NULL) {
204 if (!yang_dnode_exists(entry_dnode, cisco_entries[idx])) {
205 idx++;
206 continue;
207 }
208
209 ada.ada_xpath[arg_idx] = cisco_entries[idx];
210 ada.ada_value[arg_idx] =
211 yang_dnode_get_string(entry_dnode, cisco_entries[idx]);
212 arg_idx++;
213 idx++;
214 }
215
216 return acl_is_dup(entry_dnode, &ada);
217 }
218
acl_zebra_is_dup(const struct lyd_node * dnode,enum yang_access_list_type type)219 static bool acl_zebra_is_dup(const struct lyd_node *dnode,
220 enum yang_access_list_type type)
221 {
222 const struct lyd_node *entry_dnode =
223 yang_dnode_get_parent(dnode, "entry");
224 struct acl_dup_args ada = {};
225 int idx = 0, arg_idx = 0;
226 static const char *zebra_entries[] = {
227 "./ipv4-prefix",
228 "./ipv4-exact-match",
229 "./ipv6-prefix",
230 "./ipv6-exact-match",
231 "./mac",
232 "./any",
233 NULL
234 };
235
236 /* Initialize. */
237 switch (type) {
238 case YALT_IPV4:
239 ada.ada_type = "ipv4";
240 break;
241 case YALT_IPV6:
242 ada.ada_type = "ipv6";
243 break;
244 case YALT_MAC:
245 ada.ada_type = "mac";
246 break;
247 }
248 ada.ada_name = yang_dnode_get_string(entry_dnode, "../name");
249 ada.ada_entry_dnode = entry_dnode;
250
251 /* Load all values/XPaths. */
252 while (zebra_entries[idx] != NULL) {
253 if (!yang_dnode_exists(entry_dnode, zebra_entries[idx])) {
254 idx++;
255 continue;
256 }
257
258 ada.ada_xpath[arg_idx] = zebra_entries[idx];
259 ada.ada_value[arg_idx] =
260 yang_dnode_get_string(entry_dnode, zebra_entries[idx]);
261 arg_idx++;
262 idx++;
263 }
264
265 return acl_is_dup(entry_dnode, &ada);
266 }
267
_plist_is_dup(const struct lyd_node * dnode,void * arg)268 static int _plist_is_dup(const struct lyd_node *dnode, void *arg)
269 {
270 struct plist_dup_args *pda = arg;
271 int idx;
272
273 /* This entry is the caller, so skip it. */
274 if (pda->pda_entry_dnode
275 && pda->pda_entry_dnode == dnode)
276 return YANG_ITER_CONTINUE;
277
278 /* Check if all values match. */
279 for (idx = 0; idx < PDA_MAX_VALUES; idx++) {
280 /* No more values. */
281 if (pda->pda_xpath[idx] == NULL)
282 break;
283
284 /* Not same type, just skip it. */
285 if (!yang_dnode_exists(dnode, pda->pda_xpath[idx]))
286 return YANG_ITER_CONTINUE;
287
288 /* Check if different value. */
289 if (strcmp(yang_dnode_get_string(dnode, pda->pda_xpath[idx]),
290 pda->pda_value[idx]))
291 return YANG_ITER_CONTINUE;
292 }
293
294 pda->pda_found = true;
295
296 return YANG_ITER_STOP;
297 }
298
plist_is_dup(const struct lyd_node * dnode,struct plist_dup_args * pda)299 bool plist_is_dup(const struct lyd_node *dnode, struct plist_dup_args *pda)
300 {
301 pda->pda_found = false;
302
303 yang_dnode_iterate(
304 _plist_is_dup, pda, dnode,
305 "/frr-filter:lib/prefix-list[type='%s'][name='%s']/entry",
306 pda->pda_type, pda->pda_name);
307
308 return pda->pda_found;
309 }
310
plist_is_dup_nb(const struct lyd_node * dnode)311 static bool plist_is_dup_nb(const struct lyd_node *dnode)
312 {
313 const struct lyd_node *entry_dnode =
314 yang_dnode_get_parent(dnode, "entry");
315 struct plist_dup_args pda = {};
316 int idx = 0, arg_idx = 0;
317 static const char *entries[] = {
318 "./ipv4-prefix",
319 "./ipv4-prefix-length-greater-or-equal",
320 "./ipv4-prefix-length-lesser-or-equal",
321 "./ipv6-prefix",
322 "./ipv6-prefix-length-greater-or-equal",
323 "./ipv6-prefix-length-lesser-or-equal",
324 "./any",
325 NULL
326 };
327
328 /* Initialize. */
329 pda.pda_type = yang_dnode_get_string(entry_dnode, "../type");
330 pda.pda_name = yang_dnode_get_string(entry_dnode, "../name");
331 pda.pda_entry_dnode = entry_dnode;
332
333 /* Load all values/XPaths. */
334 while (entries[idx] != NULL) {
335 if (!yang_dnode_exists(entry_dnode, entries[idx])) {
336 idx++;
337 continue;
338 }
339
340 pda.pda_xpath[arg_idx] = entries[idx];
341 pda.pda_value[arg_idx] =
342 yang_dnode_get_string(entry_dnode, entries[idx]);
343 arg_idx++;
344 idx++;
345 }
346
347 return plist_is_dup(entry_dnode, &pda);
348 }
349
350 /*
351 * XPath: /frr-filter:lib/access-list
352 */
lib_access_list_create(struct nb_cb_create_args * args)353 static int lib_access_list_create(struct nb_cb_create_args *args)
354 {
355 struct access_list *acl = NULL;
356 const char *acl_name;
357 int type;
358
359 if (args->event != NB_EV_APPLY)
360 return NB_OK;
361
362 type = yang_dnode_get_enum(args->dnode, "./type");
363 acl_name = yang_dnode_get_string(args->dnode, "./name");
364
365 switch (type) {
366 case YALT_IPV4:
367 acl = access_list_get(AFI_IP, acl_name);
368 break;
369 case YALT_IPV6:
370 acl = access_list_get(AFI_IP6, acl_name);
371 break;
372 case YALT_MAC:
373 acl = access_list_get(AFI_L2VPN, acl_name);
374 break;
375 }
376
377 nb_running_set_entry(args->dnode, acl);
378
379 return NB_OK;
380 }
381
lib_access_list_destroy(struct nb_cb_destroy_args * args)382 static int lib_access_list_destroy(struct nb_cb_destroy_args *args)
383 {
384 struct access_master *am;
385 struct access_list *acl;
386
387 if (args->event != NB_EV_APPLY)
388 return NB_OK;
389
390 acl = nb_running_unset_entry(args->dnode);
391 am = acl->master;
392 if (am->delete_hook)
393 am->delete_hook(acl);
394
395 access_list_delete(acl);
396
397 return NB_OK;
398 }
399
400 /*
401 * XPath: /frr-filter:lib/access-list/remark
402 */
lib_access_list_remark_modify(struct nb_cb_modify_args * args)403 static int lib_access_list_remark_modify(struct nb_cb_modify_args *args)
404 {
405 struct access_list *acl;
406 const char *remark;
407
408 if (args->event != NB_EV_APPLY)
409 return NB_OK;
410
411 acl = nb_running_get_entry(args->dnode, NULL, true);
412 if (acl->remark)
413 XFREE(MTYPE_TMP, acl->remark);
414
415 remark = yang_dnode_get_string(args->dnode, NULL);
416 acl->remark = XSTRDUP(MTYPE_TMP, remark);
417
418 return NB_OK;
419 }
420
421 static int
lib_access_list_remark_destroy(struct nb_cb_destroy_args * args)422 lib_access_list_remark_destroy(struct nb_cb_destroy_args *args)
423 {
424 struct access_list *acl;
425
426 if (args->event != NB_EV_APPLY)
427 return NB_OK;
428
429 acl = nb_running_get_entry(args->dnode, NULL, true);
430 if (acl->remark)
431 XFREE(MTYPE_TMP, acl->remark);
432
433 return NB_OK;
434 }
435
436
437 /*
438 * XPath: /frr-filter:lib/access-list/entry
439 */
lib_access_list_entry_create(struct nb_cb_create_args * args)440 static int lib_access_list_entry_create(struct nb_cb_create_args *args)
441 {
442 struct access_list *acl;
443 struct filter *f;
444
445 if (args->event != NB_EV_APPLY)
446 return NB_OK;
447
448 f = filter_new();
449 f->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
450
451 acl = nb_running_get_entry(args->dnode, NULL, true);
452 f->acl = acl;
453 access_list_filter_add(acl, f);
454 nb_running_set_entry(args->dnode, f);
455
456 return NB_OK;
457 }
458
lib_access_list_entry_destroy(struct nb_cb_destroy_args * args)459 static int lib_access_list_entry_destroy(struct nb_cb_destroy_args *args)
460 {
461 struct access_list *acl;
462 struct filter *f;
463
464 if (args->event != NB_EV_APPLY)
465 return NB_OK;
466
467 f = nb_running_unset_entry(args->dnode);
468 acl = f->acl;
469 access_list_filter_delete(acl, f);
470
471 return NB_OK;
472 }
473
474 /*
475 * XPath: /frr-filter:lib/access-list/entry/action
476 */
477 static int
lib_access_list_entry_action_modify(struct nb_cb_modify_args * args)478 lib_access_list_entry_action_modify(struct nb_cb_modify_args *args)
479 {
480 const char *filter_type;
481 struct filter *f;
482
483 if (args->event != NB_EV_APPLY)
484 return NB_OK;
485
486 f = nb_running_get_entry(args->dnode, NULL, true);
487 filter_type = yang_dnode_get_string(args->dnode, NULL);
488 if (strcmp(filter_type, "permit") == 0)
489 f->type = FILTER_PERMIT;
490 else
491 f->type = FILTER_DENY;
492
493 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
494
495 return NB_OK;
496 }
497
498 /*
499 * XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
500 */
501 static int
lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args * args)502 lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
503 {
504 struct filter_zebra *fz;
505 struct filter *f;
506
507 /* Don't allow duplicated values. */
508 if (args->event == NB_EV_VALIDATE) {
509 if (acl_zebra_is_dup(
510 args->dnode,
511 yang_dnode_get_enum(args->dnode, "../../type"))) {
512 snprintfrr(args->errmsg, args->errmsg_len,
513 "duplicated access list value: %s",
514 yang_dnode_get_string(args->dnode, NULL));
515 return NB_ERR_VALIDATION;
516 }
517 return NB_OK;
518 }
519
520 if (args->event != NB_EV_APPLY)
521 return NB_OK;
522
523 f = nb_running_get_entry(args->dnode, NULL, true);
524 f->cisco = 0;
525 fz = &f->u.zfilter;
526 yang_dnode_get_prefix(&fz->prefix, args->dnode, NULL);
527
528 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
529
530 return NB_OK;
531 }
532
533 static int
lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args * args)534 lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
535 {
536 struct filter_zebra *fz;
537 struct filter *f;
538
539 if (args->event != NB_EV_APPLY)
540 return NB_OK;
541
542 f = nb_running_get_entry(args->dnode, NULL, true);
543 fz = &f->u.zfilter;
544 memset(&fz->prefix, 0, sizeof(fz->prefix));
545
546 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
547
548 return NB_OK;
549 }
550
551 /*
552 * XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
553 */
554 static int
lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args * args)555 lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args *args)
556 {
557 struct filter_zebra *fz;
558 struct filter *f;
559
560 /* Don't allow duplicated values. */
561 if (args->event == NB_EV_VALIDATE) {
562 if (acl_zebra_is_dup(
563 args->dnode,
564 yang_dnode_get_enum(args->dnode, "../../type"))) {
565 snprintfrr(args->errmsg, args->errmsg_len,
566 "duplicated access list value: %s",
567 yang_dnode_get_string(args->dnode, NULL));
568 return NB_ERR_VALIDATION;
569 }
570 return NB_OK;
571 }
572
573 if (args->event != NB_EV_APPLY)
574 return NB_OK;
575
576 f = nb_running_get_entry(args->dnode, NULL, true);
577 fz = &f->u.zfilter;
578 fz->exact = yang_dnode_get_bool(args->dnode, NULL);
579
580 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
581
582 return NB_OK;
583 }
584
585 static int
lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args * args)586 lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args *args)
587 {
588 struct filter_zebra *fz;
589 struct filter *f;
590
591 if (args->event != NB_EV_APPLY)
592 return NB_OK;
593
594 f = nb_running_get_entry(args->dnode, NULL, true);
595 fz = &f->u.zfilter;
596 fz->exact = 0;
597
598 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
599
600 return NB_OK;
601 }
602
603 /*
604 * XPath: /frr-filter:lib/access-list/entry/host
605 */
606 static int
lib_access_list_entry_host_modify(struct nb_cb_modify_args * args)607 lib_access_list_entry_host_modify(struct nb_cb_modify_args *args)
608 {
609 struct filter_cisco *fc;
610 struct filter *f;
611
612 /* Don't allow duplicated values. */
613 if (args->event == NB_EV_VALIDATE) {
614 if (acl_cisco_is_dup(args->dnode)) {
615 snprintfrr(args->errmsg, args->errmsg_len,
616 "duplicated access list value: %s",
617 yang_dnode_get_string(args->dnode, NULL));
618 return NB_ERR_VALIDATION;
619 }
620 return NB_OK;
621 }
622
623 if (args->event != NB_EV_APPLY)
624 return NB_OK;
625
626 f = nb_running_get_entry(args->dnode, NULL, true);
627 f->cisco = 1;
628 fc = &f->u.cfilter;
629 yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
630 fc->addr_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
631
632 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
633
634 return NB_OK;
635 }
636
637 static int
lib_access_list_entry_host_destroy(struct nb_cb_destroy_args * args)638 lib_access_list_entry_host_destroy(struct nb_cb_destroy_args *args)
639 {
640 struct filter_cisco *fc;
641 struct filter *f;
642
643 if (args->event != NB_EV_APPLY)
644 return NB_OK;
645
646 f = nb_running_get_entry(args->dnode, NULL, true);
647 fc = &f->u.cfilter;
648 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
649
650 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
651
652 return NB_OK;
653 }
654
655 /*
656 * XPath: /frr-filter:lib/access-list/entry/network/address
657 */
658 static int
lib_access_list_entry_network_address_modify(struct nb_cb_modify_args * args)659 lib_access_list_entry_network_address_modify(struct nb_cb_modify_args *args)
660 {
661 struct filter_cisco *fc;
662 struct filter *f;
663
664 /* Don't allow duplicated values. */
665 if (args->event == NB_EV_VALIDATE) {
666 if (acl_cisco_is_dup(args->dnode)) {
667 snprintfrr(args->errmsg, args->errmsg_len,
668 "duplicated access list value: %s",
669 yang_dnode_get_string(args->dnode, NULL));
670 return NB_ERR_VALIDATION;
671 }
672 return NB_OK;
673 }
674
675 if (args->event != NB_EV_APPLY)
676 return NB_OK;
677
678 f = nb_running_get_entry(args->dnode, NULL, true);
679 f->cisco = 1;
680 fc = &f->u.cfilter;
681 yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
682
683 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
684
685 return NB_OK;
686 }
687
688 /*
689 * XPath: /frr-filter:lib/access-list/entry/network/mask
690 */
691 static int
lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args * args)692 lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args *args)
693 {
694 struct filter_cisco *fc;
695 struct filter *f;
696
697 /* Don't allow duplicated values. */
698 if (args->event == NB_EV_VALIDATE) {
699 if (acl_cisco_is_dup(args->dnode)) {
700 snprintfrr(args->errmsg, args->errmsg_len,
701 "duplicated access list value: %s",
702 yang_dnode_get_string(args->dnode, NULL));
703 return NB_ERR_VALIDATION;
704 }
705 return NB_OK;
706 }
707
708 if (args->event != NB_EV_APPLY)
709 return NB_OK;
710
711 f = nb_running_get_entry(args->dnode, NULL, true);
712 f->cisco = 1;
713 fc = &f->u.cfilter;
714 yang_dnode_get_ipv4(&fc->addr_mask, args->dnode, NULL);
715
716 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
717
718 return NB_OK;
719 }
720
721 /*
722 * XPath: /frr-filter:lib/access-list/entry/source-any
723 */
724 static int
lib_access_list_entry_source_any_create(struct nb_cb_create_args * args)725 lib_access_list_entry_source_any_create(struct nb_cb_create_args *args)
726 {
727 struct filter_cisco *fc;
728 struct filter *f;
729
730 /* Don't allow duplicated values. */
731 if (args->event == NB_EV_VALIDATE) {
732 if (acl_cisco_is_dup(args->dnode)) {
733 snprintfrr(args->errmsg, args->errmsg_len,
734 "duplicated access list value: %s",
735 yang_dnode_get_string(args->dnode, NULL));
736 return NB_ERR_VALIDATION;
737 }
738 return NB_OK;
739 }
740
741 if (args->event != NB_EV_APPLY)
742 return NB_OK;
743
744 f = nb_running_get_entry(args->dnode, NULL, true);
745 f->cisco = 1;
746 fc = &f->u.cfilter;
747 fc->addr.s_addr = INADDR_ANY;
748 fc->addr_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
749
750 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
751
752 return NB_OK;
753 }
754
755 static int
lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args * args)756 lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args *args)
757 {
758 struct filter_cisco *fc;
759 struct filter *f;
760
761 if (args->event != NB_EV_APPLY)
762 return NB_OK;
763
764 f = nb_running_get_entry(args->dnode, NULL, true);
765 fc = &f->u.cfilter;
766 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
767
768 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
769
770 return NB_OK;
771 }
772
773 /*
774 * XPath: /frr-filter:lib/access-list/entry/destination-host
775 */
lib_access_list_entry_destination_host_modify(struct nb_cb_modify_args * args)776 static int lib_access_list_entry_destination_host_modify(
777 struct nb_cb_modify_args *args)
778 {
779 struct filter_cisco *fc;
780 struct filter *f;
781
782 /* Don't allow duplicated values. */
783 if (args->event == NB_EV_VALIDATE) {
784 if (acl_cisco_is_dup(args->dnode)) {
785 snprintfrr(args->errmsg, args->errmsg_len,
786 "duplicated access list value: %s",
787 yang_dnode_get_string(args->dnode, NULL));
788 return NB_ERR_VALIDATION;
789 }
790 return NB_OK;
791 }
792
793 if (args->event != NB_EV_APPLY)
794 return NB_OK;
795
796 f = nb_running_get_entry(args->dnode, NULL, true);
797 fc = &f->u.cfilter;
798 fc->extended = 1;
799 yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
800 fc->mask_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
801
802 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
803
804 return NB_OK;
805 }
806
lib_access_list_entry_destination_host_destroy(struct nb_cb_destroy_args * args)807 static int lib_access_list_entry_destination_host_destroy(
808 struct nb_cb_destroy_args *args)
809 {
810 struct filter_cisco *fc;
811 struct filter *f;
812
813 if (args->event != NB_EV_APPLY)
814 return NB_OK;
815
816 f = nb_running_get_entry(args->dnode, NULL, true);
817 fc = &f->u.cfilter;
818 fc->extended = 0;
819 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
820
821 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
822
823 return NB_OK;
824 }
825
826 /*
827 * XPath: /frr-filter:lib/access-list/entry/destination-network/address
828 */
lib_access_list_entry_destination_network_address_modify(struct nb_cb_modify_args * args)829 static int lib_access_list_entry_destination_network_address_modify(
830 struct nb_cb_modify_args *args)
831 {
832 struct filter_cisco *fc;
833 struct filter *f;
834
835 /* Don't allow duplicated values. */
836 if (args->event == NB_EV_VALIDATE) {
837 if (acl_cisco_is_dup(args->dnode)) {
838 snprintfrr(args->errmsg, args->errmsg_len,
839 "duplicated access list value: %s",
840 yang_dnode_get_string(args->dnode, NULL));
841 return NB_ERR_VALIDATION;
842 }
843 return NB_OK;
844 }
845
846 if (args->event != NB_EV_APPLY)
847 return NB_OK;
848
849 f = nb_running_get_entry(args->dnode, NULL, true);
850 fc = &f->u.cfilter;
851 fc->extended = 1;
852 yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
853
854 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
855
856 return NB_OK;
857 }
858
859 /*
860 * XPath: /frr-filter:lib/access-list/entry/destination-network/mask
861 */
lib_access_list_entry_destination_network_mask_modify(struct nb_cb_modify_args * args)862 static int lib_access_list_entry_destination_network_mask_modify(
863 struct nb_cb_modify_args *args)
864 {
865 struct filter_cisco *fc;
866 struct filter *f;
867
868 /* Don't allow duplicated values. */
869 if (args->event == NB_EV_VALIDATE) {
870 if (acl_cisco_is_dup(args->dnode)) {
871 snprintfrr(args->errmsg, args->errmsg_len,
872 "duplicated access list value: %s",
873 yang_dnode_get_string(args->dnode, NULL));
874 return NB_ERR_VALIDATION;
875 }
876 return NB_OK;
877 }
878
879 if (args->event != NB_EV_APPLY)
880 return NB_OK;
881
882 f = nb_running_get_entry(args->dnode, NULL, true);
883 fc = &f->u.cfilter;
884 fc->extended = 1;
885 yang_dnode_get_ipv4(&fc->mask_mask, args->dnode, NULL);
886
887 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
888
889 return NB_OK;
890 }
891
892 /*
893 * XPath: /frr-filter:lib/access-list/entry/destination-any
894 */
lib_access_list_entry_destination_any_create(struct nb_cb_create_args * args)895 static int lib_access_list_entry_destination_any_create(
896 struct nb_cb_create_args *args)
897 {
898 struct filter_cisco *fc;
899 struct filter *f;
900
901 /* Don't allow duplicated values. */
902 if (args->event == NB_EV_VALIDATE) {
903 if (acl_cisco_is_dup(args->dnode)) {
904 snprintfrr(args->errmsg, args->errmsg_len,
905 "duplicated access list value: %s",
906 yang_dnode_get_string(args->dnode, NULL));
907 return NB_ERR_VALIDATION;
908 }
909 return NB_OK;
910 }
911
912 if (args->event != NB_EV_APPLY)
913 return NB_OK;
914
915 f = nb_running_get_entry(args->dnode, NULL, true);
916 fc = &f->u.cfilter;
917 fc->extended = 1;
918 fc->mask.s_addr = INADDR_ANY;
919 fc->mask_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
920
921 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
922
923 return NB_OK;
924 }
925
lib_access_list_entry_destination_any_destroy(struct nb_cb_destroy_args * args)926 static int lib_access_list_entry_destination_any_destroy(
927 struct nb_cb_destroy_args *args)
928 {
929 struct filter_cisco *fc;
930 struct filter *f;
931
932 if (args->event != NB_EV_APPLY)
933 return NB_OK;
934
935 f = nb_running_get_entry(args->dnode, NULL, true);
936 fc = &f->u.cfilter;
937 fc->extended = 0;
938 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
939
940 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
941
942 return NB_OK;
943 }
944
945 /*
946 * XPath: /frr-filter:lib/access-list/entry/any
947 */
lib_access_list_entry_any_create(struct nb_cb_create_args * args)948 static int lib_access_list_entry_any_create(struct nb_cb_create_args *args)
949 {
950 struct filter_zebra *fz;
951 struct filter *f;
952 int type;
953
954 /* Don't allow duplicated values. */
955 if (args->event == NB_EV_VALIDATE) {
956 if (acl_zebra_is_dup(
957 args->dnode,
958 yang_dnode_get_enum(args->dnode, "../../type"))) {
959 snprintfrr(args->errmsg, args->errmsg_len,
960 "duplicated access list value: %s",
961 yang_dnode_get_string(args->dnode, NULL));
962 return NB_ERR_VALIDATION;
963 }
964 return NB_OK;
965 }
966
967 if (args->event != NB_EV_APPLY)
968 return NB_OK;
969
970 f = nb_running_get_entry(args->dnode, NULL, true);
971 f->cisco = 0;
972 fz = &f->u.zfilter;
973 memset(&fz->prefix, 0, sizeof(fz->prefix));
974
975 type = yang_dnode_get_enum(args->dnode, "../../type");
976 switch (type) {
977 case YALT_IPV4:
978 fz->prefix.family = AF_INET;
979 break;
980 case YALT_IPV6:
981 fz->prefix.family = AF_INET6;
982 break;
983 case YALT_MAC:
984 fz->prefix.family = AF_ETHERNET;
985 break;
986 }
987
988 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
989
990 return NB_OK;
991 }
992
lib_access_list_entry_any_destroy(struct nb_cb_destroy_args * args)993 static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args *args)
994 {
995 struct filter_zebra *fz;
996 struct filter *f;
997
998 if (args->event != NB_EV_APPLY)
999 return NB_OK;
1000
1001 f = nb_running_get_entry(args->dnode, NULL, true);
1002 fz = &f->u.zfilter;
1003 fz->prefix.family = 0;
1004
1005 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
1006
1007 return NB_OK;
1008 }
1009
1010 /*
1011 * XPath: /frr-filter:lib/prefix-list
1012 */
lib_prefix_list_create(struct nb_cb_create_args * args)1013 static int lib_prefix_list_create(struct nb_cb_create_args *args)
1014 {
1015 struct prefix_list *pl = NULL;
1016 const char *name;
1017 int type;
1018
1019 if (args->event != NB_EV_APPLY)
1020 return NB_OK;
1021
1022 type = yang_dnode_get_enum(args->dnode, "./type");
1023 name = yang_dnode_get_string(args->dnode, "./name");
1024 switch (type) {
1025 case 0: /* ipv4 */
1026 pl = prefix_list_get(AFI_IP, 0, name);
1027 break;
1028 case 1: /* ipv6 */
1029 pl = prefix_list_get(AFI_IP6, 0, name);
1030 break;
1031 }
1032
1033 nb_running_set_entry(args->dnode, pl);
1034
1035 return NB_OK;
1036 }
1037
lib_prefix_list_destroy(struct nb_cb_destroy_args * args)1038 static int lib_prefix_list_destroy(struct nb_cb_destroy_args *args)
1039 {
1040 struct prefix_list *pl;
1041
1042 if (args->event != NB_EV_APPLY)
1043 return NB_OK;
1044
1045 pl = nb_running_unset_entry(args->dnode);
1046 prefix_list_delete(pl);
1047
1048 return NB_OK;
1049 }
1050
1051 /*
1052 * XPath: /frr-filter:lib/prefix-list/remark
1053 */
lib_prefix_list_remark_modify(struct nb_cb_modify_args * args)1054 static int lib_prefix_list_remark_modify(struct nb_cb_modify_args *args)
1055 {
1056 struct prefix_list *pl;
1057 const char *remark;
1058
1059 if (args->event != NB_EV_APPLY)
1060 return NB_OK;
1061
1062 pl = nb_running_get_entry(args->dnode, NULL, true);
1063 if (pl->desc)
1064 XFREE(MTYPE_TMP, pl->desc);
1065
1066 remark = yang_dnode_get_string(args->dnode, NULL);
1067 pl->desc = XSTRDUP(MTYPE_TMP, remark);
1068
1069 return NB_OK;
1070 }
1071
lib_prefix_list_remark_destroy(struct nb_cb_destroy_args * args)1072 static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args *args)
1073 {
1074 struct prefix_list *pl;
1075
1076 if (args->event != NB_EV_APPLY)
1077 return NB_OK;
1078
1079 pl = nb_running_get_entry(args->dnode, NULL, true);
1080 if (pl->desc)
1081 XFREE(MTYPE_TMP, pl->desc);
1082
1083 return NB_OK;
1084 }
1085
1086 /*
1087 * XPath: /frr-filter:lib/prefix-list/entry
1088 */
lib_prefix_list_entry_create(struct nb_cb_create_args * args)1089 static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
1090 {
1091 struct prefix_list_entry *ple;
1092 struct prefix_list *pl;
1093
1094 if (args->event != NB_EV_APPLY)
1095 return NB_OK;
1096
1097 pl = nb_running_get_entry(args->dnode, NULL, true);
1098 ple = prefix_list_entry_new();
1099 ple->pl = pl;
1100 ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
1101 prefix_list_entry_set_empty(ple);
1102 nb_running_set_entry(args->dnode, ple);
1103
1104 return NB_OK;
1105 }
1106
lib_prefix_list_entry_destroy(struct nb_cb_destroy_args * args)1107 static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
1108 {
1109 struct prefix_list_entry *ple;
1110
1111 if (args->event != NB_EV_APPLY)
1112 return NB_OK;
1113
1114 ple = nb_running_unset_entry(args->dnode);
1115 if (ple->installed)
1116 prefix_list_entry_delete2(ple);
1117 else
1118 prefix_list_entry_free(ple);
1119
1120 return NB_OK;
1121 }
1122
1123 /*
1124 * XPath: /frr-filter:lib/prefix-list/entry/action
1125 */
lib_prefix_list_entry_action_modify(struct nb_cb_modify_args * args)1126 static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
1127 {
1128 struct prefix_list_entry *ple;
1129 int action_type;
1130
1131 if (args->event != NB_EV_APPLY)
1132 return NB_OK;
1133
1134 ple = nb_running_get_entry(args->dnode, NULL, true);
1135
1136 /* Start prefix entry update procedure. */
1137 prefix_list_entry_update_start(ple);
1138
1139 action_type = yang_dnode_get_enum(args->dnode, NULL);
1140 if (action_type == YPLA_PERMIT)
1141 ple->type = PREFIX_PERMIT;
1142 else
1143 ple->type = PREFIX_DENY;
1144
1145 /* Finish prefix entry update procedure. */
1146 prefix_list_entry_update_finish(ple);
1147
1148 return NB_OK;
1149 }
1150
1151 /*
1152 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
1153 */
1154 static int
lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args * args)1155 lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
1156 {
1157 struct prefix_list_entry *ple;
1158 struct prefix p;
1159
1160 if (args->event == NB_EV_VALIDATE) {
1161 if (plist_is_dup_nb(args->dnode)) {
1162 snprintf(args->errmsg, args->errmsg_len,
1163 "duplicated prefix list value: %s",
1164 yang_dnode_get_string(args->dnode, NULL));
1165 return NB_ERR_VALIDATION;
1166 }
1167 return NB_OK;
1168 }
1169
1170 if (args->event != NB_EV_APPLY)
1171 return NB_OK;
1172
1173 ple = nb_running_get_entry(args->dnode, NULL, true);
1174
1175 /* Start prefix entry update procedure. */
1176 prefix_list_entry_update_start(ple);
1177
1178 yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
1179
1180 /* Apply mask and correct original address if necessary. */
1181 prefix_copy(&p, &ple->prefix);
1182 apply_mask(&p);
1183 if (!prefix_same(&ple->prefix, &p)) {
1184 zlog_info("%s: bad network %pFX correcting it to %pFX",
1185 __func__, &ple->prefix, &p);
1186 prefix_copy(&ple->prefix, &p);
1187 }
1188
1189
1190 /* Finish prefix entry update procedure. */
1191 prefix_list_entry_update_finish(ple);
1192
1193 return NB_OK;
1194 }
1195
1196 static int
lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args * args)1197 lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
1198 {
1199 struct prefix_list_entry *ple;
1200
1201 if (args->event != NB_EV_APPLY)
1202 return NB_OK;
1203
1204 ple = nb_running_get_entry(args->dnode, NULL, true);
1205
1206 /* Start prefix entry update procedure. */
1207 prefix_list_entry_update_start(ple);
1208
1209 memset(&ple->prefix, 0, sizeof(ple->prefix));
1210
1211 /* Finish prefix entry update procedure. */
1212 prefix_list_entry_update_finish(ple);
1213
1214 return NB_OK;
1215 }
1216
1217 /*
1218 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
1219 */
lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(struct nb_cb_modify_args * args)1220 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
1221 struct nb_cb_modify_args *args)
1222 {
1223 struct prefix_list_entry *ple;
1224
1225 if (args->event == NB_EV_VALIDATE &&
1226 prefix_list_length_validate(args) != NB_OK)
1227 return NB_ERR_VALIDATION;
1228
1229 if (args->event == NB_EV_VALIDATE) {
1230 if (plist_is_dup_nb(args->dnode)) {
1231 snprintf(args->errmsg, args->errmsg_len,
1232 "duplicated prefix list value: %s",
1233 yang_dnode_get_string(args->dnode, NULL));
1234 return NB_ERR_VALIDATION;
1235 }
1236 return NB_OK;
1237 }
1238
1239 if (args->event != NB_EV_APPLY)
1240 return NB_OK;
1241
1242 ple = nb_running_get_entry(args->dnode, NULL, true);
1243
1244 /* Start prefix entry update procedure. */
1245 prefix_list_entry_update_start(ple);
1246
1247 ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
1248
1249 /* Finish prefix entry update procedure. */
1250 prefix_list_entry_update_finish(ple);
1251
1252 return NB_OK;
1253 }
1254
lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(struct nb_cb_destroy_args * args)1255 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
1256 struct nb_cb_destroy_args *args)
1257 {
1258 struct prefix_list_entry *ple;
1259
1260 if (args->event != NB_EV_APPLY)
1261 return NB_OK;
1262
1263 ple = nb_running_get_entry(args->dnode, NULL, true);
1264
1265 /* Start prefix entry update procedure. */
1266 prefix_list_entry_update_start(ple);
1267
1268 ple->ge = 0;
1269
1270 /* Finish prefix entry update procedure. */
1271 prefix_list_entry_update_finish(ple);
1272
1273 return NB_OK;
1274 }
1275
1276 /*
1277 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
1278 */
lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(struct nb_cb_modify_args * args)1279 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
1280 struct nb_cb_modify_args *args)
1281 {
1282 struct prefix_list_entry *ple;
1283
1284 if (args->event == NB_EV_VALIDATE &&
1285 prefix_list_length_validate(args) != NB_OK)
1286 return NB_ERR_VALIDATION;
1287
1288 if (args->event == NB_EV_VALIDATE) {
1289 if (plist_is_dup_nb(args->dnode)) {
1290 snprintf(args->errmsg, args->errmsg_len,
1291 "duplicated prefix list value: %s",
1292 yang_dnode_get_string(args->dnode, NULL));
1293 return NB_ERR_VALIDATION;
1294 }
1295 return NB_OK;
1296 }
1297
1298 if (args->event != NB_EV_APPLY)
1299 return NB_OK;
1300
1301 ple = nb_running_get_entry(args->dnode, NULL, true);
1302
1303 /* Start prefix entry update procedure. */
1304 prefix_list_entry_update_start(ple);
1305
1306 ple->le = yang_dnode_get_uint8(args->dnode, NULL);
1307
1308 /* Finish prefix entry update procedure. */
1309 prefix_list_entry_update_finish(ple);
1310
1311 return NB_OK;
1312 }
1313
lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(struct nb_cb_destroy_args * args)1314 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
1315 struct nb_cb_destroy_args *args)
1316 {
1317 struct prefix_list_entry *ple;
1318
1319 if (args->event != NB_EV_APPLY)
1320 return NB_OK;
1321
1322 ple = nb_running_get_entry(args->dnode, NULL, true);
1323
1324 /* Start prefix entry update procedure. */
1325 prefix_list_entry_update_start(ple);
1326
1327 ple->le = 0;
1328
1329 /* Finish prefix entry update procedure. */
1330 prefix_list_entry_update_finish(ple);
1331
1332 return NB_OK;
1333 }
1334
1335 /*
1336 * XPath: /frr-filter:lib/prefix-list/entry/any
1337 */
lib_prefix_list_entry_any_create(struct nb_cb_create_args * args)1338 static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
1339 {
1340 struct prefix_list_entry *ple;
1341 int type;
1342
1343 if (args->event == NB_EV_VALIDATE) {
1344 if (plist_is_dup_nb(args->dnode)) {
1345 snprintf(args->errmsg, args->errmsg_len,
1346 "duplicated prefix list value: %s",
1347 yang_dnode_get_string(args->dnode, NULL));
1348 return NB_ERR_VALIDATION;
1349 }
1350 return NB_OK;
1351 }
1352
1353 if (args->event != NB_EV_APPLY)
1354 return NB_OK;
1355
1356 ple = nb_running_get_entry(args->dnode, NULL, true);
1357
1358 /* Start prefix entry update procedure. */
1359 prefix_list_entry_update_start(ple);
1360
1361 ple->any = true;
1362
1363 /* Fill prefix struct from scratch. */
1364 memset(&ple->prefix, 0, sizeof(ple->prefix));
1365
1366 type = yang_dnode_get_enum(args->dnode, "../../type");
1367 switch (type) {
1368 case YPLT_IPV4:
1369 ple->prefix.family = AF_INET;
1370 ple->ge = 0;
1371 ple->le = IPV4_MAX_BITLEN;
1372 break;
1373 case YPLT_IPV6:
1374 ple->prefix.family = AF_INET6;
1375 ple->ge = 0;
1376 ple->le = IPV6_MAX_BITLEN;
1377 break;
1378 }
1379
1380 /* Finish prefix entry update procedure. */
1381 prefix_list_entry_update_finish(ple);
1382
1383 return NB_OK;
1384 }
1385
lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args * args)1386 static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
1387 {
1388 struct prefix_list_entry *ple;
1389
1390 if (args->event != NB_EV_APPLY)
1391 return NB_OK;
1392
1393 ple = nb_running_get_entry(args->dnode, NULL, true);
1394
1395 /* Start prefix entry update procedure. */
1396 prefix_list_entry_update_start(ple);
1397
1398 prefix_list_entry_set_empty(ple);
1399
1400 /* Finish prefix entry update procedure. */
1401 prefix_list_entry_update_finish(ple);
1402
1403 return NB_OK;
1404 }
1405
1406 /* clang-format off */
1407 const struct frr_yang_module_info frr_filter_info = {
1408 .name = "frr-filter",
1409 .nodes = {
1410 {
1411 .xpath = "/frr-filter:lib/access-list",
1412 .cbs = {
1413 .create = lib_access_list_create,
1414 .destroy = lib_access_list_destroy,
1415 }
1416 },
1417 {
1418 .xpath = "/frr-filter:lib/access-list/remark",
1419 .cbs = {
1420 .modify = lib_access_list_remark_modify,
1421 .destroy = lib_access_list_remark_destroy,
1422 .cli_show = access_list_remark_show,
1423 }
1424 },
1425 {
1426 .xpath = "/frr-filter:lib/access-list/entry",
1427 .cbs = {
1428 .create = lib_access_list_entry_create,
1429 .destroy = lib_access_list_entry_destroy,
1430 .cli_show = access_list_show,
1431 }
1432 },
1433 {
1434 .xpath = "/frr-filter:lib/access-list/entry/action",
1435 .cbs = {
1436 .modify = lib_access_list_entry_action_modify,
1437 }
1438 },
1439 {
1440 .xpath = "/frr-filter:lib/access-list/entry/ipv4-prefix",
1441 .cbs = {
1442 .modify = lib_access_list_entry_ipv4_prefix_modify,
1443 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
1444 }
1445 },
1446 {
1447 .xpath = "/frr-filter:lib/access-list/entry/ipv4-exact-match",
1448 .cbs = {
1449 .modify = lib_access_list_entry_ipv4_exact_match_modify,
1450 .destroy = lib_access_list_entry_ipv4_exact_match_destroy,
1451 }
1452 },
1453 {
1454 .xpath = "/frr-filter:lib/access-list/entry/host",
1455 .cbs = {
1456 .modify = lib_access_list_entry_host_modify,
1457 .destroy = lib_access_list_entry_host_destroy,
1458 }
1459 },
1460 {
1461 .xpath = "/frr-filter:lib/access-list/entry/network/address",
1462 .cbs = {
1463 .modify = lib_access_list_entry_network_address_modify,
1464 }
1465 },
1466 {
1467 .xpath = "/frr-filter:lib/access-list/entry/network/mask",
1468 .cbs = {
1469 .modify = lib_access_list_entry_network_mask_modify,
1470 }
1471 },
1472 {
1473 .xpath = "/frr-filter:lib/access-list/entry/source-any",
1474 .cbs = {
1475 .create = lib_access_list_entry_source_any_create,
1476 .destroy = lib_access_list_entry_source_any_destroy,
1477 }
1478 },
1479 {
1480 .xpath = "/frr-filter:lib/access-list/entry/destination-host",
1481 .cbs = {
1482 .modify = lib_access_list_entry_destination_host_modify,
1483 .destroy = lib_access_list_entry_destination_host_destroy,
1484 }
1485 },
1486 {
1487 .xpath = "/frr-filter:lib/access-list/entry/destination-network/address",
1488 .cbs = {
1489 .modify = lib_access_list_entry_destination_network_address_modify,
1490 }
1491 },
1492 {
1493 .xpath = "/frr-filter:lib/access-list/entry/destination-network/mask",
1494 .cbs = {
1495 .modify = lib_access_list_entry_destination_network_mask_modify,
1496 }
1497 },
1498 {
1499 .xpath = "/frr-filter:lib/access-list/entry/destination-any",
1500 .cbs = {
1501 .create = lib_access_list_entry_destination_any_create,
1502 .destroy = lib_access_list_entry_destination_any_destroy,
1503 }
1504 },
1505 {
1506 .xpath = "/frr-filter:lib/access-list/entry/ipv6-prefix",
1507 .cbs = {
1508 .modify = lib_access_list_entry_ipv4_prefix_modify,
1509 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
1510 }
1511 },
1512 {
1513 .xpath = "/frr-filter:lib/access-list/entry/ipv6-exact-match",
1514 .cbs = {
1515 .modify = lib_access_list_entry_ipv4_exact_match_modify,
1516 .destroy = lib_access_list_entry_ipv4_exact_match_destroy,
1517 }
1518 },
1519 {
1520 .xpath = "/frr-filter:lib/access-list/entry/mac",
1521 .cbs = {
1522 .modify = lib_access_list_entry_ipv4_prefix_modify,
1523 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
1524 }
1525 },
1526 {
1527 .xpath = "/frr-filter:lib/access-list/entry/any",
1528 .cbs = {
1529 .create = lib_access_list_entry_any_create,
1530 .destroy = lib_access_list_entry_any_destroy,
1531 }
1532 },
1533 {
1534 .xpath = "/frr-filter:lib/prefix-list",
1535 .cbs = {
1536 .create = lib_prefix_list_create,
1537 .destroy = lib_prefix_list_destroy,
1538 }
1539 },
1540 {
1541 .xpath = "/frr-filter:lib/prefix-list/remark",
1542 .cbs = {
1543 .modify = lib_prefix_list_remark_modify,
1544 .destroy = lib_prefix_list_remark_destroy,
1545 .cli_show = prefix_list_remark_show,
1546 }
1547 },
1548 {
1549 .xpath = "/frr-filter:lib/prefix-list/entry",
1550 .cbs = {
1551 .create = lib_prefix_list_entry_create,
1552 .destroy = lib_prefix_list_entry_destroy,
1553 .cli_show = prefix_list_show,
1554 }
1555 },
1556 {
1557 .xpath = "/frr-filter:lib/prefix-list/entry/action",
1558 .cbs = {
1559 .modify = lib_prefix_list_entry_action_modify,
1560 }
1561 },
1562 {
1563 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
1564 .cbs = {
1565 .modify = lib_prefix_list_entry_ipv4_prefix_modify,
1566 .destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
1567 }
1568 },
1569 {
1570 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
1571 .cbs = {
1572 .modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
1573 .destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
1574 }
1575 },
1576 {
1577 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
1578 .cbs = {
1579 .modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
1580 .destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
1581 }
1582 },
1583 {
1584 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
1585 .cbs = {
1586 .modify = lib_prefix_list_entry_ipv4_prefix_modify,
1587 .destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
1588 }
1589 },
1590 {
1591 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
1592 .cbs = {
1593 .modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
1594 .destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
1595 }
1596 },
1597 {
1598 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
1599 .cbs = {
1600 .modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
1601 .destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
1602 }
1603 },
1604 {
1605 .xpath = "/frr-filter:lib/prefix-list/entry/any",
1606 .cbs = {
1607 .create = lib_prefix_list_entry_any_create,
1608 .destroy = lib_prefix_list_entry_any_destroy,
1609 }
1610 },
1611 {
1612 .xpath = NULL,
1613 },
1614 }
1615 };
1616