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