]> git.proxmox.com Git - mirror_frr.git/blame - lib/filter_nb.c
lib: silently ignore duplicated values
[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
0ed507dd
RZ
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 */
130static 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
f414129b
RZ
136static 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
167bool 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
179static 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
219static 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
4470143b 268/*
375d157f 269 * XPath: /frr-filter:lib/access-list
4470143b 270 */
375d157f 271static int lib_access_list_create(struct nb_cb_create_args *args)
4470143b 272{
375d157f 273 struct access_list *acl = NULL;
4470143b 274 const char *acl_name;
375d157f 275 int type;
4470143b 276
fb8884f3 277 if (args->event != NB_EV_APPLY)
4470143b
RZ
278 return NB_OK;
279
375d157f
RZ
280 type = yang_dnode_get_enum(args->dnode, "./type");
281 acl_name = yang_dnode_get_string(args->dnode, "./name");
282
283 switch (type) {
284 case YALT_IPV4:
285 acl = access_list_get(AFI_IP, acl_name);
286 break;
287 case YALT_IPV6:
288 acl = access_list_get(AFI_IP6, acl_name);
289 break;
290 case YALT_MAC:
291 acl = access_list_get(AFI_L2VPN, acl_name);
292 break;
293 }
294
fb8884f3 295 nb_running_set_entry(args->dnode, acl);
4470143b
RZ
296
297 return NB_OK;
298}
299
375d157f 300static int lib_access_list_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
301{
302 struct access_master *am;
303 struct access_list *acl;
304
fb8884f3 305 if (args->event != NB_EV_APPLY)
4470143b
RZ
306 return NB_OK;
307
fb8884f3 308 acl = nb_running_unset_entry(args->dnode);
4470143b
RZ
309 am = acl->master;
310 if (am->delete_hook)
311 am->delete_hook(acl);
312
313 access_list_delete(acl);
314
315 return NB_OK;
316}
317
318/*
375d157f 319 * XPath: /frr-filter:lib/access-list/remark
4470143b 320 */
375d157f 321static int lib_access_list_remark_modify(struct nb_cb_modify_args *args)
4470143b
RZ
322{
323 struct access_list *acl;
324 const char *remark;
325
fb8884f3 326 if (args->event != NB_EV_APPLY)
4470143b
RZ
327 return NB_OK;
328
fb8884f3 329 acl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
330 if (acl->remark)
331 XFREE(MTYPE_TMP, acl->remark);
332
fb8884f3 333 remark = yang_dnode_get_string(args->dnode, NULL);
4470143b
RZ
334 acl->remark = XSTRDUP(MTYPE_TMP, remark);
335
336 return NB_OK;
337}
338
fb8884f3 339static int
375d157f 340lib_access_list_remark_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
341{
342 struct access_list *acl;
343
fb8884f3 344 if (args->event != NB_EV_APPLY)
4470143b
RZ
345 return NB_OK;
346
fb8884f3 347 acl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
348 if (acl->remark)
349 XFREE(MTYPE_TMP, acl->remark);
350
4470143b
RZ
351 return NB_OK;
352}
353
375d157f 354
4470143b 355/*
375d157f 356 * XPath: /frr-filter:lib/access-list/entry
4470143b 357 */
375d157f 358static int lib_access_list_entry_create(struct nb_cb_create_args *args)
4470143b 359{
4470143b
RZ
360 struct access_list *acl;
361 struct filter *f;
4470143b 362
fb8884f3 363 if (args->event != NB_EV_APPLY)
4470143b
RZ
364 return NB_OK;
365
4470143b 366 f = filter_new();
fb8884f3 367 f->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
4470143b 368
fb8884f3 369 acl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
370 f->acl = acl;
371 access_list_filter_add(acl, f);
fb8884f3 372 nb_running_set_entry(args->dnode, f);
4470143b
RZ
373
374 return NB_OK;
375}
376
375d157f 377static int lib_access_list_entry_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
378{
379 struct access_list *acl;
380 struct filter *f;
381
fb8884f3 382 if (args->event != NB_EV_APPLY)
4470143b
RZ
383 return NB_OK;
384
fb8884f3 385 f = nb_running_unset_entry(args->dnode);
4470143b
RZ
386 acl = f->acl;
387 access_list_filter_delete(acl, f);
388
389 return NB_OK;
390}
391
392/*
375d157f 393 * XPath: /frr-filter:lib/access-list/entry/action
4470143b
RZ
394 */
395static int
375d157f 396lib_access_list_entry_action_modify(struct nb_cb_modify_args *args)
4470143b
RZ
397{
398 const char *filter_type;
399 struct filter *f;
400
fb8884f3 401 if (args->event != NB_EV_APPLY)
4470143b
RZ
402 return NB_OK;
403
fb8884f3
RZ
404 f = nb_running_get_entry(args->dnode, NULL, true);
405 filter_type = yang_dnode_get_string(args->dnode, NULL);
4470143b
RZ
406 if (strcmp(filter_type, "permit") == 0)
407 f->type = FILTER_PERMIT;
408 else
409 f->type = FILTER_DENY;
410
1eb17c77
K
411 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
412
4470143b
RZ
413 return NB_OK;
414}
415
416/*
375d157f 417 * XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
4470143b
RZ
418 */
419static int
375d157f 420lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
4470143b 421{
375d157f 422 struct filter_zebra *fz;
4470143b
RZ
423 struct filter *f;
424
f414129b
RZ
425 /* Don't allow duplicated values. */
426 if (args->event == NB_EV_VALIDATE) {
427 if (acl_zebra_is_dup(
428 args->dnode,
429 yang_dnode_get_enum(args->dnode, "../../type"))) {
430 snprintfrr(args->errmsg, args->errmsg_len,
431 "duplicated access list value: %s",
432 yang_dnode_get_string(args->dnode, NULL));
433 return NB_ERR_VALIDATION;
434 }
435 return NB_OK;
436 }
437
fb8884f3 438 if (args->event != NB_EV_APPLY)
4470143b
RZ
439 return NB_OK;
440
fb8884f3 441 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
442 f->cisco = 0;
443 fz = &f->u.zfilter;
444 yang_dnode_get_prefix(&fz->prefix, args->dnode, NULL);
4470143b 445
1eb17c77
K
446 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
447
4470143b
RZ
448 return NB_OK;
449}
450
451static int
375d157f 452lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
4470143b 453{
375d157f 454 struct filter_zebra *fz;
4470143b
RZ
455 struct filter *f;
456
fb8884f3 457 if (args->event != NB_EV_APPLY)
4470143b
RZ
458 return NB_OK;
459
fb8884f3 460 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
461 fz = &f->u.zfilter;
462 memset(&fz->prefix, 0, sizeof(fz->prefix));
4470143b 463
1eb17c77
K
464 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
465
4470143b
RZ
466 return NB_OK;
467}
468
469/*
375d157f 470 * XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
4470143b
RZ
471 */
472static int
375d157f 473lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args *args)
4470143b 474{
375d157f 475 struct filter_zebra *fz;
4470143b 476 struct filter *f;
4470143b 477
f414129b
RZ
478 /* Don't allow duplicated values. */
479 if (args->event == NB_EV_VALIDATE) {
480 if (acl_zebra_is_dup(
481 args->dnode,
482 yang_dnode_get_enum(args->dnode, "../../type"))) {
483 snprintfrr(args->errmsg, args->errmsg_len,
484 "duplicated access list value: %s",
485 yang_dnode_get_string(args->dnode, NULL));
486 return NB_ERR_VALIDATION;
487 }
488 return NB_OK;
489 }
490
fb8884f3 491 if (args->event != NB_EV_APPLY)
4470143b
RZ
492 return NB_OK;
493
fb8884f3 494 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
495 fz = &f->u.zfilter;
496 fz->exact = yang_dnode_get_bool(args->dnode, NULL);
4470143b 497
1eb17c77
K
498 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
499
4470143b
RZ
500 return NB_OK;
501}
502
503static int
375d157f 504lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args *args)
4470143b 505{
375d157f 506 struct filter_zebra *fz;
4470143b
RZ
507 struct filter *f;
508
fb8884f3 509 if (args->event != NB_EV_APPLY)
4470143b
RZ
510 return NB_OK;
511
fb8884f3 512 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
513 fz = &f->u.zfilter;
514 fz->exact = 0;
4470143b 515
1eb17c77
K
516 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
517
4470143b
RZ
518 return NB_OK;
519}
520
521/*
375d157f 522 * XPath: /frr-filter:lib/access-list/entry/host
4470143b 523 */
fb8884f3 524static int
375d157f 525lib_access_list_entry_host_modify(struct nb_cb_modify_args *args)
4470143b
RZ
526{
527 struct filter_cisco *fc;
528 struct filter *f;
529
f414129b
RZ
530 /* Don't allow duplicated values. */
531 if (args->event == NB_EV_VALIDATE) {
532 if (acl_cisco_is_dup(args->dnode)) {
533 snprintfrr(args->errmsg, args->errmsg_len,
534 "duplicated access list value: %s",
535 yang_dnode_get_string(args->dnode, NULL));
536 return NB_ERR_VALIDATION;
537 }
538 return NB_OK;
539 }
540
fb8884f3 541 if (args->event != NB_EV_APPLY)
4470143b
RZ
542 return NB_OK;
543
fb8884f3 544 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 545 f->cisco = 1;
4470143b 546 fc = &f->u.cfilter;
375d157f 547 yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
0ed507dd 548 fc->addr_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
4470143b 549
1eb17c77
K
550 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
551
4470143b
RZ
552 return NB_OK;
553}
554
555static int
375d157f 556lib_access_list_entry_host_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
557{
558 struct filter_cisco *fc;
559 struct filter *f;
560
fb8884f3 561 if (args->event != NB_EV_APPLY)
4470143b
RZ
562 return NB_OK;
563
fb8884f3 564 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 565 fc = &f->u.cfilter;
0ed507dd 566 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
4470143b 567
1eb17c77
K
568 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
569
4470143b
RZ
570 return NB_OK;
571}
572
573/*
b1993be6 574 * XPath: /frr-filter:lib/access-list/entry/network/address
4470143b 575 */
375d157f 576static int
b1993be6 577lib_access_list_entry_network_address_modify(struct nb_cb_modify_args *args)
4470143b
RZ
578{
579 struct filter_cisco *fc;
580 struct filter *f;
581
f414129b
RZ
582 /* Don't allow duplicated values. */
583 if (args->event == NB_EV_VALIDATE) {
584 if (acl_cisco_is_dup(args->dnode)) {
585 snprintfrr(args->errmsg, args->errmsg_len,
586 "duplicated access list value: %s",
587 yang_dnode_get_string(args->dnode, NULL));
588 return NB_ERR_VALIDATION;
589 }
590 return NB_OK;
591 }
592
fb8884f3 593 if (args->event != NB_EV_APPLY)
4470143b
RZ
594 return NB_OK;
595
fb8884f3 596 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 597 f->cisco = 1;
4470143b 598 fc = &f->u.cfilter;
b1993be6 599 yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
4470143b 600
1eb17c77
K
601 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
602
4470143b
RZ
603 return NB_OK;
604}
605
b1993be6
RZ
606/*
607 * XPath: /frr-filter:lib/access-list/entry/network/mask
608 */
375d157f 609static int
b1993be6 610lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args *args)
4470143b
RZ
611{
612 struct filter_cisco *fc;
613 struct filter *f;
614
f414129b
RZ
615 /* Don't allow duplicated values. */
616 if (args->event == NB_EV_VALIDATE) {
617 if (acl_cisco_is_dup(args->dnode)) {
618 snprintfrr(args->errmsg, args->errmsg_len,
619 "duplicated access list value: %s",
620 yang_dnode_get_string(args->dnode, NULL));
621 return NB_ERR_VALIDATION;
622 }
623 return NB_OK;
624 }
625
fb8884f3 626 if (args->event != NB_EV_APPLY)
4470143b
RZ
627 return NB_OK;
628
fb8884f3 629 f = nb_running_get_entry(args->dnode, NULL, true);
b1993be6 630 f->cisco = 1;
4470143b 631 fc = &f->u.cfilter;
b1993be6 632 yang_dnode_get_ipv4(&fc->addr_mask, args->dnode, NULL);
4470143b 633
b1993be6 634 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
1eb17c77 635
4470143b
RZ
636 return NB_OK;
637}
638
639/*
375d157f 640 * XPath: /frr-filter:lib/access-list/entry/source-any
4470143b 641 */
375d157f
RZ
642static int
643lib_access_list_entry_source_any_create(struct nb_cb_create_args *args)
4470143b
RZ
644{
645 struct filter_cisco *fc;
646 struct filter *f;
4470143b 647
f414129b
RZ
648 /* Don't allow duplicated values. */
649 if (args->event == NB_EV_VALIDATE) {
650 if (acl_cisco_is_dup(args->dnode)) {
651 snprintfrr(args->errmsg, args->errmsg_len,
652 "duplicated access list value: %s",
653 yang_dnode_get_string(args->dnode, NULL));
654 return NB_ERR_VALIDATION;
655 }
656 return NB_OK;
657 }
658
fb8884f3 659 if (args->event != NB_EV_APPLY)
4470143b
RZ
660 return NB_OK;
661
fb8884f3 662 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 663 f->cisco = 1;
4470143b 664 fc = &f->u.cfilter;
375d157f 665 fc->addr.s_addr = INADDR_ANY;
0ed507dd 666 fc->addr_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
4470143b 667
1eb17c77
K
668 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
669
4470143b
RZ
670 return NB_OK;
671}
672
375d157f
RZ
673static int
674lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
675{
676 struct filter_cisco *fc;
677 struct filter *f;
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);
4470143b 683 fc = &f->u.cfilter;
0ed507dd 684 cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
4470143b 685
1eb17c77
K
686 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
687
4470143b
RZ
688 return NB_OK;
689}
690
691/*
375d157f 692 * XPath: /frr-filter:lib/access-list/entry/destination-host
4470143b 693 */
375d157f
RZ
694static int lib_access_list_entry_destination_host_modify(
695 struct nb_cb_modify_args *args)
4470143b
RZ
696{
697 struct filter_cisco *fc;
698 struct filter *f;
699
f414129b
RZ
700 /* Don't allow duplicated values. */
701 if (args->event == NB_EV_VALIDATE) {
702 if (acl_cisco_is_dup(args->dnode)) {
703 snprintfrr(args->errmsg, args->errmsg_len,
704 "duplicated access list value: %s",
705 yang_dnode_get_string(args->dnode, NULL));
706 return NB_ERR_VALIDATION;
707 }
708 return NB_OK;
709 }
710
fb8884f3 711 if (args->event != NB_EV_APPLY)
4470143b
RZ
712 return NB_OK;
713
fb8884f3 714 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b 715 fc = &f->u.cfilter;
375d157f
RZ
716 fc->extended = 1;
717 yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
0ed507dd 718 fc->mask_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
4470143b 719
1eb17c77
K
720 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
721
4470143b
RZ
722 return NB_OK;
723}
724
375d157f 725static int lib_access_list_entry_destination_host_destroy(
fb8884f3 726 struct nb_cb_destroy_args *args)
4470143b
RZ
727{
728 struct filter_cisco *fc;
729 struct filter *f;
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);
4470143b 735 fc = &f->u.cfilter;
375d157f 736 fc->extended = 0;
0ed507dd 737 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
4470143b 738
1eb17c77
K
739 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
740
4470143b
RZ
741 return NB_OK;
742}
743
744/*
b1993be6 745 * XPath: /frr-filter:lib/access-list/entry/destination-network/address
4470143b 746 */
b1993be6 747static int lib_access_list_entry_destination_network_address_modify(
375d157f 748 struct nb_cb_modify_args *args)
4470143b 749{
375d157f 750 struct filter_cisco *fc;
4470143b
RZ
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);
375d157f
RZ
768 fc = &f->u.cfilter;
769 fc->extended = 1;
b1993be6 770 yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
4470143b 771
1eb17c77
K
772 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
773
4470143b
RZ
774 return NB_OK;
775}
776
b1993be6
RZ
777/*
778 * XPath: /frr-filter:lib/access-list/entry/destination-network/mask
779 */
780static int lib_access_list_entry_destination_network_mask_modify(
781 struct nb_cb_modify_args *args)
4470143b 782{
375d157f 783 struct filter_cisco *fc;
4470143b
RZ
784 struct filter *f;
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 fc = &f->u.cfilter;
b1993be6
RZ
802 fc->extended = 1;
803 yang_dnode_get_ipv4(&fc->mask_mask, args->dnode, NULL);
4470143b 804
b1993be6 805 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
1eb17c77 806
4470143b
RZ
807 return NB_OK;
808}
809
810/*
375d157f 811 * XPath: /frr-filter:lib/access-list/entry/destination-any
4470143b 812 */
375d157f
RZ
813static int lib_access_list_entry_destination_any_create(
814 struct nb_cb_create_args *args)
4470143b 815{
375d157f 816 struct filter_cisco *fc;
4470143b
RZ
817 struct filter *f;
818
f414129b
RZ
819 /* Don't allow duplicated values. */
820 if (args->event == NB_EV_VALIDATE) {
821 if (acl_cisco_is_dup(args->dnode)) {
822 snprintfrr(args->errmsg, args->errmsg_len,
823 "duplicated access list value: %s",
824 yang_dnode_get_string(args->dnode, NULL));
825 return NB_ERR_VALIDATION;
826 }
827 return NB_OK;
828 }
829
fb8884f3 830 if (args->event != NB_EV_APPLY)
4470143b
RZ
831 return NB_OK;
832
fb8884f3 833 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
834 fc = &f->u.cfilter;
835 fc->extended = 1;
836 fc->mask.s_addr = INADDR_ANY;
0ed507dd 837 fc->mask_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
4470143b 838
1eb17c77
K
839 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
840
4470143b
RZ
841 return NB_OK;
842}
843
375d157f
RZ
844static int lib_access_list_entry_destination_any_destroy(
845 struct nb_cb_destroy_args *args)
4470143b 846{
375d157f 847 struct filter_cisco *fc;
4470143b
RZ
848 struct filter *f;
849
fb8884f3 850 if (args->event != NB_EV_APPLY)
4470143b
RZ
851 return NB_OK;
852
fb8884f3 853 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f
RZ
854 fc = &f->u.cfilter;
855 fc->extended = 0;
0ed507dd 856 cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
4470143b 857
1eb17c77
K
858 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
859
4470143b
RZ
860 return NB_OK;
861}
862
4470143b
RZ
863/*
864 * XPath: /frr-filter:lib/access-list/entry/any
865 */
fb8884f3 866static int lib_access_list_entry_any_create(struct nb_cb_create_args *args)
4470143b
RZ
867{
868 struct filter_zebra *fz;
869 struct filter *f;
870 int type;
871
f414129b
RZ
872 /* Don't allow duplicated values. */
873 if (args->event == NB_EV_VALIDATE) {
874 if (acl_zebra_is_dup(
875 args->dnode,
876 yang_dnode_get_enum(args->dnode, "../../type"))) {
877 snprintfrr(args->errmsg, args->errmsg_len,
878 "duplicated access list value: %s",
879 yang_dnode_get_string(args->dnode, NULL));
880 return NB_ERR_VALIDATION;
881 }
882 return NB_OK;
883 }
884
fb8884f3 885 if (args->event != NB_EV_APPLY)
4470143b
RZ
886 return NB_OK;
887
fb8884f3 888 f = nb_running_get_entry(args->dnode, NULL, true);
375d157f 889 f->cisco = 0;
4470143b
RZ
890 fz = &f->u.zfilter;
891 memset(&fz->prefix, 0, sizeof(fz->prefix));
892
fb8884f3 893 type = yang_dnode_get_enum(args->dnode, "../../type");
4470143b 894 switch (type) {
be96651c 895 case YALT_IPV4:
4470143b
RZ
896 fz->prefix.family = AF_INET;
897 break;
be96651c 898 case YALT_IPV6:
4470143b
RZ
899 fz->prefix.family = AF_INET6;
900 break;
be96651c 901 case YALT_MAC:
4470143b
RZ
902 fz->prefix.family = AF_ETHERNET;
903 break;
904 }
905
1eb17c77
K
906 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
907
4470143b
RZ
908 return NB_OK;
909}
910
fb8884f3 911static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
912{
913 struct filter_zebra *fz;
914 struct filter *f;
915
fb8884f3 916 if (args->event != NB_EV_APPLY)
4470143b
RZ
917 return NB_OK;
918
fb8884f3 919 f = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
920 fz = &f->u.zfilter;
921 fz->prefix.family = 0;
922
1eb17c77
K
923 acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
924
4470143b
RZ
925 return NB_OK;
926}
927
928/*
929 * XPath: /frr-filter:lib/prefix-list
930 */
fb8884f3 931static int lib_prefix_list_create(struct nb_cb_create_args *args)
4470143b 932{
ff94358e 933 struct prefix_list *pl = NULL;
4470143b
RZ
934 const char *name;
935 int type;
936
fb8884f3 937 if (args->event != NB_EV_APPLY)
4470143b
RZ
938 return NB_OK;
939
fb8884f3
RZ
940 type = yang_dnode_get_enum(args->dnode, "./type");
941 name = yang_dnode_get_string(args->dnode, "./name");
4470143b
RZ
942 switch (type) {
943 case 0: /* ipv4 */
944 pl = prefix_list_get(AFI_IP, 0, name);
945 break;
946 case 1: /* ipv6 */
947 pl = prefix_list_get(AFI_IP6, 0, name);
948 break;
949 }
950
fb8884f3 951 nb_running_set_entry(args->dnode, pl);
4470143b
RZ
952
953 return NB_OK;
954}
955
fb8884f3 956static int lib_prefix_list_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
957{
958 struct prefix_list *pl;
959
fb8884f3 960 if (args->event != NB_EV_APPLY)
4470143b
RZ
961 return NB_OK;
962
fb8884f3 963 pl = nb_running_unset_entry(args->dnode);
4470143b
RZ
964 prefix_list_delete(pl);
965
966 return NB_OK;
967}
968
969/*
cc82bcc1 970 * XPath: /frr-filter:lib/prefix-list/remark
4470143b 971 */
cc82bcc1 972static int lib_prefix_list_remark_modify(struct nb_cb_modify_args *args)
4470143b
RZ
973{
974 struct prefix_list *pl;
975 const char *remark;
976
fb8884f3 977 if (args->event != NB_EV_APPLY)
4470143b
RZ
978 return NB_OK;
979
fb8884f3 980 pl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
981 if (pl->desc)
982 XFREE(MTYPE_TMP, pl->desc);
983
fb8884f3 984 remark = yang_dnode_get_string(args->dnode, NULL);
4470143b
RZ
985 pl->desc = XSTRDUP(MTYPE_TMP, remark);
986
987 return NB_OK;
988}
989
cc82bcc1 990static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
991{
992 struct prefix_list *pl;
993
fb8884f3 994 if (args->event != NB_EV_APPLY)
4470143b
RZ
995 return NB_OK;
996
fb8884f3 997 pl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
998 if (pl->desc)
999 XFREE(MTYPE_TMP, pl->desc);
1000
4470143b
RZ
1001 return NB_OK;
1002}
1003
1004/*
1005 * XPath: /frr-filter:lib/prefix-list/entry
1006 */
fb8884f3 1007static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
4470143b
RZ
1008{
1009 struct prefix_list_entry *ple;
1010 struct prefix_list *pl;
4470143b 1011
fb8884f3 1012 if (args->event != NB_EV_APPLY)
4470143b
RZ
1013 return NB_OK;
1014
fb8884f3 1015 pl = nb_running_get_entry(args->dnode, NULL, true);
4470143b
RZ
1016 ple = prefix_list_entry_new();
1017 ple->pl = pl;
cc82bcc1 1018 ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
81b50422 1019 prefix_list_entry_set_empty(ple);
a7b28218 1020 nb_running_set_entry(args->dnode, ple);
4470143b
RZ
1021
1022 return NB_OK;
1023}
1024
fb8884f3 1025static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
1026{
1027 struct prefix_list_entry *ple;
1028
fb8884f3 1029 if (args->event != NB_EV_APPLY)
4470143b
RZ
1030 return NB_OK;
1031
fb8884f3 1032 ple = nb_running_unset_entry(args->dnode);
a7b28218 1033 if (ple->installed)
81b50422 1034 prefix_list_entry_delete2(ple);
a7b28218
RZ
1035 else
1036 prefix_list_entry_free(ple);
4470143b
RZ
1037
1038 return NB_OK;
1039}
1040
1041/*
1042 * XPath: /frr-filter:lib/prefix-list/entry/action
1043 */
fb8884f3 1044static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
4470143b
RZ
1045{
1046 struct prefix_list_entry *ple;
be96651c 1047 int action_type;
4470143b 1048
fb8884f3 1049 if (args->event != NB_EV_APPLY)
4470143b
RZ
1050 return NB_OK;
1051
fb8884f3 1052 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1053
1054 /* Start prefix entry update procedure. */
1055 prefix_list_entry_update_start(ple);
1056
be96651c
RZ
1057 action_type = yang_dnode_get_enum(args->dnode, NULL);
1058 if (action_type == YPLA_PERMIT)
4470143b
RZ
1059 ple->type = PREFIX_PERMIT;
1060 else
1061 ple->type = PREFIX_DENY;
1062
a7b28218
RZ
1063 /* Finish prefix entry update procedure. */
1064 prefix_list_entry_update_finish(ple);
1065
4470143b
RZ
1066 return NB_OK;
1067}
1068
1069/*
1070 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
1071 */
1072static int
fb8884f3 1073lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
4470143b
RZ
1074{
1075 struct prefix_list_entry *ple;
cf4472c4
RZ
1076 struct prefix p;
1077
1078 if (args->event == NB_EV_VALIDATE) {
1079 /*
1080 * TODO: validate prefix_entry_dup_check() passes.
1081 *
1082 * This needs to be implemented using YANG lyd_node
1083 * navigation, because the `priv` data structures are not
1084 * available at `NB_EV_VALIDATE` phase. An easier
1085 * alternative would be mark `ipvx-prefix` as unique
1086 * (see RFC 7950, Section 7.8.3. The list "unique" Statement).
1087 */
1088 return NB_OK;
1089 }
4470143b 1090
fb8884f3 1091 if (args->event != NB_EV_APPLY)
4470143b
RZ
1092 return NB_OK;
1093
fb8884f3 1094 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1095
1096 /* Start prefix entry update procedure. */
1097 prefix_list_entry_update_start(ple);
1098
fb8884f3 1099 yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
4470143b 1100
cf4472c4
RZ
1101 /* Apply mask and correct original address if necessary. */
1102 prefix_copy(&p, &ple->prefix);
1103 apply_mask(&p);
1104 if (!prefix_same(&ple->prefix, &p)) {
1105 zlog_info("%s: bad network %pFX correcting it to %pFX",
1106 __func__, &ple->prefix, &p);
1107 prefix_copy(&ple->prefix, &p);
1108 }
1109
1110
a7b28218
RZ
1111 /* Finish prefix entry update procedure. */
1112 prefix_list_entry_update_finish(ple);
1113
4470143b
RZ
1114 return NB_OK;
1115}
1116
1117static int
fb8884f3 1118lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
1119{
1120 struct prefix_list_entry *ple;
1121
fb8884f3 1122 if (args->event != NB_EV_APPLY)
4470143b
RZ
1123 return NB_OK;
1124
fb8884f3 1125 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1126
1127 /* Start prefix entry update procedure. */
1128 prefix_list_entry_update_start(ple);
1129
4470143b 1130 memset(&ple->prefix, 0, sizeof(ple->prefix));
4470143b 1131
a7b28218
RZ
1132 /* Finish prefix entry update procedure. */
1133 prefix_list_entry_update_finish(ple);
1134
4470143b
RZ
1135 return NB_OK;
1136}
1137
1138/*
1139 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
1140 */
1141static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
fb8884f3 1142 struct nb_cb_modify_args *args)
4470143b
RZ
1143{
1144 struct prefix_list_entry *ple;
1145
4362a768 1146 if (args->event == NB_EV_VALIDATE &&
8bc38cbd 1147 prefix_list_length_validate(args) != NB_OK)
4362a768
RZ
1148 return NB_ERR_VALIDATION;
1149
fb8884f3 1150 if (args->event != NB_EV_APPLY)
4470143b
RZ
1151 return NB_OK;
1152
fb8884f3 1153 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1154
1155 /* Start prefix entry update procedure. */
1156 prefix_list_entry_update_start(ple);
1157
fb8884f3 1158 ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
4470143b 1159
a7b28218
RZ
1160 /* Finish prefix entry update procedure. */
1161 prefix_list_entry_update_finish(ple);
1162
4470143b
RZ
1163 return NB_OK;
1164}
1165
1166static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
fb8884f3 1167 struct nb_cb_destroy_args *args)
4470143b
RZ
1168{
1169 struct prefix_list_entry *ple;
1170
fb8884f3 1171 if (args->event != NB_EV_APPLY)
4470143b
RZ
1172 return NB_OK;
1173
fb8884f3 1174 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1175
1176 /* Start prefix entry update procedure. */
1177 prefix_list_entry_update_start(ple);
1178
4470143b
RZ
1179 ple->ge = 0;
1180
a7b28218
RZ
1181 /* Finish prefix entry update procedure. */
1182 prefix_list_entry_update_finish(ple);
1183
4470143b
RZ
1184 return NB_OK;
1185}
1186
1187/*
1188 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
1189 */
1190static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
fb8884f3 1191 struct nb_cb_modify_args *args)
4470143b
RZ
1192{
1193 struct prefix_list_entry *ple;
1194
4362a768 1195 if (args->event == NB_EV_VALIDATE &&
8bc38cbd 1196 prefix_list_length_validate(args) != NB_OK)
4362a768
RZ
1197 return NB_ERR_VALIDATION;
1198
fb8884f3 1199 if (args->event != NB_EV_APPLY)
4470143b
RZ
1200 return NB_OK;
1201
fb8884f3 1202 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1203
1204 /* Start prefix entry update procedure. */
1205 prefix_list_entry_update_start(ple);
1206
fb8884f3 1207 ple->le = yang_dnode_get_uint8(args->dnode, NULL);
4470143b 1208
a7b28218
RZ
1209 /* Finish prefix entry update procedure. */
1210 prefix_list_entry_update_finish(ple);
1211
4470143b
RZ
1212 return NB_OK;
1213}
1214
1215static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
fb8884f3 1216 struct nb_cb_destroy_args *args)
4470143b
RZ
1217{
1218 struct prefix_list_entry *ple;
1219
fb8884f3 1220 if (args->event != NB_EV_APPLY)
4470143b
RZ
1221 return NB_OK;
1222
fb8884f3 1223 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1224
1225 /* Start prefix entry update procedure. */
1226 prefix_list_entry_update_start(ple);
1227
4470143b
RZ
1228 ple->le = 0;
1229
a7b28218
RZ
1230 /* Finish prefix entry update procedure. */
1231 prefix_list_entry_update_finish(ple);
1232
4470143b
RZ
1233 return NB_OK;
1234}
1235
4470143b
RZ
1236/*
1237 * XPath: /frr-filter:lib/prefix-list/entry/any
1238 */
fb8884f3 1239static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
4470143b
RZ
1240{
1241 struct prefix_list_entry *ple;
81b50422 1242 int type;
4470143b 1243
fb8884f3 1244 if (args->event != NB_EV_APPLY)
4470143b
RZ
1245 return NB_OK;
1246
fb8884f3 1247 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1248
1249 /* Start prefix entry update procedure. */
1250 prefix_list_entry_update_start(ple);
1251
81b50422
RZ
1252 ple->any = true;
1253
1254 /* Fill prefix struct from scratch. */
4470143b 1255 memset(&ple->prefix, 0, sizeof(ple->prefix));
81b50422
RZ
1256
1257 type = yang_dnode_get_enum(args->dnode, "../../type");
1258 switch (type) {
be96651c 1259 case YPLT_IPV4:
81b50422
RZ
1260 ple->prefix.family = AF_INET;
1261 ple->ge = 0;
1262 ple->le = IPV4_MAX_BITLEN;
1263 break;
be96651c 1264 case YPLT_IPV6:
81b50422
RZ
1265 ple->prefix.family = AF_INET6;
1266 ple->ge = 0;
1267 ple->le = IPV6_MAX_BITLEN;
1268 break;
1269 }
4470143b 1270
a7b28218
RZ
1271 /* Finish prefix entry update procedure. */
1272 prefix_list_entry_update_finish(ple);
1273
4470143b
RZ
1274 return NB_OK;
1275}
1276
fb8884f3 1277static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
4470143b
RZ
1278{
1279 struct prefix_list_entry *ple;
1280
fb8884f3 1281 if (args->event != NB_EV_APPLY)
4470143b
RZ
1282 return NB_OK;
1283
fb8884f3 1284 ple = nb_running_get_entry(args->dnode, NULL, true);
a7b28218
RZ
1285
1286 /* Start prefix entry update procedure. */
1287 prefix_list_entry_update_start(ple);
1288
81b50422 1289 prefix_list_entry_set_empty(ple);
4470143b 1290
a7b28218
RZ
1291 /* Finish prefix entry update procedure. */
1292 prefix_list_entry_update_finish(ple);
1293
4470143b
RZ
1294 return NB_OK;
1295}
1296
1297/* clang-format off */
1298const struct frr_yang_module_info frr_filter_info = {
1299 .name = "frr-filter",
1300 .nodes = {
1301 {
375d157f 1302 .xpath = "/frr-filter:lib/access-list",
4470143b 1303 .cbs = {
375d157f
RZ
1304 .create = lib_access_list_create,
1305 .destroy = lib_access_list_destroy,
4470143b
RZ
1306 }
1307 },
1308 {
375d157f 1309 .xpath = "/frr-filter:lib/access-list/remark",
4470143b 1310 .cbs = {
375d157f
RZ
1311 .modify = lib_access_list_remark_modify,
1312 .destroy = lib_access_list_remark_destroy,
1313 .cli_show = access_list_remark_show,
4470143b
RZ
1314 }
1315 },
1316 {
375d157f 1317 .xpath = "/frr-filter:lib/access-list/entry",
4470143b 1318 .cbs = {
375d157f
RZ
1319 .create = lib_access_list_entry_create,
1320 .destroy = lib_access_list_entry_destroy,
1321 .cli_show = access_list_show,
4470143b
RZ
1322 }
1323 },
1324 {
375d157f 1325 .xpath = "/frr-filter:lib/access-list/entry/action",
4470143b 1326 .cbs = {
375d157f 1327 .modify = lib_access_list_entry_action_modify,
4470143b
RZ
1328 }
1329 },
1330 {
375d157f 1331 .xpath = "/frr-filter:lib/access-list/entry/ipv4-prefix",
4470143b 1332 .cbs = {
375d157f
RZ
1333 .modify = lib_access_list_entry_ipv4_prefix_modify,
1334 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1335 }
1336 },
1337 {
375d157f 1338 .xpath = "/frr-filter:lib/access-list/entry/ipv4-exact-match",
4470143b 1339 .cbs = {
375d157f
RZ
1340 .modify = lib_access_list_entry_ipv4_exact_match_modify,
1341 .destroy = lib_access_list_entry_ipv4_exact_match_destroy,
4470143b
RZ
1342 }
1343 },
1344 {
375d157f 1345 .xpath = "/frr-filter:lib/access-list/entry/host",
4470143b 1346 .cbs = {
375d157f
RZ
1347 .modify = lib_access_list_entry_host_modify,
1348 .destroy = lib_access_list_entry_host_destroy,
4470143b
RZ
1349 }
1350 },
1351 {
b1993be6 1352 .xpath = "/frr-filter:lib/access-list/entry/network/address",
4470143b 1353 .cbs = {
b1993be6
RZ
1354 .modify = lib_access_list_entry_network_address_modify,
1355 }
1356 },
1357 {
1358 .xpath = "/frr-filter:lib/access-list/entry/network/mask",
1359 .cbs = {
1360 .modify = lib_access_list_entry_network_mask_modify,
4470143b
RZ
1361 }
1362 },
1363 {
375d157f 1364 .xpath = "/frr-filter:lib/access-list/entry/source-any",
4470143b 1365 .cbs = {
375d157f
RZ
1366 .create = lib_access_list_entry_source_any_create,
1367 .destroy = lib_access_list_entry_source_any_destroy,
4470143b
RZ
1368 }
1369 },
1370 {
375d157f 1371 .xpath = "/frr-filter:lib/access-list/entry/destination-host",
4470143b 1372 .cbs = {
375d157f
RZ
1373 .modify = lib_access_list_entry_destination_host_modify,
1374 .destroy = lib_access_list_entry_destination_host_destroy,
4470143b
RZ
1375 }
1376 },
1377 {
b1993be6
RZ
1378 .xpath = "/frr-filter:lib/access-list/entry/destination-network/address",
1379 .cbs = {
1380 .modify = lib_access_list_entry_destination_network_address_modify,
1381 }
1382 },
1383 {
1384 .xpath = "/frr-filter:lib/access-list/entry/destination-network/mask",
4470143b 1385 .cbs = {
b1993be6 1386 .modify = lib_access_list_entry_destination_network_mask_modify,
4470143b
RZ
1387 }
1388 },
1389 {
375d157f 1390 .xpath = "/frr-filter:lib/access-list/entry/destination-any",
4470143b 1391 .cbs = {
375d157f
RZ
1392 .create = lib_access_list_entry_destination_any_create,
1393 .destroy = lib_access_list_entry_destination_any_destroy,
4470143b
RZ
1394 }
1395 },
1396 {
1397 .xpath = "/frr-filter:lib/access-list/entry/ipv6-prefix",
1398 .cbs = {
a247b2b7
RZ
1399 .modify = lib_access_list_entry_ipv4_prefix_modify,
1400 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1401 }
1402 },
1403 {
1404 .xpath = "/frr-filter:lib/access-list/entry/ipv6-exact-match",
1405 .cbs = {
a247b2b7
RZ
1406 .modify = lib_access_list_entry_ipv4_exact_match_modify,
1407 .destroy = lib_access_list_entry_ipv4_exact_match_destroy,
4470143b
RZ
1408 }
1409 },
1410 {
1411 .xpath = "/frr-filter:lib/access-list/entry/mac",
1412 .cbs = {
a247b2b7
RZ
1413 .modify = lib_access_list_entry_ipv4_prefix_modify,
1414 .destroy = lib_access_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1415 }
1416 },
1417 {
1418 .xpath = "/frr-filter:lib/access-list/entry/any",
1419 .cbs = {
1420 .create = lib_access_list_entry_any_create,
1421 .destroy = lib_access_list_entry_any_destroy,
1422 }
1423 },
1424 {
1425 .xpath = "/frr-filter:lib/prefix-list",
1426 .cbs = {
1427 .create = lib_prefix_list_create,
1428 .destroy = lib_prefix_list_destroy,
1429 }
1430 },
1431 {
cc82bcc1 1432 .xpath = "/frr-filter:lib/prefix-list/remark",
4470143b 1433 .cbs = {
cc82bcc1
RZ
1434 .modify = lib_prefix_list_remark_modify,
1435 .destroy = lib_prefix_list_remark_destroy,
1d3c4b66 1436 .cli_show = prefix_list_remark_show,
4470143b
RZ
1437 }
1438 },
1439 {
1440 .xpath = "/frr-filter:lib/prefix-list/entry",
1441 .cbs = {
1442 .create = lib_prefix_list_entry_create,
1443 .destroy = lib_prefix_list_entry_destroy,
1d3c4b66 1444 .cli_show = prefix_list_show,
4470143b
RZ
1445 }
1446 },
1447 {
1448 .xpath = "/frr-filter:lib/prefix-list/entry/action",
1449 .cbs = {
1450 .modify = lib_prefix_list_entry_action_modify,
1451 }
1452 },
1453 {
1454 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
1455 .cbs = {
1456 .modify = lib_prefix_list_entry_ipv4_prefix_modify,
1457 .destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
1458 }
1459 },
1460 {
1461 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
1462 .cbs = {
1463 .modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
1464 .destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
1465 }
1466 },
1467 {
1468 .xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
1469 .cbs = {
1470 .modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
1471 .destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
1472 }
1473 },
1474 {
1475 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
1476 .cbs = {
a247b2b7
RZ
1477 .modify = lib_prefix_list_entry_ipv4_prefix_modify,
1478 .destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
4470143b
RZ
1479 }
1480 },
1481 {
1482 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
1483 .cbs = {
a247b2b7
RZ
1484 .modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
1485 .destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
4470143b
RZ
1486 }
1487 },
1488 {
1489 .xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
1490 .cbs = {
a247b2b7
RZ
1491 .modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
1492 .destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
4470143b
RZ
1493 }
1494 },
1495 {
1496 .xpath = "/frr-filter:lib/prefix-list/entry/any",
1497 .cbs = {
1498 .create = lib_prefix_list_entry_any_create,
1499 .destroy = lib_prefix_list_entry_any_destroy,
1500 }
1501 },
1502 {
1503 .xpath = NULL,
1504 },
1505 }
1506};