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