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
, xpath_le
);
80 * prefix length <= ge.
82 if (yang_dnode_exists(args
->dnode
, xpath_ge
)) {
83 ge
= yang_dnode_get_uint8(args
->dnode
, 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
, xpath_le
);
95 ge
= yang_dnode_get_uint8(args
->dnode
, 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
, ada
->ada_xpath
[idx
]),
277 ada
->ada_value
[idx
]))
278 return YANG_ITER_CONTINUE
;
281 ada
->ada_found
= true;
282 ada
->ada_seq
= yang_dnode_get_uint32(dnode
, "sequence");
284 return YANG_ITER_STOP
;
287 bool acl_is_dup(const struct lyd_node
*dnode
, struct acl_dup_args
*ada
)
289 ada
->ada_found
= false;
292 _acl_is_dup
, ada
, dnode
,
293 "/frr-filter:lib/access-list[type='%s'][name='%s']/entry",
294 ada
->ada_type
, ada
->ada_name
);
296 return ada
->ada_found
;
299 static bool acl_cisco_is_dup(const struct lyd_node
*dnode
)
301 const struct lyd_node
*entry_dnode
=
302 yang_dnode_get_parent(dnode
, "entry");
303 struct acl_dup_args ada
= {};
304 int idx
= 0, arg_idx
= 0;
305 static const char *cisco_entries
[] = {
310 "./destination-host",
311 "./destination-network/address",
312 "./destination-network/mask",
318 ada
.ada_type
= "ipv4";
319 ada
.ada_name
= yang_dnode_get_string(entry_dnode
, "../name");
320 ada
.ada_action
= yang_dnode_get_string(entry_dnode
, "action");
321 ada
.ada_entry_dnode
= entry_dnode
;
323 /* Load all values/XPaths. */
324 while (cisco_entries
[idx
] != NULL
) {
325 if (!yang_dnode_exists(entry_dnode
, cisco_entries
[idx
])) {
330 ada
.ada_xpath
[arg_idx
] = cisco_entries
[idx
];
331 ada
.ada_value
[arg_idx
] =
332 yang_dnode_get_string(entry_dnode
, cisco_entries
[idx
]);
337 return acl_is_dup(entry_dnode
, &ada
);
340 static bool acl_zebra_is_dup(const struct lyd_node
*dnode
,
341 enum yang_access_list_type type
)
343 const struct lyd_node
*entry_dnode
=
344 yang_dnode_get_parent(dnode
, "entry");
345 struct acl_dup_args ada
= {};
346 int idx
= 0, arg_idx
= 0;
347 static const char *zebra_entries
[] = {
349 "./ipv4-exact-match",
351 "./ipv6-exact-match",
360 ada
.ada_type
= "ipv4";
363 ada
.ada_type
= "ipv6";
366 ada
.ada_type
= "mac";
369 ada
.ada_name
= yang_dnode_get_string(entry_dnode
, "../name");
370 ada
.ada_action
= yang_dnode_get_string(entry_dnode
, "action");
371 ada
.ada_entry_dnode
= entry_dnode
;
373 /* Load all values/XPaths. */
374 while (zebra_entries
[idx
] != NULL
) {
375 if (!yang_dnode_exists(entry_dnode
, zebra_entries
[idx
])) {
380 ada
.ada_xpath
[arg_idx
] = zebra_entries
[idx
];
381 ada
.ada_value
[arg_idx
] =
382 yang_dnode_get_string(entry_dnode
, zebra_entries
[idx
]);
387 return acl_is_dup(entry_dnode
, &ada
);
390 static void plist_dnode_to_prefix(const struct lyd_node
*dnode
, bool *any
,
391 struct prefix
*p
, int *ge
, int *le
)
397 if (yang_dnode_exists(dnode
, "./any")) {
402 switch (yang_dnode_get_enum(dnode
, "../type")) {
404 yang_dnode_get_prefix(p
, dnode
, "./ipv4-prefix");
405 if (yang_dnode_exists(dnode
,
406 "./ipv4-prefix-length-greater-or-equal"))
407 *ge
= yang_dnode_get_uint8(
408 dnode
, "./ipv4-prefix-length-greater-or-equal");
409 if (yang_dnode_exists(dnode
,
410 "./ipv4-prefix-length-lesser-or-equal"))
411 *le
= yang_dnode_get_uint8(
412 dnode
, "./ipv4-prefix-length-lesser-or-equal");
415 yang_dnode_get_prefix(p
, dnode
, "./ipv6-prefix");
416 if (yang_dnode_exists(dnode
,
417 "./ipv6-prefix-length-greater-or-equal"))
418 *ge
= yang_dnode_get_uint8(
419 dnode
, "./ipv6-prefix-length-greater-or-equal");
420 if (yang_dnode_exists(dnode
,
421 "./ipv6-prefix-length-lesser-or-equal"))
422 *le
= yang_dnode_get_uint8(
423 dnode
, "./ipv6-prefix-length-lesser-or-equal");
428 static int _plist_is_dup(const struct lyd_node
*dnode
, void *arg
)
430 struct plist_dup_args
*pda
= arg
;
435 /* This entry is the caller, so skip it. */
436 if (pda
->pda_entry_dnode
437 && pda
->pda_entry_dnode
== dnode
)
438 return YANG_ITER_CONTINUE
;
440 if (strcmp(yang_dnode_get_string(dnode
, "action"), pda
->pda_action
))
441 return YANG_ITER_CONTINUE
;
443 plist_dnode_to_prefix(dnode
, &any
, &p
, &ge
, &le
);
447 return YANG_ITER_CONTINUE
;
449 if (!prefix_same(&pda
->prefix
, &p
) || pda
->ge
!= ge
451 return YANG_ITER_CONTINUE
;
454 pda
->pda_found
= true;
455 pda
->pda_seq
= yang_dnode_get_uint32(dnode
, "sequence");
457 return YANG_ITER_STOP
;
460 bool plist_is_dup(const struct lyd_node
*dnode
, struct plist_dup_args
*pda
)
462 pda
->pda_found
= false;
465 _plist_is_dup
, pda
, dnode
,
466 "/frr-filter:lib/prefix-list[type='%s'][name='%s']/entry",
467 pda
->pda_type
, pda
->pda_name
);
469 return pda
->pda_found
;
472 static bool plist_is_dup_nb(const struct lyd_node
*dnode
)
474 const struct lyd_node
*entry_dnode
=
475 yang_dnode_get_parent(dnode
, "entry");
476 struct plist_dup_args pda
= {};
479 pda
.pda_type
= yang_dnode_get_string(entry_dnode
, "../type");
480 pda
.pda_name
= yang_dnode_get_string(entry_dnode
, "../name");
481 pda
.pda_action
= yang_dnode_get_string(entry_dnode
, "action");
482 pda
.pda_entry_dnode
= entry_dnode
;
484 plist_dnode_to_prefix(entry_dnode
, &pda
.any
, &pda
.prefix
, &pda
.ge
,
487 return plist_is_dup(entry_dnode
, &pda
);
491 * XPath: /frr-filter:lib/access-list
493 static int lib_access_list_create(struct nb_cb_create_args
*args
)
495 struct access_list
*acl
= NULL
;
496 const char *acl_name
;
499 if (args
->event
!= NB_EV_APPLY
)
502 type
= yang_dnode_get_enum(args
->dnode
, "./type");
503 acl_name
= yang_dnode_get_string(args
->dnode
, "./name");
507 acl
= access_list_get(AFI_IP
, acl_name
);
510 acl
= access_list_get(AFI_IP6
, acl_name
);
513 acl
= access_list_get(AFI_L2VPN
, acl_name
);
517 nb_running_set_entry(args
->dnode
, acl
);
522 static int lib_access_list_destroy(struct nb_cb_destroy_args
*args
)
524 struct access_list
*acl
;
526 if (args
->event
!= NB_EV_APPLY
)
529 acl
= nb_running_unset_entry(args
->dnode
);
530 access_list_delete(acl
);
536 * XPath: /frr-filter:lib/access-list/remark
538 static int lib_access_list_remark_modify(struct nb_cb_modify_args
*args
)
540 struct access_list
*acl
;
543 if (args
->event
!= NB_EV_APPLY
)
546 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
548 XFREE(MTYPE_TMP
, acl
->remark
);
550 remark
= yang_dnode_get_string(args
->dnode
, NULL
);
551 acl
->remark
= XSTRDUP(MTYPE_TMP
, remark
);
557 lib_access_list_remark_destroy(struct nb_cb_destroy_args
*args
)
559 struct access_list
*acl
;
561 if (args
->event
!= NB_EV_APPLY
)
564 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
566 XFREE(MTYPE_TMP
, acl
->remark
);
573 * XPath: /frr-filter:lib/access-list/entry
575 static int lib_access_list_entry_create(struct nb_cb_create_args
*args
)
577 struct access_list
*acl
;
580 if (args
->event
!= NB_EV_APPLY
)
584 f
->seq
= yang_dnode_get_uint32(args
->dnode
, "./sequence");
586 acl
= nb_running_get_entry(args
->dnode
, NULL
, true);
588 access_list_filter_add(acl
, f
);
589 nb_running_set_entry(args
->dnode
, f
);
594 static int lib_access_list_entry_destroy(struct nb_cb_destroy_args
*args
)
596 struct access_list
*acl
;
599 if (args
->event
!= NB_EV_APPLY
)
602 f
= nb_running_unset_entry(args
->dnode
);
604 access_list_filter_delete(acl
, f
);
610 * XPath: /frr-filter:lib/access-list/entry/action
613 lib_access_list_entry_action_modify(struct nb_cb_modify_args
*args
)
615 const char *filter_type
;
618 if (args
->event
!= NB_EV_APPLY
)
621 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
622 filter_type
= yang_dnode_get_string(args
->dnode
, NULL
);
623 if (strcmp(filter_type
, "permit") == 0)
624 f
->type
= FILTER_PERMIT
;
626 f
->type
= FILTER_DENY
;
628 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
634 * XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
637 lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args
*args
)
639 struct filter_zebra
*fz
;
642 /* Don't allow duplicated values. */
643 if (args
->event
== NB_EV_VALIDATE
) {
644 if (acl_zebra_is_dup(
646 yang_dnode_get_enum(args
->dnode
, "../../type"))) {
647 snprintfrr(args
->errmsg
, args
->errmsg_len
,
648 "duplicated access list value: %s",
649 yang_dnode_get_string(args
->dnode
, NULL
));
650 return NB_ERR_VALIDATION
;
655 if (args
->event
!= NB_EV_APPLY
)
658 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
661 yang_dnode_get_prefix(&fz
->prefix
, args
->dnode
, NULL
);
663 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
669 lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args
*args
)
671 struct filter_zebra
*fz
;
674 if (args
->event
!= NB_EV_APPLY
)
677 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
679 memset(&fz
->prefix
, 0, sizeof(fz
->prefix
));
681 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
687 * XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
690 lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args
*args
)
692 struct filter_zebra
*fz
;
695 /* Don't allow duplicated values. */
696 if (args
->event
== NB_EV_VALIDATE
) {
697 if (acl_zebra_is_dup(
699 yang_dnode_get_enum(args
->dnode
, "../../type"))) {
700 snprintfrr(args
->errmsg
, args
->errmsg_len
,
701 "duplicated access list value: %s",
702 yang_dnode_get_string(args
->dnode
, NULL
));
703 return NB_ERR_VALIDATION
;
708 if (args
->event
!= NB_EV_APPLY
)
711 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
713 fz
->exact
= yang_dnode_get_bool(args
->dnode
, NULL
);
715 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
721 lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args
*args
)
723 struct filter_zebra
*fz
;
726 if (args
->event
!= NB_EV_APPLY
)
729 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
733 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
739 * XPath: /frr-filter:lib/access-list/entry/host
742 lib_access_list_entry_host_modify(struct nb_cb_modify_args
*args
)
744 struct filter_cisco
*fc
;
747 /* Don't allow duplicated values. */
748 if (args
->event
== NB_EV_VALIDATE
) {
749 if (acl_cisco_is_dup(args
->dnode
)) {
750 snprintfrr(args
->errmsg
, args
->errmsg_len
,
751 "duplicated access list value: %s",
752 yang_dnode_get_string(args
->dnode
, NULL
));
753 return NB_ERR_VALIDATION
;
758 if (args
->event
!= NB_EV_APPLY
)
761 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
764 yang_dnode_get_ipv4(&fc
->addr
, args
->dnode
, NULL
);
765 fc
->addr_mask
.s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
767 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
773 lib_access_list_entry_host_destroy(struct nb_cb_destroy_args
*args
)
775 struct filter_cisco
*fc
;
778 if (args
->event
!= NB_EV_APPLY
)
781 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
783 cisco_unset_addr_mask(&fc
->addr
, &fc
->addr_mask
);
785 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
791 * XPath: /frr-filter:lib/access-list/entry/network/address
794 lib_access_list_entry_network_address_modify(struct nb_cb_modify_args
*args
)
796 struct filter_cisco
*fc
;
799 /* Don't allow duplicated values. */
800 if (args
->event
== NB_EV_VALIDATE
) {
801 if (acl_cisco_is_dup(args
->dnode
)) {
802 snprintfrr(args
->errmsg
, args
->errmsg_len
,
803 "duplicated access list value: %s",
804 yang_dnode_get_string(args
->dnode
, NULL
));
805 return NB_ERR_VALIDATION
;
810 if (args
->event
!= NB_EV_APPLY
)
813 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
816 yang_dnode_get_ipv4(&fc
->addr
, args
->dnode
, NULL
);
818 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
824 * XPath: /frr-filter:lib/access-list/entry/network/mask
827 lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args
*args
)
829 struct filter_cisco
*fc
;
832 /* Don't allow duplicated values. */
833 if (args
->event
== NB_EV_VALIDATE
) {
834 if (acl_cisco_is_dup(args
->dnode
)) {
835 snprintfrr(args
->errmsg
, args
->errmsg_len
,
836 "duplicated access list value: %s",
837 yang_dnode_get_string(args
->dnode
, NULL
));
838 return NB_ERR_VALIDATION
;
843 if (args
->event
!= NB_EV_APPLY
)
846 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
849 yang_dnode_get_ipv4(&fc
->addr_mask
, args
->dnode
, NULL
);
851 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
857 * XPath: /frr-filter:lib/access-list/entry/source-any
860 lib_access_list_entry_source_any_create(struct nb_cb_create_args
*args
)
862 struct filter_cisco
*fc
;
865 /* Don't allow duplicated values. */
866 if (args
->event
== NB_EV_VALIDATE
) {
867 if (acl_cisco_is_dup(args
->dnode
)) {
868 snprintfrr(args
->errmsg
, args
->errmsg_len
,
869 "duplicated access list value: %s",
870 yang_dnode_get_string(args
->dnode
, NULL
));
871 return NB_ERR_VALIDATION
;
876 if (args
->event
!= NB_EV_APPLY
)
879 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
882 fc
->addr
.s_addr
= INADDR_ANY
;
883 fc
->addr_mask
.s_addr
= CISCO_BIN_ANY_WILDCARD_MASK
;
885 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
891 lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args
*args
)
893 struct filter_cisco
*fc
;
896 if (args
->event
!= NB_EV_APPLY
)
899 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
901 cisco_unset_addr_mask(&fc
->addr
, &fc
->addr_mask
);
903 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
909 * XPath: /frr-filter:lib/access-list/entry/destination-host
911 static int lib_access_list_entry_destination_host_modify(
912 struct nb_cb_modify_args
*args
)
914 struct filter_cisco
*fc
;
917 /* Don't allow duplicated values. */
918 if (args
->event
== NB_EV_VALIDATE
) {
919 if (acl_cisco_is_dup(args
->dnode
)) {
920 snprintfrr(args
->errmsg
, args
->errmsg_len
,
921 "duplicated access list value: %s",
922 yang_dnode_get_string(args
->dnode
, NULL
));
923 return NB_ERR_VALIDATION
;
928 if (args
->event
!= NB_EV_APPLY
)
931 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
934 yang_dnode_get_ipv4(&fc
->mask
, args
->dnode
, NULL
);
935 fc
->mask_mask
.s_addr
= CISCO_BIN_HOST_WILDCARD_MASK
;
937 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
942 static int lib_access_list_entry_destination_host_destroy(
943 struct nb_cb_destroy_args
*args
)
945 struct filter_cisco
*fc
;
948 if (args
->event
!= NB_EV_APPLY
)
951 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
954 cisco_unset_addr_mask(&fc
->mask
, &fc
->mask_mask
);
956 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
962 * XPath: /frr-filter:lib/access-list/entry/destination-network/address
964 static int lib_access_list_entry_destination_network_address_modify(
965 struct nb_cb_modify_args
*args
)
967 struct filter_cisco
*fc
;
970 /* Don't allow duplicated values. */
971 if (args
->event
== NB_EV_VALIDATE
) {
972 if (acl_cisco_is_dup(args
->dnode
)) {
973 snprintfrr(args
->errmsg
, args
->errmsg_len
,
974 "duplicated access list value: %s",
975 yang_dnode_get_string(args
->dnode
, NULL
));
976 return NB_ERR_VALIDATION
;
981 if (args
->event
!= NB_EV_APPLY
)
984 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
987 yang_dnode_get_ipv4(&fc
->mask
, args
->dnode
, NULL
);
989 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
995 * XPath: /frr-filter:lib/access-list/entry/destination-network/mask
997 static int lib_access_list_entry_destination_network_mask_modify(
998 struct nb_cb_modify_args
*args
)
1000 struct filter_cisco
*fc
;
1003 /* Don't allow duplicated values. */
1004 if (args
->event
== NB_EV_VALIDATE
) {
1005 if (acl_cisco_is_dup(args
->dnode
)) {
1006 snprintfrr(args
->errmsg
, args
->errmsg_len
,
1007 "duplicated access list value: %s",
1008 yang_dnode_get_string(args
->dnode
, NULL
));
1009 return NB_ERR_VALIDATION
;
1014 if (args
->event
!= NB_EV_APPLY
)
1017 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1020 yang_dnode_get_ipv4(&fc
->mask_mask
, args
->dnode
, NULL
);
1022 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1028 * XPath: /frr-filter:lib/access-list/entry/destination-any
1030 static int lib_access_list_entry_destination_any_create(
1031 struct nb_cb_create_args
*args
)
1033 struct filter_cisco
*fc
;
1036 /* Don't allow duplicated values. */
1037 if (args
->event
== NB_EV_VALIDATE
) {
1038 if (acl_cisco_is_dup(args
->dnode
)) {
1039 snprintfrr(args
->errmsg
, args
->errmsg_len
,
1040 "duplicated access list value: %s",
1041 yang_dnode_get_string(args
->dnode
, NULL
));
1042 return NB_ERR_VALIDATION
;
1047 if (args
->event
!= NB_EV_APPLY
)
1050 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1053 fc
->mask
.s_addr
= INADDR_ANY
;
1054 fc
->mask_mask
.s_addr
= CISCO_BIN_ANY_WILDCARD_MASK
;
1056 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1061 static int lib_access_list_entry_destination_any_destroy(
1062 struct nb_cb_destroy_args
*args
)
1064 struct filter_cisco
*fc
;
1067 if (args
->event
!= NB_EV_APPLY
)
1070 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1073 cisco_unset_addr_mask(&fc
->mask
, &fc
->mask_mask
);
1075 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
1081 * XPath: /frr-filter:lib/access-list/entry/any
1083 static int lib_access_list_entry_any_create(struct nb_cb_create_args
*args
)
1085 struct filter_zebra
*fz
;
1089 /* Don't allow duplicated values. */
1090 if (args
->event
== NB_EV_VALIDATE
) {
1091 if (acl_zebra_is_dup(
1093 yang_dnode_get_enum(args
->dnode
, "../../type"))) {
1094 snprintfrr(args
->errmsg
, args
->errmsg_len
,
1095 "duplicated access list value: %s",
1096 yang_dnode_get_string(args
->dnode
, NULL
));
1097 return NB_ERR_VALIDATION
;
1102 if (args
->event
!= NB_EV_APPLY
)
1105 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1108 memset(&fz
->prefix
, 0, sizeof(fz
->prefix
));
1110 type
= yang_dnode_get_enum(args
->dnode
, "../../type");
1113 fz
->prefix
.family
= AF_INET
;
1116 fz
->prefix
.family
= AF_INET6
;
1119 fz
->prefix
.family
= AF_ETHERNET
;
1123 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_ADDED
);
1128 static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args
*args
)
1130 struct filter_zebra
*fz
;
1133 if (args
->event
!= NB_EV_APPLY
)
1136 f
= nb_running_get_entry(args
->dnode
, NULL
, true);
1138 fz
->prefix
.family
= AF_UNSPEC
;
1140 acl_notify_route_map(f
->acl
, RMAP_EVENT_FILTER_DELETED
);
1146 * XPath: /frr-filter:lib/prefix-list
1148 static int lib_prefix_list_create(struct nb_cb_create_args
*args
)
1150 struct prefix_list
*pl
= NULL
;
1154 if (args
->event
!= NB_EV_APPLY
)
1157 type
= yang_dnode_get_enum(args
->dnode
, "./type");
1158 name
= yang_dnode_get_string(args
->dnode
, "./name");
1161 pl
= prefix_list_get(AFI_IP
, 0, name
);
1164 pl
= prefix_list_get(AFI_IP6
, 0, name
);
1168 nb_running_set_entry(args
->dnode
, pl
);
1173 static int lib_prefix_list_destroy(struct nb_cb_destroy_args
*args
)
1175 struct prefix_list
*pl
;
1177 if (args
->event
!= NB_EV_APPLY
)
1180 pl
= nb_running_unset_entry(args
->dnode
);
1181 prefix_list_delete(pl
);
1187 * XPath: /frr-filter:lib/prefix-list/remark
1189 static int lib_prefix_list_remark_modify(struct nb_cb_modify_args
*args
)
1191 struct prefix_list
*pl
;
1194 if (args
->event
!= NB_EV_APPLY
)
1197 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1199 XFREE(MTYPE_TMP
, pl
->desc
);
1201 remark
= yang_dnode_get_string(args
->dnode
, NULL
);
1202 pl
->desc
= XSTRDUP(MTYPE_TMP
, remark
);
1207 static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args
*args
)
1209 struct prefix_list
*pl
;
1211 if (args
->event
!= NB_EV_APPLY
)
1214 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1216 XFREE(MTYPE_TMP
, pl
->desc
);
1222 * XPath: /frr-filter:lib/prefix-list/entry
1224 static int lib_prefix_list_entry_create(struct nb_cb_create_args
*args
)
1226 struct prefix_list_entry
*ple
;
1227 struct prefix_list
*pl
;
1229 if (args
->event
!= NB_EV_APPLY
)
1232 pl
= nb_running_get_entry(args
->dnode
, NULL
, true);
1233 ple
= prefix_list_entry_new();
1235 ple
->seq
= yang_dnode_get_uint32(args
->dnode
, "./sequence");
1236 prefix_list_entry_set_empty(ple
);
1237 nb_running_set_entry(args
->dnode
, ple
);
1242 static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args
*args
)
1244 struct prefix_list_entry
*ple
;
1246 if (args
->event
!= NB_EV_APPLY
)
1249 ple
= nb_running_unset_entry(args
->dnode
);
1251 prefix_list_entry_delete2(ple
);
1253 prefix_list_entry_free(ple
);
1259 * XPath: /frr-filter:lib/prefix-list/entry/action
1261 static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args
*args
)
1263 struct prefix_list_entry
*ple
;
1266 if (args
->event
!= NB_EV_APPLY
)
1269 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1271 /* Start prefix entry update procedure. */
1272 prefix_list_entry_update_start(ple
);
1274 action_type
= yang_dnode_get_enum(args
->dnode
, NULL
);
1275 if (action_type
== YPLA_PERMIT
)
1276 ple
->type
= PREFIX_PERMIT
;
1278 ple
->type
= PREFIX_DENY
;
1280 /* Finish prefix entry update procedure. */
1281 prefix_list_entry_update_finish(ple
);
1286 static int lib_prefix_list_entry_prefix_modify(struct nb_cb_modify_args
*args
)
1288 struct prefix_list_entry
*ple
;
1291 if (args
->event
!= NB_EV_APPLY
)
1294 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1296 /* Start prefix entry update procedure. */
1297 prefix_list_entry_update_start(ple
);
1299 yang_dnode_get_prefix(&ple
->prefix
, args
->dnode
, NULL
);
1301 /* Apply mask and correct original address if necessary. */
1302 prefix_copy(&p
, &ple
->prefix
);
1304 if (!prefix_same(&ple
->prefix
, &p
)) {
1305 zlog_info("%s: bad network %pFX correcting it to %pFX",
1306 __func__
, &ple
->prefix
, &p
);
1307 prefix_copy(&ple
->prefix
, &p
);
1311 /* Finish prefix entry update procedure. */
1312 prefix_list_entry_update_finish(ple
);
1317 static int lib_prefix_list_entry_prefix_destroy(struct nb_cb_destroy_args
*args
)
1319 struct prefix_list_entry
*ple
;
1321 if (args
->event
!= NB_EV_APPLY
)
1324 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1326 /* Start prefix entry update procedure. */
1327 prefix_list_entry_update_start(ple
);
1329 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
1331 /* Finish prefix entry update procedure. */
1332 prefix_list_entry_update_finish(ple
);
1338 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
1341 lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args
*args
)
1343 if (args
->event
== NB_EV_VALIDATE
) {
1344 const struct lyd_node
*plist_dnode
=
1345 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1347 if (plist_is_dup_nb(args
->dnode
)) {
1348 snprintf(args
->errmsg
, args
->errmsg_len
,
1349 "duplicated prefix list value: %s",
1350 yang_dnode_get_string(args
->dnode
, NULL
));
1351 return NB_ERR_VALIDATION
;
1354 return prefix_list_nb_validate_v4_af_type(
1355 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1358 return lib_prefix_list_entry_prefix_modify(args
);
1362 lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args
*args
)
1365 if (args
->event
!= NB_EV_APPLY
)
1368 return lib_prefix_list_entry_prefix_destroy(args
);
1372 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix
1375 lib_prefix_list_entry_ipv6_prefix_modify(struct nb_cb_modify_args
*args
)
1378 if (args
->event
== NB_EV_VALIDATE
) {
1379 const struct lyd_node
*plist_dnode
=
1380 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1382 if (plist_is_dup_nb(args
->dnode
)) {
1383 snprintf(args
->errmsg
, args
->errmsg_len
,
1384 "duplicated prefix list value: %s",
1385 yang_dnode_get_string(args
->dnode
, NULL
));
1386 return NB_ERR_VALIDATION
;
1389 return prefix_list_nb_validate_v6_af_type(
1390 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1393 return lib_prefix_list_entry_prefix_modify(args
);
1397 lib_prefix_list_entry_ipv6_prefix_destroy(struct nb_cb_destroy_args
*args
)
1400 if (args
->event
!= NB_EV_APPLY
)
1403 return lib_prefix_list_entry_prefix_destroy(args
);
1407 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
1409 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
1410 struct nb_cb_modify_args
*args
)
1412 if (args
->event
== NB_EV_VALIDATE
1413 && prefix_list_length_validate(args
) != NB_OK
)
1414 return NB_ERR_VALIDATION
;
1416 if (args
->event
== NB_EV_VALIDATE
) {
1417 const struct lyd_node
*plist_dnode
=
1418 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1420 if (plist_is_dup_nb(args
->dnode
)) {
1421 snprintf(args
->errmsg
, args
->errmsg_len
,
1422 "duplicated prefix list value: %s",
1423 yang_dnode_get_string(args
->dnode
, NULL
));
1424 return NB_ERR_VALIDATION
;
1427 return prefix_list_nb_validate_v4_af_type(
1428 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1431 return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
1435 static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
1436 struct nb_cb_destroy_args
*args
)
1438 if (args
->event
== NB_EV_VALIDATE
) {
1439 const struct lyd_node
*plist_dnode
=
1440 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1442 return prefix_list_nb_validate_v4_af_type(
1443 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1446 return lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
1451 * XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
1453 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
1454 struct nb_cb_modify_args
*args
)
1456 if (args
->event
== NB_EV_VALIDATE
1457 && prefix_list_length_validate(args
) != NB_OK
)
1458 return NB_ERR_VALIDATION
;
1460 if (args
->event
== NB_EV_VALIDATE
) {
1461 const struct lyd_node
*plist_dnode
=
1462 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1464 if (plist_is_dup_nb(args
->dnode
)) {
1465 snprintf(args
->errmsg
, args
->errmsg_len
,
1466 "duplicated prefix list value: %s",
1467 yang_dnode_get_string(args
->dnode
, NULL
));
1468 return NB_ERR_VALIDATION
;
1471 return prefix_list_nb_validate_v4_af_type(
1472 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1475 return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
1479 static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
1480 struct nb_cb_destroy_args
*args
)
1482 if (args
->event
== NB_EV_VALIDATE
) {
1483 const struct lyd_node
*plist_dnode
=
1484 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1486 return prefix_list_nb_validate_v4_af_type(
1487 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1490 return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
1495 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal
1497 static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify(
1498 struct nb_cb_modify_args
*args
)
1500 if (args
->event
== NB_EV_VALIDATE
1501 && prefix_list_length_validate(args
) != NB_OK
)
1502 return NB_ERR_VALIDATION
;
1504 if (args
->event
== NB_EV_VALIDATE
) {
1505 const struct lyd_node
*plist_dnode
=
1506 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1508 if (plist_is_dup_nb(args
->dnode
)) {
1509 snprintf(args
->errmsg
, args
->errmsg_len
,
1510 "duplicated prefix list value: %s",
1511 yang_dnode_get_string(args
->dnode
, NULL
));
1512 return NB_ERR_VALIDATION
;
1515 return prefix_list_nb_validate_v6_af_type(
1516 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1519 return lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
1523 static int lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_destroy(
1524 struct nb_cb_destroy_args
*args
)
1526 if (args
->event
== NB_EV_VALIDATE
) {
1527 const struct lyd_node
*plist_dnode
=
1528 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1530 return prefix_list_nb_validate_v6_af_type(
1531 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1534 return lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
1539 * XPath: /frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal
1541 static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_modify(
1542 struct nb_cb_modify_args
*args
)
1544 if (args
->event
== NB_EV_VALIDATE
1545 && prefix_list_length_validate(args
) != NB_OK
)
1546 return NB_ERR_VALIDATION
;
1548 if (args
->event
== NB_EV_VALIDATE
) {
1549 const struct lyd_node
*plist_dnode
=
1550 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1552 if (plist_is_dup_nb(args
->dnode
)) {
1553 snprintf(args
->errmsg
, args
->errmsg_len
,
1554 "duplicated prefix list value: %s",
1555 yang_dnode_get_string(args
->dnode
, NULL
));
1556 return NB_ERR_VALIDATION
;
1559 return prefix_list_nb_validate_v6_af_type(
1560 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1563 return lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
1567 static int lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_destroy(
1568 struct nb_cb_destroy_args
*args
)
1570 if (args
->event
== NB_EV_VALIDATE
) {
1571 const struct lyd_node
*plist_dnode
=
1572 yang_dnode_get_parent(args
->dnode
, "prefix-list");
1574 return prefix_list_nb_validate_v6_af_type(
1575 plist_dnode
, args
->errmsg
, args
->errmsg_len
);
1578 return lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
1583 * XPath: /frr-filter:lib/prefix-list/entry/any
1585 static int lib_prefix_list_entry_any_create(struct nb_cb_create_args
*args
)
1587 struct prefix_list_entry
*ple
;
1590 if (args
->event
== NB_EV_VALIDATE
) {
1591 if (plist_is_dup_nb(args
->dnode
)) {
1592 snprintf(args
->errmsg
, args
->errmsg_len
,
1593 "duplicated prefix list value: %s",
1594 yang_dnode_get_string(args
->dnode
, NULL
));
1595 return NB_ERR_VALIDATION
;
1601 if (args
->event
!= NB_EV_APPLY
)
1604 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1606 /* Start prefix entry update procedure. */
1607 prefix_list_entry_update_start(ple
);
1611 /* Fill prefix struct from scratch. */
1612 memset(&ple
->prefix
, 0, sizeof(ple
->prefix
));
1614 type
= yang_dnode_get_enum(args
->dnode
, "../../type");
1617 ple
->prefix
.family
= AF_INET
;
1619 ple
->le
= IPV4_MAX_BITLEN
;
1622 ple
->prefix
.family
= AF_INET6
;
1624 ple
->le
= IPV6_MAX_BITLEN
;
1628 /* Finish prefix entry update procedure. */
1629 prefix_list_entry_update_finish(ple
);
1634 static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args
*args
)
1636 struct prefix_list_entry
*ple
;
1638 if (args
->event
!= NB_EV_APPLY
)
1641 ple
= nb_running_get_entry(args
->dnode
, NULL
, true);
1643 /* Start prefix entry update procedure. */
1644 prefix_list_entry_update_start(ple
);
1646 prefix_list_entry_set_empty(ple
);
1648 /* Finish prefix entry update procedure. */
1649 prefix_list_entry_update_finish(ple
);
1654 /* clang-format off */
1655 const struct frr_yang_module_info frr_filter_info
= {
1656 .name
= "frr-filter",
1659 .xpath
= "/frr-filter:lib/access-list",
1661 .create
= lib_access_list_create
,
1662 .destroy
= lib_access_list_destroy
,
1666 .xpath
= "/frr-filter:lib/access-list/remark",
1668 .modify
= lib_access_list_remark_modify
,
1669 .destroy
= lib_access_list_remark_destroy
,
1670 .cli_show
= access_list_remark_show
,
1674 .xpath
= "/frr-filter:lib/access-list/entry",
1676 .create
= lib_access_list_entry_create
,
1677 .destroy
= lib_access_list_entry_destroy
,
1678 .cli_cmp
= access_list_cmp
,
1679 .cli_show
= access_list_show
,
1683 .xpath
= "/frr-filter:lib/access-list/entry/action",
1685 .modify
= lib_access_list_entry_action_modify
,
1689 .xpath
= "/frr-filter:lib/access-list/entry/ipv4-prefix",
1691 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1692 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1696 .xpath
= "/frr-filter:lib/access-list/entry/ipv4-exact-match",
1698 .modify
= lib_access_list_entry_ipv4_exact_match_modify
,
1699 .destroy
= lib_access_list_entry_ipv4_exact_match_destroy
,
1703 .xpath
= "/frr-filter:lib/access-list/entry/host",
1705 .modify
= lib_access_list_entry_host_modify
,
1706 .destroy
= lib_access_list_entry_host_destroy
,
1710 .xpath
= "/frr-filter:lib/access-list/entry/network/address",
1712 .modify
= lib_access_list_entry_network_address_modify
,
1716 .xpath
= "/frr-filter:lib/access-list/entry/network/mask",
1718 .modify
= lib_access_list_entry_network_mask_modify
,
1722 .xpath
= "/frr-filter:lib/access-list/entry/source-any",
1724 .create
= lib_access_list_entry_source_any_create
,
1725 .destroy
= lib_access_list_entry_source_any_destroy
,
1729 .xpath
= "/frr-filter:lib/access-list/entry/destination-host",
1731 .modify
= lib_access_list_entry_destination_host_modify
,
1732 .destroy
= lib_access_list_entry_destination_host_destroy
,
1736 .xpath
= "/frr-filter:lib/access-list/entry/destination-network/address",
1738 .modify
= lib_access_list_entry_destination_network_address_modify
,
1742 .xpath
= "/frr-filter:lib/access-list/entry/destination-network/mask",
1744 .modify
= lib_access_list_entry_destination_network_mask_modify
,
1748 .xpath
= "/frr-filter:lib/access-list/entry/destination-any",
1750 .create
= lib_access_list_entry_destination_any_create
,
1751 .destroy
= lib_access_list_entry_destination_any_destroy
,
1755 .xpath
= "/frr-filter:lib/access-list/entry/ipv6-prefix",
1757 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1758 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1762 .xpath
= "/frr-filter:lib/access-list/entry/ipv6-exact-match",
1764 .modify
= lib_access_list_entry_ipv4_exact_match_modify
,
1765 .destroy
= lib_access_list_entry_ipv4_exact_match_destroy
,
1769 .xpath
= "/frr-filter:lib/access-list/entry/mac",
1771 .modify
= lib_access_list_entry_ipv4_prefix_modify
,
1772 .destroy
= lib_access_list_entry_ipv4_prefix_destroy
,
1776 .xpath
= "/frr-filter:lib/access-list/entry/any",
1778 .create
= lib_access_list_entry_any_create
,
1779 .destroy
= lib_access_list_entry_any_destroy
,
1783 .xpath
= "/frr-filter:lib/prefix-list",
1785 .create
= lib_prefix_list_create
,
1786 .destroy
= lib_prefix_list_destroy
,
1790 .xpath
= "/frr-filter:lib/prefix-list/remark",
1792 .modify
= lib_prefix_list_remark_modify
,
1793 .destroy
= lib_prefix_list_remark_destroy
,
1794 .cli_show
= prefix_list_remark_show
,
1798 .xpath
= "/frr-filter:lib/prefix-list/entry",
1800 .create
= lib_prefix_list_entry_create
,
1801 .destroy
= lib_prefix_list_entry_destroy
,
1802 .cli_cmp
= prefix_list_cmp
,
1803 .cli_show
= prefix_list_show
,
1807 .xpath
= "/frr-filter:lib/prefix-list/entry/action",
1809 .modify
= lib_prefix_list_entry_action_modify
,
1813 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
1815 .modify
= lib_prefix_list_entry_ipv4_prefix_modify
,
1816 .destroy
= lib_prefix_list_entry_ipv4_prefix_destroy
,
1820 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
1822 .modify
= lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify
,
1823 .destroy
= lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy
,
1827 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
1829 .modify
= lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify
,
1830 .destroy
= lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy
,
1834 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
1836 .modify
= lib_prefix_list_entry_ipv6_prefix_modify
,
1837 .destroy
= lib_prefix_list_entry_ipv6_prefix_destroy
,
1841 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
1843 .modify
= lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_modify
,
1844 .destroy
= lib_prefix_list_entry_ipv6_prefix_length_greater_or_equal_destroy
,
1848 .xpath
= "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
1850 .modify
= lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_modify
,
1851 .destroy
= lib_prefix_list_entry_ipv6_prefix_length_lesser_or_equal_destroy
,
1855 .xpath
= "/frr-filter:lib/prefix-list/entry/any",
1857 .create
= lib_prefix_list_entry_any_create
,
1858 .destroy
= lib_prefix_list_entry_any_destroy
,