back to topotato report
topotato coverage report
Current view: top level - lib - if_rmap.c (source / functions) Hit Total Coverage
Test: test_bgp_disable_addpath_rx.py::BGPDisableAddpathRx Lines: 4 153 2.6 %
Date: 2023-02-24 18:37:08 Functions: 8 25 32.0 %

          Line data    Source code
       1             : /* route-map for interface.
       2             :  * Copyright (C) 1999 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "hash.h"
      24             : #include "command.h"
      25             : #include "memory.h"
      26             : #include "if.h"
      27             : #include "if_rmap.h"
      28             : 
      29          24 : DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX, "Interface route map container");
      30          24 : DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME,
      31             :                     "Interface route map container name");
      32          24 : DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map");
      33          24 : DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name");
      34             : 
      35             : static struct list *if_rmap_ctx_list;
      36             : 
      37           0 : static struct if_rmap *if_rmap_new(void)
      38             : {
      39           0 :         struct if_rmap *new;
      40             : 
      41           0 :         new = XCALLOC(MTYPE_IF_RMAP, sizeof(struct if_rmap));
      42             : 
      43           0 :         return new;
      44             : }
      45             : 
      46           0 : static void if_rmap_free(struct if_rmap *if_rmap)
      47             : {
      48           0 :         XFREE(MTYPE_IF_RMAP_NAME, if_rmap->ifname);
      49             : 
      50           0 :         XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
      51           0 :         XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
      52             : 
      53           0 :         XFREE(MTYPE_IF_RMAP, if_rmap);
      54           0 : }
      55             : 
      56           0 : struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx, const char *ifname)
      57             : {
      58           0 :         struct if_rmap key;
      59           0 :         struct if_rmap *if_rmap;
      60             : 
      61             :         /* temporary copy */
      62           0 :         key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
      63             : 
      64           0 :         if_rmap = hash_lookup(ctx->ifrmaphash, &key);
      65             : 
      66           0 :         XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
      67             : 
      68           0 :         return if_rmap;
      69             : }
      70             : 
      71           0 : void if_rmap_hook_add(struct if_rmap_ctx *ctx,
      72             :                       void (*func)(struct if_rmap_ctx *ctx,
      73             :                                    struct if_rmap *))
      74             : {
      75           0 :         ctx->if_rmap_add_hook = func;
      76           0 : }
      77             : 
      78           0 : void if_rmap_hook_delete(struct if_rmap_ctx *ctx,
      79             :                          void (*func)(struct if_rmap_ctx *ctx,
      80             :                                       struct if_rmap *))
      81             : {
      82           0 :         ctx->if_rmap_delete_hook = func;
      83           0 : }
      84             : 
      85           0 : static void *if_rmap_hash_alloc(void *arg)
      86             : {
      87           0 :         struct if_rmap *ifarg = (struct if_rmap *)arg;
      88           0 :         struct if_rmap *if_rmap;
      89             : 
      90           0 :         if_rmap = if_rmap_new();
      91           0 :         if_rmap->ifname = XSTRDUP(MTYPE_IF_RMAP_NAME, ifarg->ifname);
      92             : 
      93           0 :         return if_rmap;
      94             : }
      95             : 
      96           0 : static struct if_rmap *if_rmap_get(struct if_rmap_ctx *ctx, const char *ifname)
      97             : {
      98           0 :         struct if_rmap key;
      99           0 :         struct if_rmap *ret;
     100             : 
     101             :         /* temporary copy */
     102           0 :         key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
     103             : 
     104           0 :         ret = hash_get(ctx->ifrmaphash, &key, if_rmap_hash_alloc);
     105             : 
     106           0 :         XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
     107             : 
     108           0 :         return ret;
     109             : }
     110             : 
     111           0 : static unsigned int if_rmap_hash_make(const void *data)
     112             : {
     113           0 :         const struct if_rmap *if_rmap = data;
     114             : 
     115           0 :         return string_hash_make(if_rmap->ifname);
     116             : }
     117             : 
     118           0 : static bool if_rmap_hash_cmp(const void *arg1, const void *arg2)
     119             : {
     120           0 :         const struct if_rmap *if_rmap1 = arg1;
     121           0 :         const struct if_rmap *if_rmap2 = arg2;
     122             : 
     123           0 :         return strcmp(if_rmap1->ifname, if_rmap2->ifname) == 0;
     124             : }
     125             : 
     126           0 : static struct if_rmap *if_rmap_set(struct if_rmap_ctx *ctx,
     127             :                                    const char *ifname, enum if_rmap_type type,
     128             :                                    const char *routemap_name)
     129             : {
     130           0 :         struct if_rmap *if_rmap;
     131             : 
     132           0 :         if_rmap = if_rmap_get(ctx, ifname);
     133             : 
     134           0 :         if (type == IF_RMAP_IN) {
     135           0 :                 XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
     136           0 :                 if_rmap->routemap[IF_RMAP_IN] =
     137           0 :                         XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
     138             :         }
     139           0 :         if (type == IF_RMAP_OUT) {
     140           0 :                 XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
     141           0 :                 if_rmap->routemap[IF_RMAP_OUT] =
     142           0 :                         XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
     143             :         }
     144             : 
     145           0 :         if (ctx->if_rmap_add_hook)
     146           0 :                 (ctx->if_rmap_add_hook)(ctx, if_rmap);
     147             : 
     148           0 :         return if_rmap;
     149             : }
     150             : 
     151           0 : static int if_rmap_unset(struct if_rmap_ctx *ctx,
     152             :                          const char *ifname, enum if_rmap_type type,
     153             :                          const char *routemap_name)
     154             : {
     155           0 :         struct if_rmap *if_rmap;
     156             : 
     157           0 :         if_rmap = if_rmap_lookup(ctx, ifname);
     158           0 :         if (!if_rmap)
     159             :                 return 0;
     160             : 
     161           0 :         if (type == IF_RMAP_IN) {
     162           0 :                 if (!if_rmap->routemap[IF_RMAP_IN])
     163             :                         return 0;
     164           0 :                 if (strcmp(if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
     165             :                         return 0;
     166             : 
     167           0 :                 XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
     168             :         }
     169             : 
     170           0 :         if (type == IF_RMAP_OUT) {
     171           0 :                 if (!if_rmap->routemap[IF_RMAP_OUT])
     172             :                         return 0;
     173           0 :                 if (strcmp(if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
     174             :                         return 0;
     175             : 
     176           0 :                 XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
     177             :         }
     178             : 
     179           0 :         if (ctx->if_rmap_delete_hook)
     180           0 :                 ctx->if_rmap_delete_hook(ctx, if_rmap);
     181             : 
     182           0 :         if (if_rmap->routemap[IF_RMAP_IN] == NULL
     183           0 :             && if_rmap->routemap[IF_RMAP_OUT] == NULL) {
     184           0 :                 hash_release(ctx->ifrmaphash, if_rmap);
     185           0 :                 if_rmap_free(if_rmap);
     186             :         }
     187             : 
     188             :         return 1;
     189             : }
     190             : 
     191           0 : DEFUN (if_rmap,
     192             :        if_rmap_cmd,
     193             :        "route-map RMAP_NAME <in|out> IFNAME",
     194             :        "Route map set\n"
     195             :        "Route map name\n"
     196             :        "Route map set for input filtering\n"
     197             :        "Route map set for output filtering\n"
     198             :        "Route map interface name\n")
     199             : {
     200           0 :         int idx_rmap_name = 1;
     201           0 :         int idx_in_out = 2;
     202           0 :         int idx_ifname = 3;
     203           0 :         enum if_rmap_type type;
     204           0 :         struct if_rmap_ctx *ctx =
     205           0 :                 (struct if_rmap_ctx *)listnode_head(if_rmap_ctx_list);
     206             : 
     207           0 :         if (strncmp(argv[idx_in_out]->text, "in", 1) == 0)
     208             :                 type = IF_RMAP_IN;
     209           0 :         else if (strncmp(argv[idx_in_out]->text, "out", 1) == 0)
     210             :                 type = IF_RMAP_OUT;
     211             :         else {
     212           0 :                 vty_out(vty, "route-map direction must be [in|out]\n");
     213           0 :                 return CMD_WARNING_CONFIG_FAILED;
     214             :         }
     215             : 
     216           0 :         if_rmap_set(ctx, argv[idx_ifname]->arg,
     217           0 :                     type, argv[idx_rmap_name]->arg);
     218             : 
     219           0 :         return CMD_SUCCESS;
     220             : }
     221             : 
     222           0 : DEFUN (no_if_rmap,
     223             :        no_if_rmap_cmd,
     224             :        "no route-map ROUTEMAP_NAME <in|out> IFNAME",
     225             :        NO_STR
     226             :        "Route map unset\n"
     227             :        "Route map name\n"
     228             :        "Route map for input filtering\n"
     229             :        "Route map for output filtering\n"
     230             :        "Route map interface name\n")
     231             : {
     232           0 :         int idx_routemap_name = 2;
     233           0 :         int idx_in_out = 3;
     234           0 :         int idx_ifname = 4;
     235           0 :         int ret;
     236           0 :         enum if_rmap_type type;
     237           0 :         struct if_rmap_ctx *ctx =
     238           0 :                 (struct if_rmap_ctx *)listnode_head(if_rmap_ctx_list);
     239             : 
     240           0 :         if (strncmp(argv[idx_in_out]->arg, "i", 1) == 0)
     241             :                 type = IF_RMAP_IN;
     242           0 :         else if (strncmp(argv[idx_in_out]->arg, "o", 1) == 0)
     243             :                 type = IF_RMAP_OUT;
     244             :         else {
     245           0 :                 vty_out(vty, "route-map direction must be [in|out]\n");
     246           0 :                 return CMD_WARNING_CONFIG_FAILED;
     247             :         }
     248             : 
     249           0 :         ret = if_rmap_unset(ctx, argv[idx_ifname]->arg, type,
     250           0 :                             argv[idx_routemap_name]->arg);
     251           0 :         if (!ret) {
     252           0 :                 vty_out(vty, "route-map doesn't exist\n");
     253           0 :                 return CMD_WARNING_CONFIG_FAILED;
     254             :         }
     255             :         return CMD_SUCCESS;
     256             : }
     257             : 
     258             : 
     259             : /* Configuration write function. */
     260           0 : int config_write_if_rmap(struct vty *vty,
     261             :                          struct if_rmap_ctx *ctx)
     262             : {
     263           0 :         unsigned int i;
     264           0 :         struct hash_bucket *mp;
     265           0 :         int write = 0;
     266           0 :         struct hash *ifrmaphash = ctx->ifrmaphash;
     267             : 
     268           0 :         for (i = 0; i < ifrmaphash->size; i++)
     269           0 :                 for (mp = ifrmaphash->index[i]; mp; mp = mp->next) {
     270           0 :                         struct if_rmap *if_rmap;
     271             : 
     272           0 :                         if_rmap = mp->data;
     273             : 
     274           0 :                         if (if_rmap->routemap[IF_RMAP_IN]) {
     275           0 :                                 vty_out(vty, " route-map %s in %s\n",
     276             :                                         if_rmap->routemap[IF_RMAP_IN],
     277             :                                         if_rmap->ifname);
     278           0 :                                 write++;
     279             :                         }
     280             : 
     281           0 :                         if (if_rmap->routemap[IF_RMAP_OUT]) {
     282           0 :                                 vty_out(vty, " route-map %s out %s\n",
     283             :                                         if_rmap->routemap[IF_RMAP_OUT],
     284             :                                         if_rmap->ifname);
     285           0 :                                 write++;
     286             :                         }
     287             :                 }
     288           0 :         return write;
     289             : }
     290             : 
     291           0 : void if_rmap_ctx_delete(struct if_rmap_ctx *ctx)
     292             : {
     293           0 :         listnode_delete(if_rmap_ctx_list, ctx);
     294           0 :         hash_clean(ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
     295           0 :         if (ctx->name)
     296           0 :                 XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx);
     297           0 :         XFREE(MTYPE_IF_RMAP_CTX, ctx);
     298           0 : }
     299             : 
     300             : /* name is optional: either vrf name, or other */
     301           0 : struct if_rmap_ctx *if_rmap_ctx_create(const char *name)
     302             : {
     303           0 :         struct if_rmap_ctx *ctx;
     304             : 
     305           0 :         ctx = XCALLOC(MTYPE_IF_RMAP_CTX, sizeof(struct if_rmap_ctx));
     306             : 
     307           0 :         if (ctx->name)
     308           0 :                 ctx->name = XSTRDUP(MTYPE_IF_RMAP_CTX_NAME, name);
     309           0 :         ctx->ifrmaphash = hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
     310             :                                            "Interface Route-Map Hash");
     311           0 :         if (!if_rmap_ctx_list)
     312           0 :                 if_rmap_ctx_list = list_new();
     313           0 :         listnode_add(if_rmap_ctx_list, ctx);
     314           0 :         return ctx;
     315             : }
     316             : 
     317           0 : void if_rmap_init(int node)
     318             : {
     319           0 :         if (node == RIPNG_NODE) {
     320           0 :         } else if (node == RIP_NODE) {
     321           0 :                 install_element(RIP_NODE, &if_rmap_cmd);
     322           0 :                 install_element(RIP_NODE, &no_if_rmap_cmd);
     323             :         }
     324           0 :         if_rmap_ctx_list = list_new();
     325           0 : }
     326             : 
     327           0 : void if_rmap_terminate(void)
     328             : {
     329           0 :         if (!if_rmap_ctx_list)
     330             :                 return;
     331           0 :         list_delete(&if_rmap_ctx_list);
     332             : }

Generated by: LCOV version v1.16-topotato