back to topotato report
topotato coverage report
Current view: top level - ripngd - ripng_routemap.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 21 135 15.6 %
Date: 2023-02-24 19:38:44 Functions: 1 15 6.7 %

          Line data    Source code
       1             : /* RIPng routemap.
       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 "if.h"
      24             : #include "memory.h"
      25             : #include "prefix.h"
      26             : #include "vty.h"
      27             : #include "routemap.h"
      28             : #include "command.h"
      29             : #include "sockunion.h"
      30             : 
      31             : #include "ripngd/ripngd.h"
      32             : 
      33             : struct rip_metric_modifier {
      34             :         enum { metric_increment, metric_decrement, metric_absolute } type;
      35             :         bool used;
      36             :         uint8_t metric;
      37             : };
      38             : 
      39             : /* `match metric METRIC' */
      40             : /* Match function return 1 if match is success else return zero. */
      41             : static enum route_map_cmd_result_t
      42           0 : route_match_metric(void *rule, const struct prefix *prefix, void *object)
      43             : {
      44           0 :         uint32_t *metric;
      45           0 :         struct ripng_info *rinfo;
      46             : 
      47           0 :         metric = rule;
      48           0 :         rinfo = object;
      49             : 
      50           0 :         if (rinfo->metric == *metric)
      51             :                 return RMAP_MATCH;
      52             :         else
      53           0 :                 return RMAP_NOMATCH;
      54             : 
      55             :         return RMAP_NOMATCH;
      56             : }
      57             : 
      58             : /* Route map `match metric' match statement. `arg' is METRIC value */
      59           0 : static void *route_match_metric_compile(const char *arg)
      60             : {
      61           0 :         uint32_t *metric;
      62             : 
      63           0 :         metric = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
      64           0 :         *metric = atoi(arg);
      65             : 
      66           0 :         if (*metric > 0)
      67             :                 return metric;
      68             : 
      69           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, metric);
      70           0 :         return NULL;
      71             : }
      72             : 
      73             : /* Free route map's compiled `match metric' value. */
      74           0 : static void route_match_metric_free(void *rule)
      75             : {
      76           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
      77           0 : }
      78             : 
      79             : /* Route map commands for metric matching. */
      80             : static const struct route_map_rule_cmd route_match_metric_cmd = {
      81             :         "metric",
      82             :         route_match_metric,
      83             :         route_match_metric_compile,
      84             :         route_match_metric_free
      85             : };
      86             : 
      87             : /* `match interface IFNAME' */
      88             : /* Match function return 1 if match is success else return zero. */
      89             : static enum route_map_cmd_result_t
      90           0 : route_match_interface(void *rule, const struct prefix *prefix, void *object)
      91             : {
      92           0 :         struct ripng_info *rinfo;
      93           0 :         struct interface *ifp;
      94           0 :         char *ifname;
      95             : 
      96           0 :         ifname = rule;
      97           0 :         ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
      98             : 
      99           0 :         if (!ifp)
     100             :                 return RMAP_NOMATCH;
     101             : 
     102           0 :         rinfo = object;
     103             : 
     104           0 :         if (rinfo->ifindex == ifp->ifindex)
     105             :                 return RMAP_MATCH;
     106             :         else
     107           0 :                 return RMAP_NOMATCH;
     108             : 
     109             :         return RMAP_NOMATCH;
     110             : }
     111             : 
     112             : /* Route map `match interface' match statement. `arg' is IFNAME value */
     113           0 : static void *route_match_interface_compile(const char *arg)
     114             : {
     115           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     116             : }
     117             : 
     118           0 : static void route_match_interface_free(void *rule)
     119             : {
     120           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     121           0 : }
     122             : 
     123             : static const struct route_map_rule_cmd route_match_interface_cmd = {
     124             :         "interface",
     125             :         route_match_interface,
     126             :         route_match_interface_compile,
     127             :         route_match_interface_free
     128             : };
     129             : 
     130             : /* `match tag TAG' */
     131             : /* Match function return 1 if match is success else return zero. */
     132           0 : static enum route_map_cmd_result_t route_match_tag(void *rule,
     133             :                                                    const struct prefix *prefix,
     134             :                                                    void *object)
     135             : {
     136           0 :         route_tag_t *tag;
     137           0 :         struct ripng_info *rinfo;
     138           0 :         route_tag_t rinfo_tag;
     139             : 
     140           0 :         tag = rule;
     141           0 :         rinfo = object;
     142             : 
     143             :         /* The information stored by rinfo is host ordered. */
     144           0 :         rinfo_tag = rinfo->tag;
     145           0 :         if (rinfo_tag == *tag)
     146             :                 return RMAP_MATCH;
     147             :         else
     148           0 :                 return RMAP_NOMATCH;
     149             : }
     150             : 
     151             : 
     152             : static const struct route_map_rule_cmd route_match_tag_cmd = {
     153             :         "tag",
     154             :         route_match_tag,
     155             :         route_map_rule_tag_compile,
     156             :         route_map_rule_tag_free,
     157             : };
     158             : 
     159             : /* `set metric METRIC' */
     160             : 
     161             : /* Set metric to attribute. */
     162             : static enum route_map_cmd_result_t
     163           0 : route_set_metric(void *rule, const struct prefix *prefix, void *object)
     164             : {
     165           0 :         struct rip_metric_modifier *mod;
     166           0 :         struct ripng_info *rinfo;
     167             : 
     168           0 :         mod = rule;
     169           0 :         rinfo = object;
     170             : 
     171           0 :         if (!mod->used)
     172             :                 return RMAP_OKAY;
     173             : 
     174           0 :         if (mod->type == metric_increment)
     175           0 :                 rinfo->metric_out += mod->metric;
     176           0 :         else if (mod->type == metric_decrement)
     177           0 :                 rinfo->metric_out -= mod->metric;
     178           0 :         else if (mod->type == metric_absolute)
     179           0 :                 rinfo->metric_out = mod->metric;
     180             : 
     181           0 :         if (rinfo->metric_out < 1)
     182           0 :                 rinfo->metric_out = 1;
     183           0 :         if (rinfo->metric_out > RIPNG_METRIC_INFINITY)
     184           0 :                 rinfo->metric_out = RIPNG_METRIC_INFINITY;
     185             : 
     186           0 :         rinfo->metric_set = 1;
     187             : 
     188           0 :         return RMAP_OKAY;
     189             : }
     190             : 
     191             : /* set metric compilation. */
     192           0 : static void *route_set_metric_compile(const char *arg)
     193             : {
     194           0 :         int len;
     195           0 :         const char *pnt;
     196           0 :         long metric;
     197           0 :         char *endptr = NULL;
     198           0 :         struct rip_metric_modifier *mod;
     199             : 
     200           0 :         len = strlen(arg);
     201           0 :         pnt = arg;
     202             : 
     203           0 :         mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
     204             :                       sizeof(struct rip_metric_modifier));
     205           0 :         mod->used = false;
     206             : 
     207           0 :         if (len == 0)
     208             :                 return mod;
     209             : 
     210             :         /* Examine first character. */
     211           0 :         if (arg[0] == '+') {
     212           0 :                 mod->type = metric_increment;
     213           0 :                 pnt++;
     214           0 :         } else if (arg[0] == '-') {
     215           0 :                 mod->type = metric_decrement;
     216           0 :                 pnt++;
     217             :         } else
     218           0 :                 mod->type = metric_absolute;
     219             : 
     220             :         /* Check beginning with digit string. */
     221           0 :         if (*pnt < '0' || *pnt > '9')
     222             :                 return mod;
     223             : 
     224             :         /* Convert string to integer. */
     225           0 :         metric = strtol(pnt, &endptr, 10);
     226             : 
     227           0 :         if (*endptr != '\0' || metric < 0)
     228             :                 return mod;
     229             : 
     230           0 :         if (metric > RIPNG_METRIC_INFINITY) {
     231           0 :                 zlog_info(
     232             :                         "%s: Metric specified: %ld is being converted into METRIC_INFINITY",
     233             :                         __func__, metric);
     234           0 :                 mod->metric = RIPNG_METRIC_INFINITY;
     235             :         } else
     236           0 :                 mod->metric = metric;
     237             : 
     238           0 :         mod->used = true;
     239           0 :         return mod;
     240             : }
     241             : 
     242             : /* Free route map's compiled `set metric' value. */
     243           0 : static void route_set_metric_free(void *rule)
     244             : {
     245           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     246           0 : }
     247             : 
     248             : static const struct route_map_rule_cmd route_set_metric_cmd = {
     249             :         "metric",
     250             :         route_set_metric,
     251             :         route_set_metric_compile,
     252             :         route_set_metric_free,
     253             : };
     254             : 
     255             : /* `set ipv6 next-hop local IP_ADDRESS' */
     256             : 
     257             : /* Set nexthop to object.  object must be pointer to struct attr. */
     258             : static enum route_map_cmd_result_t
     259           0 : route_set_ipv6_nexthop_local(void *rule, const struct prefix *p, void *object)
     260             : {
     261           0 :         struct in6_addr *address;
     262           0 :         struct ripng_info *rinfo;
     263             : 
     264             :         /* Fetch routemap's rule information. */
     265           0 :         address = rule;
     266           0 :         rinfo = object;
     267             : 
     268             :         /* Set next hop value. */
     269           0 :         rinfo->nexthop_out = *address;
     270             : 
     271           0 :         return RMAP_OKAY;
     272             : }
     273             : 
     274             : /* Route map `ipv6 nexthop local' compile function.  Given string is converted
     275             :    to struct in6_addr structure. */
     276           0 : static void *route_set_ipv6_nexthop_local_compile(const char *arg)
     277             : {
     278           0 :         int ret;
     279           0 :         struct in6_addr *address;
     280             : 
     281           0 :         address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
     282             : 
     283           0 :         ret = inet_pton(AF_INET6, arg, address);
     284             : 
     285           0 :         if (ret == 0) {
     286           0 :                 XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
     287           0 :                 return NULL;
     288             :         }
     289             : 
     290             :         return address;
     291             : }
     292             : 
     293             : /* Free route map's compiled `ipv6 nexthop local' value. */
     294           0 : static void route_set_ipv6_nexthop_local_free(void *rule)
     295             : {
     296           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     297           0 : }
     298             : 
     299             : /* Route map commands for ipv6 nexthop local set. */
     300             : static const struct route_map_rule_cmd
     301             :                 route_set_ipv6_nexthop_local_cmd = {
     302             :         "ipv6 next-hop local",
     303             :         route_set_ipv6_nexthop_local,
     304             :         route_set_ipv6_nexthop_local_compile,
     305             :         route_set_ipv6_nexthop_local_free
     306             : };
     307             : 
     308             : /* `set tag TAG' */
     309             : 
     310             : /* Set tag to object.  object must be pointer to struct attr. */
     311             : static enum route_map_cmd_result_t
     312           0 : route_set_tag(void *rule, const struct prefix *prefix, void *object)
     313             : {
     314           0 :         route_tag_t *tag;
     315           0 :         struct ripng_info *rinfo;
     316             : 
     317             :         /* Fetch routemap's rule information. */
     318           0 :         tag = rule;
     319           0 :         rinfo = object;
     320             : 
     321             :         /* Set next hop value. */
     322           0 :         rinfo->tag_out = *tag;
     323             : 
     324           0 :         return RMAP_OKAY;
     325             : }
     326             : 
     327             : /* Route map commands for tag set. */
     328             : static const struct route_map_rule_cmd route_set_tag_cmd = {
     329             :         "tag",
     330             :         route_set_tag,
     331             :         route_map_rule_tag_compile,
     332             :         route_map_rule_tag_free
     333             : };
     334             : 
     335             : #define MATCH_STR "Match values from routing table\n"
     336             : #define SET_STR "Set values in destination routing protocol\n"
     337             : 
     338           1 : void ripng_route_map_init(void)
     339             : {
     340           1 :         route_map_init();
     341             : 
     342           1 :         route_map_match_interface_hook(generic_match_add);
     343           1 :         route_map_no_match_interface_hook(generic_match_delete);
     344             : 
     345           1 :         route_map_match_metric_hook(generic_match_add);
     346           1 :         route_map_no_match_metric_hook(generic_match_delete);
     347             : 
     348           1 :         route_map_match_tag_hook(generic_match_add);
     349           1 :         route_map_no_match_tag_hook(generic_match_delete);
     350             : 
     351           1 :         route_map_set_ipv6_nexthop_local_hook(generic_set_add);
     352           1 :         route_map_no_set_ipv6_nexthop_local_hook(generic_set_delete);
     353             : 
     354           1 :         route_map_set_metric_hook(generic_set_add);
     355           1 :         route_map_no_set_metric_hook(generic_set_delete);
     356             : 
     357           1 :         route_map_set_tag_hook(generic_set_add);
     358           1 :         route_map_no_set_tag_hook(generic_set_delete);
     359             : 
     360           1 :         route_map_install_match(&route_match_metric_cmd);
     361           1 :         route_map_install_match(&route_match_interface_cmd);
     362           1 :         route_map_install_match(&route_match_tag_cmd);
     363           1 :         route_map_install_set(&route_set_metric_cmd);
     364           1 :         route_map_install_set(&route_set_ipv6_nexthop_local_cmd);
     365           1 :         route_map_install_set(&route_set_tag_cmd);
     366           1 : }

Generated by: LCOV version v1.16-topotato