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