2 * FRR filter northbound implementation.
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "lib/northbound.h"
26 #include "lib/prefix.h"
27 #include "lib/printfrr.h"
29 #include "lib/filter.h"
30 #include "lib/plist.h"
31 #include "lib/plist_int.h"
32 #include "lib/routemap.h"
34 /* Helper function. */
35 static void acl_notify_route_map(struct access_list
*acl
, int route_map_event
)
37 switch (route_map_event
) {
38 case RMAP_EVENT_FILTER_ADDED
:
39 if (acl
->master
->add_hook
)
40 (*acl
->master
->add_hook
)(acl
);
42 case RMAP_EVENT_FILTER_DELETED
:
43 if (acl
->master
->delete_hook
)
44 (*acl
->master
->delete_hook
)(acl
);
48 route_map_notify_dependencies(acl
->name
, route_map_event
);
51 static enum nb_error
prefix_list_length_validate(struct nb_cb_modify_args
*args
)
53 int type
= yang_dnode_get_enum(args
->dnode
, "../../type");
54 const char *xpath_le
= NULL
, *xpath_ge
= NULL
;
58 if (type
== YPLT_IPV4
) {
59 yang_dnode_get_prefix(&p
, args
->dnode
, "../ipv4-prefix");
60 xpath_le
= "../ipv4-prefix-length-lesser-or-equal";
61 xpath_ge
= "../ipv4-prefix-length-greater-or-equal";
63 yang_dnode_get_prefix(&p
, args
->dnode
, "../ipv6-prefix");
64 xpath_le
= "../ipv6-prefix-length-lesser-or-equal";
65 xpath_ge
= "../ipv6-prefix-length-greater-or-equal";
70 * prefix length <= le.
72 if (yang_dnode_exists(args
->dnode
, xpath_le
)) {
73 le
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_le
);
80 * prefix length <= ge.
82 if (yang_dnode_exists(args
->dnode
, xpath_ge
)) {
83 ge
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_ge
);
92 if (yang_dnode_exists(args
->dnode
, xpath_le
)
93 && yang_dnode_exists(args
->dnode
, xpath_ge
)) {
94 le
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_le
);
95 ge
= yang_dnode_get_uint8(args
->dnode
, "%s", xpath_ge
);
104 args
->errmsg
, args
->errmsg_len
,
105 "Invalid prefix range for %pFX: Make sure that mask length <= ge <= le",
107 return NB_ERR_VALIDATION
;
111 * Sets prefix list entry to blank value.
113 * \param[out] ple prefix list entry to modify.
115 static void prefix_list_entry_set_empty(struct prefix_list_entry
*ple
)
118 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
124 prefix_list_nb_validate_v4_af_type(const struct lyd_node
*plist_dnode
,
125 char *errmsg
, size_t errmsg_len
)
129 af_type
= yang_dnode_get_enum(plist_dnode
, "./type");
130 if (af_type
!= YPLT_IPV4
) {
131 snprintf(errmsg
, errmsg_len
,
132 "prefix-list type %u is mismatched.", af_type
);
133 return NB_ERR_VALIDATION
;
140 prefix_list_nb_validate_v6_af_type(const struct lyd_node
*plist_dnode
,
141 char *errmsg
, size_t errmsg_len
)
145 af_type
= yang_dnode_get_enum(plist_dnode
, "./type");
146 if (af_type
!= YPLT_IPV6
) {
147 snprintf(errmsg
, errmsg_len
,
148 "prefix-list type %u is mismatched.", af_type
);
149 return NB_ERR_VALIDATION
;
155 static int lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
156 struct nb_cb_modify_args
*args
)
158 struct prefix_list_entry
*ple
;
160 if (args
->event
!= NB_EV_APPLY
)
163 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
165 /* Start prefix entry update procedure. */
166 prefix_list_entry_update_start(ple
);
168 ple
->ge
= yang_dnode_get_uint8(args
->dnode
, NULL
);
170 /* Finish prefix entry update procedure. */
171 prefix_list_entry_update_finish(ple
);
176 static int lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
177 struct nb_cb_modify_args
*args
)
179 struct prefix_list_entry
*ple
;
181 if (args
->event
!= NB_EV_APPLY
)
184 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
186 /* Start prefix entry update procedure. */
187 prefix_list_entry_update_start(ple
);
189 ple
->le
= yang_dnode_get_uint8(args
->dnode
, NULL
);
191 /* Finish prefix entry update procedure. */
192 prefix_list_entry_update_finish(ple
);
197 static int lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
198 struct nb_cb_destroy_args
*args
)
200 struct prefix_list_entry
*ple
;
202 if (args
->event
!= NB_EV_APPLY
)
205 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
207 /* Start prefix entry update procedure. */
208 prefix_list_entry_update_start(ple
);
212 /* Finish prefix entry update procedure. */
213 prefix_list_entry_update_finish(ple
);
218 static int lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
219 struct nb_cb_destroy_args
*args
)
221 struct prefix_list_entry
*ple
;
223 if (args
->event
!= NB_EV_APPLY
)
226 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
228 /* Start prefix entry update procedure. */
229 prefix_list_entry_update_start(ple
);
233 /* Finish prefix entry update procedure. */
234 prefix_list_entry_update_finish(ple
);
240 * Unsets the cisco style rule for addresses so it becomes disabled (the
241 * equivalent of setting: `0.0.0.0/32`).
243 * \param addr address part.
244 * \param mask mask part.
246 static void cisco_unset_addr_mask(struct in_addr
*addr
, struct in_addr
*mask
)
248 addr
->s_addr
= INADDR_ANY
;
249 mask
->s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
252 static int _acl_is_dup(const struct lyd_node
*dnode
, void *arg
)
254 struct acl_dup_args
*ada
= arg
;
257 /* This entry is the caller, so skip it. */
258 if (ada
->ada_entry_dnode
259 && ada
->ada_entry_dnode
== dnode
)
260 return YANG_ITER_CONTINUE
;
262 if (strcmp(yang_dnode_get_string(dnode
, "action"), ada
->ada_action
))
263 return YANG_ITER_CONTINUE
;
265 /* Check if all values match. */
266 for (idx
= 0; idx
< ADA_MAX_VALUES
; idx
++) {
267 /* No more values. */
268 if (ada
->ada_xpath
[idx
] == NULL
)
271 /* Not same type, just skip it. */
272 if (!yang_dnode_exists(dnode
, ada
->ada_xpath
[idx
]))
273 return YANG_ITER_CONTINUE
;
275 /* Check if different value. */
276 if (strcmp(yang_dnode_get_string(dnode
, "%s",
277 ada
->ada_xpath
[idx
]),
278 ada
->ada_value
[idx
]))
279 return YANG_ITER_CONTINUE
;
282 ada
->ada_found
= true;
283 ada
->ada_seq
= yang_dnode_get_uint32(dnode
, "sequence");
285 return YANG_ITER_STOP
;
288 bool acl_is_dup(const struct lyd_node
*dnode
, struct acl_dup_args
*ada
)
290 ada
->ada_found
= false;
293 _acl_is_dup
, ada
, dnode
,
294 "/frr-filter:lib/access-list[type='%s'][name='%s']/entry",
295 ada
->ada_type
, ada
->ada_name
);
297 return ada
->ada_found
;
300 static bool acl_cisco_is_dup(const struct lyd_node
*dnode
)
302 const struct lyd_node
*entry_dnode
=
303 yang_dnode_get_parent(dnode
, "entry");
304 struct acl_dup_args ada
= {};
305 int idx
= 0, arg_idx
= 0;
306 static const char *cisco_entries
[] = {
311 "./destination-host",
312 "./destination-network/address",
313 "./destination-network/mask",
319 ada
.ada_type
= "ipv4";
320 ada
.ada_name
= yang_dnode_get_string(entry_dnode
, "../name");
321 ada
.ada_action
= yang_dnode_get_string(entry_dnode
, "action");
322 ada
.ada_entry_dnode
= entry_dnode
;
324 /* Load all values/XPaths. */
325 while (cisco_entries
[idx
] != NULL
) {
326 if (!yang_dnode_exists(entry_dnode
, cisco_entries
[idx
])) {
331 ada
.ada_xpath
[arg_idx
] = cisco_entries
[idx
];
332 ada
.ada_value
[arg_idx
] = yang_dnode_get_string(
333 entry_dnode
, "%s", cisco_entries
[idx
]);
338 return acl_is_dup(entry_dnode
, &ada
);
341 static bool acl_zebra_is_dup(const struct lyd_node
*dnode
,
342 enum yang_access_list_type type
)
344 const struct lyd_node
*entry_dnode
=
345 yang_dnode_get_parent(dnode
, "entry");
346 struct acl_dup_args ada
= {};
347 int idx
= 0, arg_idx
= 0;
348 static const char *zebra_entries
[] = {
350 "./ipv4-exact-match",
352 "./ipv6-exact-match",
361 ada
.ada_type
= "ipv4";
364 ada
.ada_type
= "ipv6";
367 ada
.ada_type
= "mac";
370 ada
.ada_name
= yang_dnode_get_string(entry_dnode
, "../name");
371 ada
.ada_action
= yang_dnode_get_string(entry_dnode
, "action");
372 ada
.ada_entry_dnode
= entry_dnode
;
374 /* Load all values/XPaths. */
375 while (zebra_entries
[idx
] != NULL
) {
376 if (!yang_dnode_exists(entry_dnode
, zebra_entries
[idx
])) {
381 ada
.ada_xpath
[arg_idx
] = zebra_entries
[idx
];
382 ada
.ada_value
[arg_idx
] = yang_dnode_get_string(
383 entry_dnode
, "%s", zebra_entries
[idx
]);
388 return acl_is_dup(entry_dnode
, &ada
);
391 static void plist_dnode_to_prefix(const struct lyd_node
*dnode
, bool *any
,
392 struct prefix
*p
, int *ge
, int *le
)
398 if (yang_dnode_exists(dnode
, "./any")) {
403 switch (yang_dnode_get_enum(dnode
, "../type")) {
405 yang_dnode_get_prefix(p
, dnode
, "./ipv4-prefix");
406 if (yang_dnode_exists(dnode
,
407 "./ipv4-prefix-length-greater-or-equal"))
408 *ge
= yang_dnode_get_uint8(
409 dnode
, "./ipv4-prefix-length-greater-or-equal");
410 if (yang_dnode_exists(dnode
,
411 "./ipv4-prefix-length-lesser-or-equal"))
412 *le
= yang_dnode_get_uint8(
413 dnode
, "./ipv4-prefix-length-lesser-or-equal");
416 yang_dnode_get_prefix(p
, dnode
, "./ipv6-prefix");
417 if (yang_dnode_exists(dnode
,
418 "./ipv6-prefix-length-greater-or-equal"))
419 *ge
= yang_dnode_get_uint8(
420 dnode
, "./ipv6-prefix-length-greater-or-equal");
421 if (yang_dnode_exists(dnode
,
422 "./ipv6-prefix-length-lesser-or-equal"))
423 *le
= yang_dnode_get_uint8(
424 dnode
, "./ipv6-prefix-length-lesser-or-equal");
429 static int _plist_is_dup(const struct lyd_node
*dnode
, void *arg
)
431 struct plist_dup_args
*pda
= arg
;
432 struct prefix p
= {};
436 /* This entry is the caller, so skip it. */
437 if (pda
->pda_entry_dnode
438 && pda
->pda_entry_dnode
== dnode
)
439 return YANG_ITER_CONTINUE
;
441 if (strcmp(yang_dnode_get_string(dnode
, "action"), pda
->pda_action
))
442 return YANG_ITER_CONTINUE
;
444 plist_dnode_to_prefix(dnode
, &any
, &p
, &ge
, &le
);
448 return YANG_ITER_CONTINUE
;
450 if (!prefix_same(&pda
->prefix
, &p
) || pda
->ge
!= ge
452 return YANG_ITER_CONTINUE
;
455 pda
->pda_found
= true;
456 pda
->pda_seq
= yang_dnode_get_uint32(dnode
, "sequence");
458 return YANG_ITER_STOP
;
461 bool plist_is_dup(const struct lyd_node
*dnode
, struct plist_dup_args
*pda
)
463 pda
->pda_found
= false;
466 _plist_is_dup
, pda
, dnode
,
467 "/frr-filter:lib/prefix-list[type='%s'][name='%s']/entry",
468 pda
->pda_type
, pda
->pda_name
);
470 return pda
->pda_found
;
473 static bool plist_is_dup_nb(const struct lyd_node
*dnode
)
475 const struct lyd_node
*entry_dnode
=
476 yang_dnode_get_parent(dnode
, "entry");
477 struct plist_dup_args pda
= {};
480 pda
.pda_type
= yang_dnode_get_string(entry_dnode
, "../type");
481 pda
.pda_name
= yang_dnode_get_string(entry_dnode
, "../name");
482 pda
.pda_action
= yang_dnode_get_string(entry_dnode
, "action");
483 pda
.pda_entry_dnode
= entry_dnode
;
485 plist_dnode_to_prefix(entry_dnode
, &pda
.any
, &pda
.prefix
, &pda
.ge
,
488 return plist_is_dup(entry_dnode
, &pda
);
492 * XPath: /frr-filter:lib/access-list
494 static int lib_access_list_create(struct nb_cb_create_args
*args
)
496 struct access_list
*acl
= NULL
;
497 const char *acl_name
;
500 if (args
->event
!= NB_EV_APPLY
)
503 type
= yang_dnode_get_enum(args
->dnode
, "./type");
504 acl_name
= yang_dnode_get_string(args
->dnode
, "./name");
508 acl
= access_list_get(AFI_IP
, acl_name
);
511 acl
= access_list_get(AFI_IP6
, acl_name
);
514 acl
= access_list_get(AFI_L2VPN
, acl_name
);
518 nb_running_set_entry(args
->dnode
, acl
);
523 static int lib_access_list_destroy(struct nb_cb_destroy_args
*args
)
525 struct access_list
*acl
;
527 if (args
->event
!= NB_EV_APPLY
)
530 acl
= nb_running_unset_entry(args
->dnode
);
531 access_list_delete(acl
);
537 * XPath: /frr-filter:lib/access-list/remark
539 static int lib_access_list_remark_modify(struct nb_cb_modify_args
*args
)
541 struct access_list
*acl
;
544 if (args
->event
!= NB_EV_APPLY
)
547 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
549 XFREE(MTYPE_TMP
, acl
->remark
);
551 remark
= yang_dnode_get_string(args
->dnode
, NULL
);
552 acl
->remark
= XSTRDUP(MTYPE_TMP
, remark
);
558 lib_access_list_remark_destroy(struct nb_cb_destroy_args
*args
)
560 struct access_list
*acl
;
562 if (args
->event
!= NB_EV_APPLY
)
565 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
567 XFREE(MTYPE_TMP
, acl
->remark
);
574 * XPath: /frr-filter:lib/access-list/entry
576 static int lib_access_list_entry_create(struct nb_cb_create_args
*args
)
578 struct access_list
*acl
;
581 if (args
->event
!= NB_EV_APPLY
)
585 f
->seq
= yang_dnode_get_uint32(args
->dnode
, "./sequence");
587 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
589 access_list_filter_add(acl
, f
);
590 nb_running_set_entry(args
->dnode
, f
);
595 static int lib_access_list_entry_destroy(struct nb_cb_destroy_args
*args
)
597 struct access_list
*acl
;
600 if (args
->event
!= NB_EV_APPLY
)
603 f
= nb_running_unset_entry(args
->dnode
);
605 access_list_filter_delete(acl
, f
);
611 * XPath: /frr-filter:lib/access-list/entry/action
614 lib_access_list_entry_action_modify(struct nb_cb_modify_args
*args
)
616 const char *filter_type
;
619 if (args
->event
!= NB_EV_APPLY
)
622 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
623 filter_type
= yang_dnode_get_string(args
->dnode
, NULL
);
624 if (strcmp(filter_type
, "permit") == 0)
625 f
->type
= FILTER_PERMIT
;
627 f
->type
= FILTER_DENY
;
629 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
635 * XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
638 lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args
*args
)
640 struct filter_zebra
*fz
;
643 /* Don't allow duplicated values. */
644 if (args
->event
== NB_EV_VALIDATE
) {
645 if (acl_zebra_is_dup(
647 yang_dnode_get_enum(args
->dnode
, "../../type"))) {
648 snprintfrr(args
->errmsg
, args
->errmsg_len
,
649 "duplicated access list value: %s",
650 yang_dnode_get_string(args
->dnode
, NULL
));
651 return NB_ERR_VALIDATION
;
656 if (args
->event
!= NB_EV_APPLY
)
659 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
662 yang_dnode_get_prefix(&fz
->prefix
, args
->dnode
, NULL
);
664 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
670 lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args
*args
)
672 struct filter_zebra
*fz
;
675 if (args
->event
!= NB_EV_APPLY
)
678 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
680 memset(&fz
->prefix
, 0, sizeof(fz
->prefix
));
682 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
688 * XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
691 lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args
*args
)
693 struct filter_zebra
*fz
;
696 /* Don't allow duplicated values. */
697 if (args
->event
== NB_EV_VALIDATE
) {
698 if (acl_zebra_is_dup(
700 yang_dnode_get_enum(args
->dnode
, "../../type"))) {
701 snprintfrr(args
->errmsg
, args
->errmsg_len
,
702 "duplicated access list value: %s",
703 yang_dnode_get_string(args
->dnode
, NULL
));
704 return NB_ERR_VALIDATION
;
709 if (args
->event
!= NB_EV_APPLY
)
712 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
714 fz
->exact
= yang_dnode_get_bool(args
->dnode
, NULL
);
716 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
722 lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args
*args
)
724 struct filter_zebra
*fz
;
727 if (args
->event
!= NB_EV_APPLY
)
730 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
734 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
740 * XPath: /frr-filter:lib/access-list/entry/host
743 lib_access_list_entry_host_modify(struct nb_cb_modify_args
*args
)
745 struct filter_cisco
*fc
;
748 /* Don't allow duplicated values. */
749 if (args
->event
== NB_EV_VALIDATE
) {
750 if (acl_cisco_is_dup(args
->dnode
)) {
751 snprintfrr(args
->errmsg
, args
->errmsg_len
,
752 "duplicated access list value: %s",
753 yang_dnode_get_string(args
->dnode
, NULL
));
754 return NB_ERR_VALIDATION
;
759 if (args
->event
!= NB_EV_APPLY
)
762 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
765 yang_dnode_get_ipv4(&fc
->addr
, args
->dnode
, NULL
);
766 fc
->addr_mask
.s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
768 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
774 lib_access_list_entry_host_destroy(struct nb_cb_destroy_args
*args
)
776 struct filter_cisco
*fc
;
779 if (args
->event
!= NB_EV_APPLY
)
782 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
784 cisco_unset_addr_mask(&fc
->addr
, &fc
->addr_mask
);
786 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
792 * XPath: /frr-filter:lib/access-list/entry/network/address
795 lib_access_list_entry_network_address_modify(struct nb_cb_modify_args
*args
)
797 struct filter_cisco
*fc
;
800 /* Don't allow duplicated values. */
801 if (args
->event
== NB_EV_VALIDATE
) {
802 if (acl_cisco_is_dup(args
->dnode
)) {
803 snprintfrr(args
->errmsg
, args
->errmsg_len
,
804 "duplicated access list value: %s",
805 yang_dnode_get_string(args
->dnode
, NULL
));
806 return NB_ERR_VALIDATION
;
811 if (args
->event
!= NB_EV_APPLY
)
814 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
817 yang_dnode_get_ipv4(&fc
->addr
, args
->dnode
, NULL
);
819 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
825 * XPath: /frr-filter:lib/access-list/entry/network/mask
828 lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args
*args
)
830 struct filter_cisco
*fc
;
833 /* Don't allow duplicated values. */
834 if (args
->event
== NB_EV_VALIDATE
) {
835 if (acl_cisco_is_dup(args
->dnode
)) {
836 snprintfrr(args
->errmsg
, args
->errmsg_len
,
837 "duplicated access list value: %s",
838 yang_dnode_get_string(args
->dnode
, NULL
));
839 return NB_ERR_VALIDATION
;
844 if (args
->event
!= NB_EV_APPLY
)
847 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
850 yang_dnode_get_ipv4(&fc
->addr_mask
, args
->dnode
, NULL
);
852 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
858 * XPath: /frr-filter:lib/access-list/entry/source-any
861 lib_access_list_entry_source_any_create(struct nb_cb_create_args
*args
)
863 struct filter_cisco
*fc
;
866 /* Don't allow duplicated values. */
867 if (args
->event
== NB_EV_VALIDATE
) {
868 if (acl_cisco_is_dup(args
->dnode
)) {
869 snprintfrr(args
->errmsg
, args
->errmsg_len
,
870 "duplicated access list value: %s",
871 yang_dnode_get_string(args
->dnode
, NULL
));
872 return NB_ERR_VALIDATION
;
877 if (args
->event
!= NB_EV_APPLY
)
880 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
883 fc
->addr
.s_addr
= INADDR_ANY
;
884 fc
->addr_mask
.s_addr
= CISCO_BIN_ANY_WILDCARD_MASK
;
886 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
892 lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args
*args
)
894 struct filter_cisco
*fc
;
897 if (args
->event
!= NB_EV_APPLY
)
900 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
902 cisco_unset_addr_mask(&fc
->addr
, &fc
->addr_mask
);
904 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
910 * XPath: /frr-filter:lib/access-list/entry/destination-host
912 static int lib_access_list_entry_destination_host_modify(
913 struct nb_cb_modify_args
*args
)
915 struct filter_cisco
*fc
;
918 /* Don't allow duplicated values. */
919 if (args
->event
== NB_EV_VALIDATE
) {
920 if (acl_cisco_is_dup(args
->dnode
)) {
921 snprintfrr(args
->errmsg
, args
->errmsg_len
,
922 "duplicated access list value: %s",
923 yang_dnode_get_string(args
->dnode
, NULL
));
924 return NB_ERR_VALIDATION
;
929 if (args
->event
!= NB_EV_APPLY
)
932 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
935 yang_dnode_get_ipv4(&fc
->mask
, args
->dnode
, NULL
);
936 fc
->mask_mask
.s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
938 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
943 static int lib_access_list_entry_destination_host_destroy(
944 struct nb_cb_destroy_args
*args
)
946 struct filter_cisco
*fc
;
949 if (args
->event
!= NB_EV_APPLY
)
952 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
955 cisco_unset_addr_mask(&fc
->mask
, &fc
->mask_mask
);
957 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
963 * XPath: /frr-filter:lib/access-list/entry/destination-network/address
965 static int lib_access_list_entry_destination_network_address_modify(
966 struct nb_cb_modify_args
*args
)
968 struct filter_cisco
*fc
;
971 /* Don't allow duplicated values. */
972 if (args
->event
== NB_EV_VALIDATE
) {
973 if (acl_cisco_is_dup(args
->dnode
)) {
974 snprintfrr(args
->errmsg
, args
->errmsg_len
,
975 "duplicated access list value: %s",
976 yang_dnode_get_string(args
->dnode
, NULL
));
977 return NB_ERR_VALIDATION
;
982 if (args
->event
!= NB_EV_APPLY
)
985 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
988 yang_dnode_get_ipv4(&fc
->mask
, args
->dnode
, NULL
);
990 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
996 * XPath: /frr-filter:lib/access-list/entry/destination-network/mask
998 static int lib_access_list_entry_destination_network_mask_modify(
999 struct nb_cb_modify_args
*args
)
1001 struct filter_cisco
*fc
;
1004 /* Don't allow duplicated values. */
1005 if (args
->event
== NB_EV_VALIDATE
) {
1006 if (acl_cisco_is_dup(args
->dnode
)) {
1007 snprintfrr(args
->errmsg
, args
->errmsg_len
,
1008 "duplicated access list value: %s",
1009 yang_dnode_get_string(args
->dnode
, NULL
));
1010 return NB_ERR_VALIDATION
;
1015 if (args
->event
!= NB_EV_APPLY
)
1018 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1021 yang_dnode_get_ipv4(&fc
->mask_mask
, args
->dnode
, NULL
);
1023 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1029 * XPath: /frr-filter:lib/access-list/entry/destination-any
1031 static int lib_access_list_entry_destination_any_create(
1032 struct nb_cb_create_args
*args
)
1034 struct filter_cisco
*fc
;
1037 /* Don't allow duplicated values. */
1038 if (args
->event
== NB_EV_VALIDATE
) {
1039 if (acl_cisco_is_dup(args
->dnode
)) {
1040 snprintfrr(args
->errmsg
, args
->errmsg_len
,
1041 "duplicated access list value: %s",
1042 yang_dnode_get_string(args
->dnode
, NULL
));
1043 return NB_ERR_VALIDATION
;
1048 if (args
->event
!= NB_EV_APPLY
)
1051 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1054 fc
->mask
.s_addr
= INADDR_ANY
;
1055 fc
->mask_mask
.s_addr
= CISCO_BIN_ANY_WILDCARD_MASK
;
1057 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1062 static int lib_access_list_entry_destination_any_destroy(
1063 struct nb_cb_destroy_args
*args
)
1065 struct filter_cisco
*fc
;
1068 if (args
->event
!= NB_EV_APPLY
)
1071 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1074 cisco_unset_addr_mask(&fc
->mask
, &fc
->mask_mask
);
1076 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
1082 * XPath: /frr-filter:lib/access-list/entry/any
1084 static int lib_access_list_entry_any_create(struct nb_cb_create_args
*args
)
1086 struct filter_zebra
*fz
;
1090 /* Don't allow duplicated values. */
1091 if (args
->event
== NB_EV_VALIDATE
) {
1092 if (acl_zebra_is_dup(
1094 yang_dnode_get_enum(args
->dnode
, "../../type"))) {
1095 snprintfrr(args
->errmsg
, args
->errmsg_len
,
1096 "duplicated access list value: %s",
1097 yang_dnode_get_string(args
->dnode
, NULL
));
1098 return NB_ERR_VALIDATION
;
1103 if (args
->event
!= NB_EV_APPLY
)
1106 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1109 memset(&fz
->prefix
, 0, sizeof(fz
->prefix
));
1111 type
= yang_dnode_get_enum(args
->dnode
, "../../type");
1114 fz
->prefix
.family
= AF_INET
;
1117 fz
->prefix
.family
= AF_INET6
;
1120 fz
->prefix
.family
= AF_ETHERNET
;
1124 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1129 static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args
*args
)
1131 struct filter_zebra
*fz
;
1134 if (args
->event
!= NB_EV_APPLY
)
1137 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1139 fz
->prefix
.family
= AF_UNSPEC
;
1141 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
1147 * XPath: /frr-filter:lib/prefix-list
1149 static int lib_prefix_list_create(struct nb_cb_create_args
*args
)
1151 struct prefix_list
*pl
= NULL
;
1155 if (args
->event
!= NB_EV_APPLY
)
1158 type
= yang_dnode_get_enum(args
->dnode
, "./type");
1159 name
= yang_dnode_get_string(args
->dnode
, "./name");
1162 pl
= prefix_list_get(AFI_IP
, 0, name
);
1165 pl
= prefix_list_get(AFI_IP6
, 0, name
);
1169 nb_running_set_entry(args
->dnode
, pl
);
1174 static int lib_prefix_list_destroy(struct nb_cb_destroy_args
*args
)
1176 struct prefix_list
*pl
;
1178 if (args
->event
!= NB_EV_APPLY
)
1181 pl
= nb_running_unset_entry(args
->dnode
);
1182 prefix_list_delete(pl
);
1188 * XPath: /frr-filter:lib/prefix-list/remark
1190 static int lib_prefix_list_remark_modify(struct nb_cb_modify_args
*args
)
1192 struct prefix_list
*pl
;
1195 if (args
->event
!= NB_EV_APPLY
)
1198 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1200 XFREE(MTYPE_TMP
, pl
->desc
);
1202 remark
= yang_dnode_get_string(args
->dnode
, NULL
);
1203 pl
->desc
= XSTRDUP(MTYPE_TMP
, remark
);
1208 static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args
*args
)
1210 struct prefix_list
*pl
;
1212 if (args
->event
!= NB_EV_APPLY
)
1215 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1217 XFREE(MTYPE_TMP
, pl
->desc
);
1223 * XPath: /frr-filter:lib/prefix-list/entry
1225 static int lib_prefix_list_entry_create(struct nb_cb_create_args
*args
)
1227 struct prefix_list_entry
*ple
;
1228 struct prefix_list
*pl
;
1230 if (args
->event
!= NB_EV_APPLY
)
1233 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1234 ple
= prefix_list_entry_new();
1236 ple
->seq
= yang_dnode_get_uint32(args
->dnode
, "./sequence");
1237 prefix_list_entry_set_empty(ple
);
1238 nb_running_set_entry(args
->dnode
, ple
);
1243 static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args
*args
)
1245 struct prefix_list_entry
*ple
;
1247 if (args
->event
!= NB_EV_APPLY
)
1250 ple
= nb_running_unset_entry(args
->dnode
);
1252 prefix_list_entry_delete2(ple
);
1254 prefix_list_entry_free(ple
);
1260 * XPath: /frr-filter:lib/prefix-list/entry/action
1262 static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args
*args
)
1264 struct prefix_list_entry
*ple
;
1267 if (args
->event
!= NB_EV_APPLY
)
1270 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1272 /* Start prefix entry update procedure. */
1273 prefix_list_entry_update_start(ple
);
1275 action_type
= yang_dnode_get_enum(args
->dnode
, NULL
);
1276 if (action_type
== YPLA_PERMIT
)
1277 ple
->type
= PREFIX_PERMIT
;
1279 ple
->type
= PREFIX_DENY
;
1281 /* Finish prefix entry update procedure. */
1282 prefix_list_entry_update_finish(ple
);
1287 static int lib_prefix_list_entry_prefix_modify(struct nb_cb_modify_args
*args
)
1289 struct prefix_list_entry
*ple
;
1292 if (args
->event
!= NB_EV_APPLY
)
1295 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1297 /* Start prefix entry update procedure. */
1298 prefix_list_entry_update_start(ple
);
1300 yang_dnode_get_prefix(&ple
->prefix
, args
->dnode
, NULL
);
1302 /* Apply mask and correct original address if necessary. */
1303 prefix_copy(&p
, &ple
->prefix
);
1305 if (!prefix_same(&ple
->prefix
, &p
)) {
1306 zlog_info("%s: bad network %pFX correcting it to %pFX",
1307 __func__
, &ple
->prefix
, &p
);
1308 prefix_copy(&ple
->prefix
, &p
);
1312 /* Finish prefix entry update procedure. */
1313 prefix_list_entry_update_finish(ple
);
1318 static int lib_prefix_list_entry_prefix_destroy(struct nb_cb_destroy_args
*args
)
1320 struct prefix_list_entry
*ple
;
1322 if (args
->event
!= NB_EV_APPLY
)
1325 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1327 /* Start prefix entry update procedure. */
1328 prefix_list_entry_update_start(ple
);
1330 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
1332 /* Finish prefix entry update procedure. */
1333 prefix_list_entry_update_finish(ple
);
1339 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
1342 lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args
*args
)
1344 if (args
->event
== NB_EV_VALIDATE
) {
1345 const struct lyd_node
*plist_dnode
=
1346 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1348 if (plist_is_dup_nb(args
->dnode
)) {
1349 snprintf(args
->errmsg
, args
->errmsg_len
,
1350 "duplicated prefix list value: %s",
1351 yang_dnode_get_string(args
->dnode
, NULL
));
1352 return NB_ERR_VALIDATION
;
1355 return prefix_list_nb_validate_v4_af_type(
1356 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1359 return lib_prefix_list_entry_prefix_modify(args
);
1363 lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args
*args
)
1366 if (args
->event
!= NB_EV_APPLY
)
1369 return lib_prefix_list_entry_prefix_destroy(args
);
1373 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix
1376 lib_prefix_list_entry_ipv6_prefix_modify(struct nb_cb_modify_args
*args
)
1379 if (args
->event
== NB_EV_VALIDATE
) {
1380 const struct lyd_node
*plist_dnode
=
1381 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1383 if (plist_is_dup_nb(args
->dnode
)) {
1384 snprintf(args
->errmsg
, args
->errmsg_len
,
1385 "duplicated prefix list value: %s",
1386 yang_dnode_get_string(args
->dnode
, NULL
));
1387 return NB_ERR_VALIDATION
;
1390 return prefix_list_nb_validate_v6_af_type(
1391 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1394 return lib_prefix_list_entry_prefix_modify(args
);
1398 lib_prefix_list_entry_ipv6_prefix_destroy(struct nb_cb_destroy_args
*args
)
1401 if (args
->event
!= NB_EV_APPLY
)
1404 return lib_prefix_list_entry_prefix_destroy(args
);
1408 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
1410 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
1411 struct nb_cb_modify_args
*args
)
1413 if (args
->event
== NB_EV_VALIDATE
1414 && prefix_list_length_validate(args
) != NB_OK
)
1415 return NB_ERR_VALIDATION
;
1417 if (args
->event
== NB_EV_VALIDATE
) {
1418 const struct lyd_node
*plist_dnode
=
1419 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1421 if (plist_is_dup_nb(args
->dnode
)) {
1422 snprintf(args
->errmsg
, args
->errmsg_len
,
1423 "duplicated prefix list value: %s",
1424 yang_dnode_get_string(args
->dnode
, NULL
));
1425 return NB_ERR_VALIDATION
;
1428 return prefix_list_nb_validate_v4_af_type(
1429 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1432 return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
1436 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
1437 struct nb_cb_destroy_args
*args
)
1439 if (args
->event
== NB_EV_VALIDATE
) {
1440 const struct lyd_node
*plist_dnode
=
1441 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1443 return prefix_list_nb_validate_v4_af_type(
1444 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1447 return lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
1452 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
1454 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
1455 struct nb_cb_modify_args
*args
)
1457 if (args
->event
== NB_EV_VALIDATE
1458 && prefix_list_length_validate(args
) != NB_OK
)
1459 return NB_ERR_VALIDATION
;
1461 if (args
->event
== NB_EV_VALIDATE
) {
1462 const struct lyd_node
*plist_dnode
=
1463 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1465 if (plist_is_dup_nb(args
->dnode
)) {
1466 snprintf(args
->errmsg
, args
->errmsg_len
,
1467 "duplicated prefix list value: %s",
1468 yang_dnode_get_string(args
->dnode
, NULL
));
1469 return NB_ERR_VALIDATION
;
1472 return prefix_list_nb_validate_v4_af_type(
1473 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1476 return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
1480 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
1481 struct nb_cb_destroy_args
*args
)
1483 if (args
->event
== NB_EV_VALIDATE
) {
1484 const struct lyd_node
*plist_dnode
=
1485 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1487 return prefix_list_nb_validate_v4_af_type(
1488 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1491 return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
1496 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal
1498 static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify(
1499 struct nb_cb_modify_args
*args
)
1501 if (args
->event
== NB_EV_VALIDATE
1502 && prefix_list_length_validate(args
) != NB_OK
)
1503 return NB_ERR_VALIDATION
;
1505 if (args
->event
== NB_EV_VALIDATE
) {
1506 const struct lyd_node
*plist_dnode
=
1507 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1509 if (plist_is_dup_nb(args
->dnode
)) {
1510 snprintf(args
->errmsg
, args
->errmsg_len
,
1511 "duplicated prefix list value: %s",
1512 yang_dnode_get_string(args
->dnode
, NULL
));
1513 return NB_ERR_VALIDATION
;
1516 return prefix_list_nb_validate_v6_af_type(
1517 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1520 return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
1524 static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_destroy(
1525 struct nb_cb_destroy_args
*args
)
1527 if (args
->event
== NB_EV_VALIDATE
) {
1528 const struct lyd_node
*plist_dnode
=
1529 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1531 return prefix_list_nb_validate_v6_af_type(
1532 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1535 return lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
1540 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal
1542 static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_modify(
1543 struct nb_cb_modify_args
*args
)
1545 if (args
->event
== NB_EV_VALIDATE
1546 && prefix_list_length_validate(args
) != NB_OK
)
1547 return NB_ERR_VALIDATION
;
1549 if (args
->event
== NB_EV_VALIDATE
) {
1550 const struct lyd_node
*plist_dnode
=
1551 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1553 if (plist_is_dup_nb(args
->dnode
)) {
1554 snprintf(args
->errmsg
, args
->errmsg_len
,
1555 "duplicated prefix list value: %s",
1556 yang_dnode_get_string(args
->dnode
, NULL
));
1557 return NB_ERR_VALIDATION
;
1560 return prefix_list_nb_validate_v6_af_type(
1561 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1564 return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
1568 static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_destroy(
1569 struct nb_cb_destroy_args
*args
)
1571 if (args
->event
== NB_EV_VALIDATE
) {
1572 const struct lyd_node
*plist_dnode
=
1573 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1575 return prefix_list_nb_validate_v6_af_type(
1576 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1579 return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
1584 * XPath: /frr-filter:lib/prefix-list/entry/any
1586 static int lib_prefix_list_entry_any_create(struct nb_cb_create_args
*args
)
1588 struct prefix_list_entry
*ple
;
1591 if (args
->event
== NB_EV_VALIDATE
) {
1592 if (plist_is_dup_nb(args
->dnode
)) {
1593 snprintf(args
->errmsg
, args
->errmsg_len
,
1594 "duplicated prefix list value: %s",
1595 yang_dnode_get_string(args
->dnode
, NULL
));
1596 return NB_ERR_VALIDATION
;
1602 if (args
->event
!= NB_EV_APPLY
)
1605 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1607 /* Start prefix entry update procedure. */
1608 prefix_list_entry_update_start(ple
);
1612 /* Fill prefix struct from scratch. */
1613 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
1615 type
= yang_dnode_get_enum(args
->dnode
, "../../type");
1618 ple
->prefix
.family
= AF_INET
;
1620 ple
->le
= IPV4_MAX_BITLEN
;
1623 ple
->prefix
.family
= AF_INET6
;
1625 ple
->le
= IPV6_MAX_BITLEN
;
1629 /* Finish prefix entry update procedure. */
1630 prefix_list_entry_update_finish(ple
);
1635 static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args
*args
)
1637 struct prefix_list_entry
*ple
;
1639 if (args
->event
!= NB_EV_APPLY
)
1642 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1644 /* Start prefix entry update procedure. */
1645 prefix_list_entry_update_start(ple
);
1647 prefix_list_entry_set_empty(ple
);
1649 /* Finish prefix entry update procedure. */
1650 prefix_list_entry_update_finish(ple
);
1655 /* clang-format off */
1656 const struct frr_yang_module_info frr_filter_info
= {
1657 .name
= "frr-filter",
1660 .xpath
= "/frr-filter:lib/access-list",
1662 .create
= lib_access_list_create
,
1663 .destroy
= lib_access_list_destroy
,
1667 .xpath
= "/frr-filter:lib/access-list/remark",
1669 .modify
= lib_access_list_remark_modify
,
1670 .destroy
= lib_access_list_remark_destroy
,
1671 .cli_show
= access_list_remark_show
,
1675 .xpath
= "/frr-filter:lib/access-list/entry",
1677 .create
= lib_access_list_entry_create
,
1678 .destroy
= lib_access_list_entry_destroy
,
1679 .cli_cmp
= access_list_cmp
,
1680 .cli_show
= access_list_show
,
1684 .xpath
= "/frr-filter:lib/access-list/entry/action",
1686 .modify
= lib_access_list_entry_action_modify
,
1690 .xpath
= "/frr-filter:lib/access-list/entry/ipv4-prefix",
1692 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1693 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1697 .xpath
= "/frr-filter:lib/access-list/entry/ipv4-exact-match",
1699 .modify
= lib_access_list_entry_ipv4_exact_match_modify
,
1700 .destroy
= lib_access_list_entry_ipv4_exact_match_destroy
,
1704 .xpath
= "/frr-filter:lib/access-list/entry/host",
1706 .modify
= lib_access_list_entry_host_modify
,
1707 .destroy
= lib_access_list_entry_host_destroy
,
1711 .xpath
= "/frr-filter:lib/access-list/entry/network/address",
1713 .modify
= lib_access_list_entry_network_address_modify
,
1717 .xpath
= "/frr-filter:lib/access-list/entry/network/mask",
1719 .modify
= lib_access_list_entry_network_mask_modify
,
1723 .xpath
= "/frr-filter:lib/access-list/entry/source-any",
1725 .create
= lib_access_list_entry_source_any_create
,
1726 .destroy
= lib_access_list_entry_source_any_destroy
,
1730 .xpath
= "/frr-filter:lib/access-list/entry/destination-host",
1732 .modify
= lib_access_list_entry_destination_host_modify
,
1733 .destroy
= lib_access_list_entry_destination_host_destroy
,
1737 .xpath
= "/frr-filter:lib/access-list/entry/destination-network/address",
1739 .modify
= lib_access_list_entry_destination_network_address_modify
,
1743 .xpath
= "/frr-filter:lib/access-list/entry/destination-network/mask",
1745 .modify
= lib_access_list_entry_destination_network_mask_modify
,
1749 .xpath
= "/frr-filter:lib/access-list/entry/destination-any",
1751 .create
= lib_access_list_entry_destination_any_create
,
1752 .destroy
= lib_access_list_entry_destination_any_destroy
,
1756 .xpath
= "/frr-filter:lib/access-list/entry/ipv6-prefix",
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/ipv6-exact-match",
1765 .modify
= lib_access_list_entry_ipv4_exact_match_modify
,
1766 .destroy
= lib_access_list_entry_ipv4_exact_match_destroy
,
1770 .xpath
= "/frr-filter:lib/access-list/entry/mac",
1772 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1773 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1777 .xpath
= "/frr-filter:lib/access-list/entry/any",
1779 .create
= lib_access_list_entry_any_create
,
1780 .destroy
= lib_access_list_entry_any_destroy
,
1784 .xpath
= "/frr-filter:lib/prefix-list",
1786 .create
= lib_prefix_list_create
,
1787 .destroy
= lib_prefix_list_destroy
,
1791 .xpath
= "/frr-filter:lib/prefix-list/remark",
1793 .modify
= lib_prefix_list_remark_modify
,
1794 .destroy
= lib_prefix_list_remark_destroy
,
1795 .cli_show
= prefix_list_remark_show
,
1799 .xpath
= "/frr-filter:lib/prefix-list/entry",
1801 .create
= lib_prefix_list_entry_create
,
1802 .destroy
= lib_prefix_list_entry_destroy
,
1803 .cli_cmp
= prefix_list_cmp
,
1804 .cli_show
= prefix_list_show
,
1808 .xpath
= "/frr-filter:lib/prefix-list/entry/action",
1810 .modify
= lib_prefix_list_entry_action_modify
,
1814 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
1816 .modify
= lib_prefix_list_entry_ipv4_prefix_modify
,
1817 .destroy
= lib_prefix_list_entry_ipv4_prefix_destroy
,
1821 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
1823 .modify
= lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify
,
1824 .destroy
= lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy
,
1828 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
1830 .modify
= lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify
,
1831 .destroy
= lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy
,
1835 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
1837 .modify
= lib_prefix_list_entry_ipv6_prefix_modify
,
1838 .destroy
= lib_prefix_list_entry_ipv6_prefix_destroy
,
1842 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
1844 .modify
= lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify
,
1845 .destroy
= lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_destroy
,
1849 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
1851 .modify
= lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_modify
,
1852 .destroy
= lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_destroy
,
1856 .xpath
= "/frr-filter:lib/prefix-list/entry/any",
1858 .create
= lib_prefix_list_entry_any_create
,
1859 .destroy
= lib_prefix_list_entry_any_destroy
,