back to topotato report
topotato coverage report
Current view: top level - lib - filter_nb.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 244 730 33.4 %
Date: 2023-02-24 14:41:08 Functions: 25 65 38.5 %

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

Generated by: LCOV version v1.16-topotato