1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * FRR filter northbound implementation.
5 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
11 #include "lib/northbound.h"
12 #include "lib/prefix.h"
13 #include "lib/printfrr.h"
15 #include "lib/filter.h"
16 #include "lib/plist.h"
17 #include "lib/plist_int.h"
18 #include "lib/routemap.h"
20 /* Helper function. */
21 static void acl_notify_route_map(struct access_list
*acl
, int route_map_event
)
23 switch (route_map_event
) {
24 case RMAP_EVENT_FILTER_ADDED
:
25 if (acl
->master
->add_hook
)
26 (*acl
->master
->add_hook
)(acl
);
28 case RMAP_EVENT_FILTER_DELETED
:
29 if (acl
->master
->delete_hook
)
30 (*acl
->master
->delete_hook
)(acl
);
34 route_map_notify_dependencies(acl
->name
, route_map_event
);
37 static enum nb_error
prefix_list_length_validate(struct nb_cb_modify_args
*args
)
39 int type
= yang_dnode_get_enum(args
->dnode
, "../../type");
40 const char *xpath_le
= NULL
, *xpath_ge
= NULL
;
44 if (type
== YPLT_IPV4
) {
45 yang_dnode_get_prefix(&p
, args
->dnode
, "../ipv4-prefix");
46 xpath_le
= "../ipv4-prefix-length-lesser-or-equal";
47 xpath_ge
= "../ipv4-prefix-length-greater-or-equal";
49 yang_dnode_get_prefix(&p
, args
->dnode
, "../ipv6-prefix");
50 xpath_le
= "../ipv6-prefix-length-lesser-or-equal";
51 xpath_ge
= "../ipv6-prefix-length-greater-or-equal";
56 * prefix length <= le.
58 if (yang_dnode_exists(args
->dnode
, xpath_le
)) {
59 le
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_le
);
66 * prefix length <= ge.
68 if (yang_dnode_exists(args
->dnode
, xpath_ge
)) {
69 ge
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_ge
);
78 if (yang_dnode_exists(args
->dnode
, xpath_le
)
79 && yang_dnode_exists(args
->dnode
, xpath_ge
)) {
80 le
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_le
);
81 ge
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_ge
);
90 args
->errmsg
, args
->errmsg_len
,
91 "Invalid prefix range for %pFX: Make sure that mask length <= ge <= le",
93 return NB_ERR_VALIDATION
;
97 * Sets prefix list entry to blank value.
99 * \param[out] ple prefix list entry to modify.
101 static void prefix_list_entry_set_empty(struct prefix_list_entry
*ple
)
104 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
110 prefix_list_nb_validate_v4_af_type(const struct lyd_node
*plist_dnode
,
111 char *errmsg
, size_t errmsg_len
)
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
;
126 prefix_list_nb_validate_v6_af_type(const struct lyd_node
*plist_dnode
,
127 char *errmsg
, size_t errmsg_len
)
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
;
141 static int lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
142 struct nb_cb_modify_args
*args
)
144 struct prefix_list_entry
*ple
;
146 if (args
->event
!= NB_EV_APPLY
)
149 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
151 /* Start prefix entry update procedure. */
152 prefix_list_entry_update_start(ple
);
154 ple
->ge
= yang_dnode_get_uint8(args
->dnode
, NULL
);
156 /* Finish prefix entry update procedure. */
157 prefix_list_entry_update_finish(ple
);
162 static int lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
163 struct nb_cb_modify_args
*args
)
165 struct prefix_list_entry
*ple
;
167 if (args
->event
!= NB_EV_APPLY
)
170 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
172 /* Start prefix entry update procedure. */
173 prefix_list_entry_update_start(ple
);
175 ple
->le
= yang_dnode_get_uint8(args
->dnode
, NULL
);
177 /* Finish prefix entry update procedure. */
178 prefix_list_entry_update_finish(ple
);
183 static int lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
184 struct nb_cb_destroy_args
*args
)
186 struct prefix_list_entry
*ple
;
188 if (args
->event
!= NB_EV_APPLY
)
191 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
193 /* Start prefix entry update procedure. */
194 prefix_list_entry_update_start(ple
);
198 /* Finish prefix entry update procedure. */
199 prefix_list_entry_update_finish(ple
);
204 static int lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
205 struct nb_cb_destroy_args
*args
)
207 struct prefix_list_entry
*ple
;
209 if (args
->event
!= NB_EV_APPLY
)
212 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
214 /* Start prefix entry update procedure. */
215 prefix_list_entry_update_start(ple
);
219 /* Finish prefix entry update procedure. */
220 prefix_list_entry_update_finish(ple
);
226 * Unsets the cisco style rule for addresses so it becomes disabled (the
227 * equivalent of setting: `0.0.0.0/32`).
229 * \param addr address part.
230 * \param mask mask part.
232 static void cisco_unset_addr_mask(struct in_addr
*addr
, struct in_addr
*mask
)
234 addr
->s_addr
= INADDR_ANY
;
235 mask
->s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
238 static int _acl_is_dup(const struct lyd_node
*dnode
, void *arg
)
240 struct acl_dup_args
*ada
= arg
;
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
;
248 if (strcmp(yang_dnode_get_string(dnode
, "action"), ada
->ada_action
))
249 return YANG_ITER_CONTINUE
;
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
)
257 /* Not same type, just skip it. */
258 if (!yang_dnode_exists(dnode
, ada
->ada_xpath
[idx
]))
259 return YANG_ITER_CONTINUE
;
261 /* Check if different value. */
262 if (strcmp(yang_dnode_get_string(dnode
, "%s",
263 ada
->ada_xpath
[idx
]),
264 ada
->ada_value
[idx
]))
265 return YANG_ITER_CONTINUE
;
268 ada
->ada_found
= true;
269 ada
->ada_seq
= yang_dnode_get_uint32(dnode
, "sequence");
271 return YANG_ITER_STOP
;
274 bool acl_is_dup(const struct lyd_node
*dnode
, struct acl_dup_args
*ada
)
276 ada
->ada_found
= false;
279 _acl_is_dup
, ada
, dnode
,
280 "/frr-filter:lib/access-list[type='%s'][name='%s']/entry",
281 ada
->ada_type
, ada
->ada_name
);
283 return ada
->ada_found
;
286 static bool acl_cisco_is_dup(const struct lyd_node
*dnode
)
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
[] = {
297 "./destination-host",
298 "./destination-network/address",
299 "./destination-network/mask",
305 ada
.ada_type
= "ipv4";
306 ada
.ada_name
= yang_dnode_get_string(entry_dnode
, "../name");
307 ada
.ada_action
= yang_dnode_get_string(entry_dnode
, "action");
308 ada
.ada_entry_dnode
= entry_dnode
;
310 /* Load all values/XPaths. */
311 while (cisco_entries
[idx
] != NULL
) {
312 if (!yang_dnode_exists(entry_dnode
, cisco_entries
[idx
])) {
317 ada
.ada_xpath
[arg_idx
] = cisco_entries
[idx
];
318 ada
.ada_value
[arg_idx
] = yang_dnode_get_string(
319 entry_dnode
, "%s", cisco_entries
[idx
]);
324 return acl_is_dup(entry_dnode
, &ada
);
327 static bool acl_zebra_is_dup(const struct lyd_node
*dnode
,
328 enum yang_access_list_type type
)
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
[] = {
336 "./ipv4-exact-match",
338 "./ipv6-exact-match",
347 ada
.ada_type
= "ipv4";
350 ada
.ada_type
= "ipv6";
353 ada
.ada_type
= "mac";
356 ada
.ada_name
= yang_dnode_get_string(entry_dnode
, "../name");
357 ada
.ada_action
= yang_dnode_get_string(entry_dnode
, "action");
358 ada
.ada_entry_dnode
= entry_dnode
;
360 /* Load all values/XPaths. */
361 while (zebra_entries
[idx
] != NULL
) {
362 if (!yang_dnode_exists(entry_dnode
, zebra_entries
[idx
])) {
367 ada
.ada_xpath
[arg_idx
] = zebra_entries
[idx
];
368 ada
.ada_value
[arg_idx
] = yang_dnode_get_string(
369 entry_dnode
, "%s", zebra_entries
[idx
]);
374 return acl_is_dup(entry_dnode
, &ada
);
377 static void plist_dnode_to_prefix(const struct lyd_node
*dnode
, bool *any
,
378 struct prefix
*p
, int *ge
, int *le
)
384 if (yang_dnode_exists(dnode
, "./any")) {
389 switch (yang_dnode_get_enum(dnode
, "../type")) {
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");
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");
415 static int _plist_is_dup(const struct lyd_node
*dnode
, void *arg
)
417 struct plist_dup_args
*pda
= arg
;
418 struct prefix p
= {};
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
;
427 if (strcmp(yang_dnode_get_string(dnode
, "action"), pda
->pda_action
))
428 return YANG_ITER_CONTINUE
;
430 plist_dnode_to_prefix(dnode
, &any
, &p
, &ge
, &le
);
434 return YANG_ITER_CONTINUE
;
436 if (!prefix_same(&pda
->prefix
, &p
) || pda
->ge
!= ge
438 return YANG_ITER_CONTINUE
;
441 pda
->pda_found
= true;
442 pda
->pda_seq
= yang_dnode_get_uint32(dnode
, "sequence");
444 return YANG_ITER_STOP
;
447 bool plist_is_dup(const struct lyd_node
*dnode
, struct plist_dup_args
*pda
)
449 pda
->pda_found
= false;
452 _plist_is_dup
, pda
, dnode
,
453 "/frr-filter:lib/prefix-list[type='%s'][name='%s']/entry",
454 pda
->pda_type
, pda
->pda_name
);
456 return pda
->pda_found
;
459 static bool plist_is_dup_nb(const struct lyd_node
*dnode
)
461 const struct lyd_node
*entry_dnode
=
462 yang_dnode_get_parent(dnode
, "entry");
463 struct plist_dup_args pda
= {};
466 pda
.pda_type
= yang_dnode_get_string(entry_dnode
, "../type");
467 pda
.pda_name
= yang_dnode_get_string(entry_dnode
, "../name");
468 pda
.pda_action
= yang_dnode_get_string(entry_dnode
, "action");
469 pda
.pda_entry_dnode
= entry_dnode
;
471 plist_dnode_to_prefix(entry_dnode
, &pda
.any
, &pda
.prefix
, &pda
.ge
,
474 return plist_is_dup(entry_dnode
, &pda
);
478 * XPath: /frr-filter:lib/access-list
480 static int lib_access_list_create(struct nb_cb_create_args
*args
)
482 struct access_list
*acl
= NULL
;
483 const char *acl_name
;
486 if (args
->event
!= NB_EV_APPLY
)
489 type
= yang_dnode_get_enum(args
->dnode
, "./type");
490 acl_name
= yang_dnode_get_string(args
->dnode
, "./name");
494 acl
= access_list_get(AFI_IP
, acl_name
);
497 acl
= access_list_get(AFI_IP6
, acl_name
);
500 acl
= access_list_get(AFI_L2VPN
, acl_name
);
504 nb_running_set_entry(args
->dnode
, acl
);
509 static int lib_access_list_destroy(struct nb_cb_destroy_args
*args
)
511 struct access_list
*acl
;
513 if (args
->event
!= NB_EV_APPLY
)
516 acl
= nb_running_unset_entry(args
->dnode
);
517 access_list_delete(acl
);
523 * XPath: /frr-filter:lib/access-list/remark
525 static int lib_access_list_remark_modify(struct nb_cb_modify_args
*args
)
527 struct access_list
*acl
;
530 if (args
->event
!= NB_EV_APPLY
)
533 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
535 XFREE(MTYPE_TMP
, acl
->remark
);
537 remark
= yang_dnode_get_string(args
->dnode
, NULL
);
538 acl
->remark
= XSTRDUP(MTYPE_TMP
, remark
);
544 lib_access_list_remark_destroy(struct nb_cb_destroy_args
*args
)
546 struct access_list
*acl
;
548 if (args
->event
!= NB_EV_APPLY
)
551 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
553 XFREE(MTYPE_TMP
, acl
->remark
);
560 * XPath: /frr-filter:lib/access-list/entry
562 static int lib_access_list_entry_create(struct nb_cb_create_args
*args
)
564 struct access_list
*acl
;
567 if (args
->event
!= NB_EV_APPLY
)
571 f
->seq
= yang_dnode_get_uint32(args
->dnode
, "./sequence");
573 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
575 access_list_filter_add(acl
, f
);
576 nb_running_set_entry(args
->dnode
, f
);
581 static int lib_access_list_entry_destroy(struct nb_cb_destroy_args
*args
)
583 struct access_list
*acl
;
586 if (args
->event
!= NB_EV_APPLY
)
589 f
= nb_running_unset_entry(args
->dnode
);
591 access_list_filter_delete(acl
, f
);
597 * XPath: /frr-filter:lib/access-list/entry/action
600 lib_access_list_entry_action_modify(struct nb_cb_modify_args
*args
)
602 const char *filter_type
;
605 if (args
->event
!= NB_EV_APPLY
)
608 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
609 filter_type
= yang_dnode_get_string(args
->dnode
, NULL
);
610 if (strcmp(filter_type
, "permit") == 0)
611 f
->type
= FILTER_PERMIT
;
613 f
->type
= FILTER_DENY
;
615 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
621 * XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
624 lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args
*args
)
626 struct filter_zebra
*fz
;
629 /* Don't allow duplicated values. */
630 if (args
->event
== NB_EV_VALIDATE
) {
631 if (acl_zebra_is_dup(
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
;
642 if (args
->event
!= NB_EV_APPLY
)
645 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
648 yang_dnode_get_prefix(&fz
->prefix
, args
->dnode
, NULL
);
650 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
656 lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args
*args
)
658 struct filter_zebra
*fz
;
661 if (args
->event
!= NB_EV_APPLY
)
664 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
666 memset(&fz
->prefix
, 0, sizeof(fz
->prefix
));
668 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
674 * XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
677 lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args
*args
)
679 struct filter_zebra
*fz
;
682 /* Don't allow duplicated values. */
683 if (args
->event
== NB_EV_VALIDATE
) {
684 if (acl_zebra_is_dup(
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
;
695 if (args
->event
!= NB_EV_APPLY
)
698 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
700 fz
->exact
= yang_dnode_get_bool(args
->dnode
, NULL
);
702 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
708 lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args
*args
)
710 struct filter_zebra
*fz
;
713 if (args
->event
!= NB_EV_APPLY
)
716 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
720 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
726 * XPath: /frr-filter:lib/access-list/entry/host
729 lib_access_list_entry_host_modify(struct nb_cb_modify_args
*args
)
731 struct filter_cisco
*fc
;
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
;
745 if (args
->event
!= NB_EV_APPLY
)
748 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
751 yang_dnode_get_ipv4(&fc
->addr
, args
->dnode
, NULL
);
752 fc
->addr_mask
.s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
754 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
760 lib_access_list_entry_host_destroy(struct nb_cb_destroy_args
*args
)
762 struct filter_cisco
*fc
;
765 if (args
->event
!= NB_EV_APPLY
)
768 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
770 cisco_unset_addr_mask(&fc
->addr
, &fc
->addr_mask
);
772 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
778 * XPath: /frr-filter:lib/access-list/entry/network/address
781 lib_access_list_entry_network_address_modify(struct nb_cb_modify_args
*args
)
783 struct filter_cisco
*fc
;
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
;
797 if (args
->event
!= NB_EV_APPLY
)
800 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
803 yang_dnode_get_ipv4(&fc
->addr
, args
->dnode
, NULL
);
805 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
811 * XPath: /frr-filter:lib/access-list/entry/network/mask
814 lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args
*args
)
816 struct filter_cisco
*fc
;
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
;
830 if (args
->event
!= NB_EV_APPLY
)
833 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
836 yang_dnode_get_ipv4(&fc
->addr_mask
, args
->dnode
, NULL
);
838 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
844 * XPath: /frr-filter:lib/access-list/entry/source-any
847 lib_access_list_entry_source_any_create(struct nb_cb_create_args
*args
)
849 struct filter_cisco
*fc
;
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
;
863 if (args
->event
!= NB_EV_APPLY
)
866 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
869 fc
->addr
.s_addr
= INADDR_ANY
;
870 fc
->addr_mask
.s_addr
= CISCO_BIN_ANY_WILDCARD_MASK
;
872 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
878 lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args
*args
)
880 struct filter_cisco
*fc
;
883 if (args
->event
!= NB_EV_APPLY
)
886 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
888 cisco_unset_addr_mask(&fc
->addr
, &fc
->addr_mask
);
890 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
896 * XPath: /frr-filter:lib/access-list/entry/destination-host
898 static int lib_access_list_entry_destination_host_modify(
899 struct nb_cb_modify_args
*args
)
901 struct filter_cisco
*fc
;
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
;
915 if (args
->event
!= NB_EV_APPLY
)
918 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
921 yang_dnode_get_ipv4(&fc
->mask
, args
->dnode
, NULL
);
922 fc
->mask_mask
.s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
924 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
929 static int lib_access_list_entry_destination_host_destroy(
930 struct nb_cb_destroy_args
*args
)
932 struct filter_cisco
*fc
;
935 if (args
->event
!= NB_EV_APPLY
)
938 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
941 cisco_unset_addr_mask(&fc
->mask
, &fc
->mask_mask
);
943 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
949 * XPath: /frr-filter:lib/access-list/entry/destination-network/address
951 static int lib_access_list_entry_destination_network_address_modify(
952 struct nb_cb_modify_args
*args
)
954 struct filter_cisco
*fc
;
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
;
968 if (args
->event
!= NB_EV_APPLY
)
971 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
974 yang_dnode_get_ipv4(&fc
->mask
, args
->dnode
, NULL
);
976 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
982 * XPath: /frr-filter:lib/access-list/entry/destination-network/mask
984 static int lib_access_list_entry_destination_network_mask_modify(
985 struct nb_cb_modify_args
*args
)
987 struct filter_cisco
*fc
;
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
;
1001 if (args
->event
!= NB_EV_APPLY
)
1004 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1007 yang_dnode_get_ipv4(&fc
->mask_mask
, args
->dnode
, NULL
);
1009 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1015 * XPath: /frr-filter:lib/access-list/entry/destination-any
1017 static int lib_access_list_entry_destination_any_create(
1018 struct nb_cb_create_args
*args
)
1020 struct filter_cisco
*fc
;
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
;
1034 if (args
->event
!= NB_EV_APPLY
)
1037 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1040 fc
->mask
.s_addr
= INADDR_ANY
;
1041 fc
->mask_mask
.s_addr
= CISCO_BIN_ANY_WILDCARD_MASK
;
1043 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1048 static int lib_access_list_entry_destination_any_destroy(
1049 struct nb_cb_destroy_args
*args
)
1051 struct filter_cisco
*fc
;
1054 if (args
->event
!= NB_EV_APPLY
)
1057 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1060 cisco_unset_addr_mask(&fc
->mask
, &fc
->mask_mask
);
1062 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
1068 * XPath: /frr-filter:lib/access-list/entry/any
1070 static int lib_access_list_entry_any_create(struct nb_cb_create_args
*args
)
1072 struct filter_zebra
*fz
;
1076 /* Don't allow duplicated values. */
1077 if (args
->event
== NB_EV_VALIDATE
) {
1078 if (acl_zebra_is_dup(
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
;
1089 if (args
->event
!= NB_EV_APPLY
)
1092 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1095 memset(&fz
->prefix
, 0, sizeof(fz
->prefix
));
1097 type
= yang_dnode_get_enum(args
->dnode
, "../../type");
1100 fz
->prefix
.family
= AF_INET
;
1103 fz
->prefix
.family
= AF_INET6
;
1106 fz
->prefix
.family
= AF_ETHERNET
;
1110 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1115 static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args
*args
)
1117 struct filter_zebra
*fz
;
1120 if (args
->event
!= NB_EV_APPLY
)
1123 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1125 fz
->prefix
.family
= AF_UNSPEC
;
1127 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
1133 * XPath: /frr-filter:lib/prefix-list
1135 static int lib_prefix_list_create(struct nb_cb_create_args
*args
)
1137 struct prefix_list
*pl
= NULL
;
1141 if (args
->event
!= NB_EV_APPLY
)
1144 type
= yang_dnode_get_enum(args
->dnode
, "./type");
1145 name
= yang_dnode_get_string(args
->dnode
, "./name");
1148 pl
= prefix_list_get(AFI_IP
, 0, name
);
1151 pl
= prefix_list_get(AFI_IP6
, 0, name
);
1155 nb_running_set_entry(args
->dnode
, pl
);
1160 static int lib_prefix_list_destroy(struct nb_cb_destroy_args
*args
)
1162 struct prefix_list
*pl
;
1164 if (args
->event
!= NB_EV_APPLY
)
1167 pl
= nb_running_unset_entry(args
->dnode
);
1168 prefix_list_delete(pl
);
1174 * XPath: /frr-filter:lib/prefix-list/remark
1176 static int lib_prefix_list_remark_modify(struct nb_cb_modify_args
*args
)
1178 struct prefix_list
*pl
;
1181 if (args
->event
!= NB_EV_APPLY
)
1184 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1186 XFREE(MTYPE_TMP
, pl
->desc
);
1188 remark
= yang_dnode_get_string(args
->dnode
, NULL
);
1189 pl
->desc
= XSTRDUP(MTYPE_TMP
, remark
);
1194 static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args
*args
)
1196 struct prefix_list
*pl
;
1198 if (args
->event
!= NB_EV_APPLY
)
1201 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1203 XFREE(MTYPE_TMP
, pl
->desc
);
1209 * XPath: /frr-filter:lib/prefix-list/entry
1211 static int lib_prefix_list_entry_create(struct nb_cb_create_args
*args
)
1213 struct prefix_list_entry
*ple
;
1214 struct prefix_list
*pl
;
1216 if (args
->event
!= NB_EV_APPLY
)
1219 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1220 ple
= prefix_list_entry_new();
1222 ple
->seq
= yang_dnode_get_uint32(args
->dnode
, "./sequence");
1223 prefix_list_entry_set_empty(ple
);
1224 nb_running_set_entry(args
->dnode
, ple
);
1229 static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args
*args
)
1231 struct prefix_list_entry
*ple
;
1233 if (args
->event
!= NB_EV_APPLY
)
1236 ple
= nb_running_unset_entry(args
->dnode
);
1238 prefix_list_entry_delete2(ple
);
1240 prefix_list_entry_free(ple
);
1246 * XPath: /frr-filter:lib/prefix-list/entry/action
1248 static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args
*args
)
1250 struct prefix_list_entry
*ple
;
1253 if (args
->event
!= NB_EV_APPLY
)
1256 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1258 /* Start prefix entry update procedure. */
1259 prefix_list_entry_update_start(ple
);
1261 action_type
= yang_dnode_get_enum(args
->dnode
, NULL
);
1262 if (action_type
== YPLA_PERMIT
)
1263 ple
->type
= PREFIX_PERMIT
;
1265 ple
->type
= PREFIX_DENY
;
1267 /* Finish prefix entry update procedure. */
1268 prefix_list_entry_update_finish(ple
);
1273 static int lib_prefix_list_entry_prefix_modify(struct nb_cb_modify_args
*args
)
1275 struct prefix_list_entry
*ple
;
1278 if (args
->event
!= NB_EV_APPLY
)
1281 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1283 /* Start prefix entry update procedure. */
1284 prefix_list_entry_update_start(ple
);
1286 yang_dnode_get_prefix(&ple
->prefix
, args
->dnode
, NULL
);
1288 /* Apply mask and correct original address if necessary. */
1289 prefix_copy(&p
, &ple
->prefix
);
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
);
1298 /* Finish prefix entry update procedure. */
1299 prefix_list_entry_update_finish(ple
);
1304 static int lib_prefix_list_entry_prefix_destroy(struct nb_cb_destroy_args
*args
)
1306 struct prefix_list_entry
*ple
;
1308 if (args
->event
!= NB_EV_APPLY
)
1311 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1313 /* Start prefix entry update procedure. */
1314 prefix_list_entry_update_start(ple
);
1316 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
1318 /* Finish prefix entry update procedure. */
1319 prefix_list_entry_update_finish(ple
);
1325 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
1328 lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args
*args
)
1330 if (args
->event
== NB_EV_VALIDATE
) {
1331 const struct lyd_node
*plist_dnode
=
1332 yang_dnode_get_parent(args
->dnode
, "prefix-list");
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
;
1341 return prefix_list_nb_validate_v4_af_type(
1342 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1345 return lib_prefix_list_entry_prefix_modify(args
);
1349 lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args
*args
)
1352 if (args
->event
!= NB_EV_APPLY
)
1355 return lib_prefix_list_entry_prefix_destroy(args
);
1359 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix
1362 lib_prefix_list_entry_ipv6_prefix_modify(struct nb_cb_modify_args
*args
)
1365 if (args
->event
== NB_EV_VALIDATE
) {
1366 const struct lyd_node
*plist_dnode
=
1367 yang_dnode_get_parent(args
->dnode
, "prefix-list");
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
;
1376 return prefix_list_nb_validate_v6_af_type(
1377 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1380 return lib_prefix_list_entry_prefix_modify(args
);
1384 lib_prefix_list_entry_ipv6_prefix_destroy(struct nb_cb_destroy_args
*args
)
1387 if (args
->event
!= NB_EV_APPLY
)
1390 return lib_prefix_list_entry_prefix_destroy(args
);
1394 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
1396 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
1397 struct nb_cb_modify_args
*args
)
1399 if (args
->event
== NB_EV_VALIDATE
1400 && prefix_list_length_validate(args
) != NB_OK
)
1401 return NB_ERR_VALIDATION
;
1403 if (args
->event
== NB_EV_VALIDATE
) {
1404 const struct lyd_node
*plist_dnode
=
1405 yang_dnode_get_parent(args
->dnode
, "prefix-list");
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
;
1414 return prefix_list_nb_validate_v4_af_type(
1415 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1418 return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
1422 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
1423 struct nb_cb_destroy_args
*args
)
1425 if (args
->event
== NB_EV_VALIDATE
) {
1426 const struct lyd_node
*plist_dnode
=
1427 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1429 return prefix_list_nb_validate_v4_af_type(
1430 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1433 return lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
1438 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
1440 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
1441 struct nb_cb_modify_args
*args
)
1443 if (args
->event
== NB_EV_VALIDATE
1444 && prefix_list_length_validate(args
) != NB_OK
)
1445 return NB_ERR_VALIDATION
;
1447 if (args
->event
== NB_EV_VALIDATE
) {
1448 const struct lyd_node
*plist_dnode
=
1449 yang_dnode_get_parent(args
->dnode
, "prefix-list");
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
;
1458 return prefix_list_nb_validate_v4_af_type(
1459 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1462 return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
1466 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
1467 struct nb_cb_destroy_args
*args
)
1469 if (args
->event
== NB_EV_VALIDATE
) {
1470 const struct lyd_node
*plist_dnode
=
1471 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1473 return prefix_list_nb_validate_v4_af_type(
1474 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1477 return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
1482 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal
1484 static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify(
1485 struct nb_cb_modify_args
*args
)
1487 if (args
->event
== NB_EV_VALIDATE
1488 && prefix_list_length_validate(args
) != NB_OK
)
1489 return NB_ERR_VALIDATION
;
1491 if (args
->event
== NB_EV_VALIDATE
) {
1492 const struct lyd_node
*plist_dnode
=
1493 yang_dnode_get_parent(args
->dnode
, "prefix-list");
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
;
1502 return prefix_list_nb_validate_v6_af_type(
1503 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1506 return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
1510 static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_destroy(
1511 struct nb_cb_destroy_args
*args
)
1513 if (args
->event
== NB_EV_VALIDATE
) {
1514 const struct lyd_node
*plist_dnode
=
1515 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1517 return prefix_list_nb_validate_v6_af_type(
1518 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1521 return lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
1526 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal
1528 static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_modify(
1529 struct nb_cb_modify_args
*args
)
1531 if (args
->event
== NB_EV_VALIDATE
1532 && prefix_list_length_validate(args
) != NB_OK
)
1533 return NB_ERR_VALIDATION
;
1535 if (args
->event
== NB_EV_VALIDATE
) {
1536 const struct lyd_node
*plist_dnode
=
1537 yang_dnode_get_parent(args
->dnode
, "prefix-list");
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
;
1546 return prefix_list_nb_validate_v6_af_type(
1547 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1550 return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
1554 static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_destroy(
1555 struct nb_cb_destroy_args
*args
)
1557 if (args
->event
== NB_EV_VALIDATE
) {
1558 const struct lyd_node
*plist_dnode
=
1559 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1561 return prefix_list_nb_validate_v6_af_type(
1562 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1565 return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
1570 * XPath: /frr-filter:lib/prefix-list/entry/any
1572 static int lib_prefix_list_entry_any_create(struct nb_cb_create_args
*args
)
1574 struct prefix_list_entry
*ple
;
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
;
1588 if (args
->event
!= NB_EV_APPLY
)
1591 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1593 /* Start prefix entry update procedure. */
1594 prefix_list_entry_update_start(ple
);
1598 /* Fill prefix struct from scratch. */
1599 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
1601 type
= yang_dnode_get_enum(args
->dnode
, "../../type");
1604 ple
->prefix
.family
= AF_INET
;
1606 ple
->le
= IPV4_MAX_BITLEN
;
1609 ple
->prefix
.family
= AF_INET6
;
1611 ple
->le
= IPV6_MAX_BITLEN
;
1615 /* Finish prefix entry update procedure. */
1616 prefix_list_entry_update_finish(ple
);
1621 static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args
*args
)
1623 struct prefix_list_entry
*ple
;
1625 if (args
->event
!= NB_EV_APPLY
)
1628 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1630 /* Start prefix entry update procedure. */
1631 prefix_list_entry_update_start(ple
);
1633 prefix_list_entry_set_empty(ple
);
1635 /* Finish prefix entry update procedure. */
1636 prefix_list_entry_update_finish(ple
);
1641 /* clang-format off */
1642 const struct frr_yang_module_info frr_filter_info
= {
1643 .name
= "frr-filter",
1646 .xpath
= "/frr-filter:lib/access-list",
1648 .create
= lib_access_list_create
,
1649 .destroy
= lib_access_list_destroy
,
1653 .xpath
= "/frr-filter:lib/access-list/remark",
1655 .modify
= lib_access_list_remark_modify
,
1656 .destroy
= lib_access_list_remark_destroy
,
1657 .cli_show
= access_list_remark_show
,
1661 .xpath
= "/frr-filter:lib/access-list/entry",
1663 .create
= lib_access_list_entry_create
,
1664 .destroy
= lib_access_list_entry_destroy
,
1665 .cli_cmp
= access_list_cmp
,
1666 .cli_show
= access_list_show
,
1670 .xpath
= "/frr-filter:lib/access-list/entry/action",
1672 .modify
= lib_access_list_entry_action_modify
,
1676 .xpath
= "/frr-filter:lib/access-list/entry/ipv4-prefix",
1678 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1679 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1683 .xpath
= "/frr-filter:lib/access-list/entry/ipv4-exact-match",
1685 .modify
= lib_access_list_entry_ipv4_exact_match_modify
,
1686 .destroy
= lib_access_list_entry_ipv4_exact_match_destroy
,
1690 .xpath
= "/frr-filter:lib/access-list/entry/host",
1692 .modify
= lib_access_list_entry_host_modify
,
1693 .destroy
= lib_access_list_entry_host_destroy
,
1697 .xpath
= "/frr-filter:lib/access-list/entry/network/address",
1699 .modify
= lib_access_list_entry_network_address_modify
,
1703 .xpath
= "/frr-filter:lib/access-list/entry/network/mask",
1705 .modify
= lib_access_list_entry_network_mask_modify
,
1709 .xpath
= "/frr-filter:lib/access-list/entry/source-any",
1711 .create
= lib_access_list_entry_source_any_create
,
1712 .destroy
= lib_access_list_entry_source_any_destroy
,
1716 .xpath
= "/frr-filter:lib/access-list/entry/destination-host",
1718 .modify
= lib_access_list_entry_destination_host_modify
,
1719 .destroy
= lib_access_list_entry_destination_host_destroy
,
1723 .xpath
= "/frr-filter:lib/access-list/entry/destination-network/address",
1725 .modify
= lib_access_list_entry_destination_network_address_modify
,
1729 .xpath
= "/frr-filter:lib/access-list/entry/destination-network/mask",
1731 .modify
= lib_access_list_entry_destination_network_mask_modify
,
1735 .xpath
= "/frr-filter:lib/access-list/entry/destination-any",
1737 .create
= lib_access_list_entry_destination_any_create
,
1738 .destroy
= lib_access_list_entry_destination_any_destroy
,
1742 .xpath
= "/frr-filter:lib/access-list/entry/ipv6-prefix",
1744 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1745 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1749 .xpath
= "/frr-filter:lib/access-list/entry/ipv6-exact-match",
1751 .modify
= lib_access_list_entry_ipv4_exact_match_modify
,
1752 .destroy
= lib_access_list_entry_ipv4_exact_match_destroy
,
1756 .xpath
= "/frr-filter:lib/access-list/entry/mac",
1758 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1759 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1763 .xpath
= "/frr-filter:lib/access-list/entry/any",
1765 .create
= lib_access_list_entry_any_create
,
1766 .destroy
= lib_access_list_entry_any_destroy
,
1770 .xpath
= "/frr-filter:lib/prefix-list",
1772 .create
= lib_prefix_list_create
,
1773 .destroy
= lib_prefix_list_destroy
,
1777 .xpath
= "/frr-filter:lib/prefix-list/remark",
1779 .modify
= lib_prefix_list_remark_modify
,
1780 .destroy
= lib_prefix_list_remark_destroy
,
1781 .cli_show
= prefix_list_remark_show
,
1785 .xpath
= "/frr-filter:lib/prefix-list/entry",
1787 .create
= lib_prefix_list_entry_create
,
1788 .destroy
= lib_prefix_list_entry_destroy
,
1789 .cli_cmp
= prefix_list_cmp
,
1790 .cli_show
= prefix_list_show
,
1794 .xpath
= "/frr-filter:lib/prefix-list/entry/action",
1796 .modify
= lib_prefix_list_entry_action_modify
,
1800 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
1802 .modify
= lib_prefix_list_entry_ipv4_prefix_modify
,
1803 .destroy
= lib_prefix_list_entry_ipv4_prefix_destroy
,
1807 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
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
,
1814 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
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
,
1821 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
1823 .modify
= lib_prefix_list_entry_ipv6_prefix_modify
,
1824 .destroy
= lib_prefix_list_entry_ipv6_prefix_destroy
,
1828 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
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
,
1835 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
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
,
1842 .xpath
= "/frr-filter:lib/prefix-list/entry/any",
1844 .create
= lib_prefix_list_entry_any_create
,
1845 .destroy
= lib_prefix_list_entry_any_destroy
,