back to topotato report
topotato coverage report
Current view: top level - ripd - rip_routemap.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 36 224 16.1 %
Date: 2023-02-24 14:41:08 Functions: 1 30 3.3 %

          Line data    Source code
       1             : /* RIPv2 routemap.
       2             :  * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
       3             :  * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
       4             :  *
       5             :  * This file is part of GNU Zebra.
       6             :  *
       7             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * GNU Zebra is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License along
      18             :  * with this program; see the file COPYING; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include <zebra.h>
      23             : 
      24             : #include "memory.h"
      25             : #include "prefix.h"
      26             : #include "vty.h"
      27             : #include "routemap.h"
      28             : #include "command.h"
      29             : #include "filter.h"
      30             : #include "log.h"
      31             : #include "sockunion.h" /* for inet_aton () */
      32             : #include "plist.h"
      33             : #include "vrf.h"
      34             : 
      35             : #include "ripd/ripd.h"
      36             : 
      37             : struct rip_metric_modifier {
      38             :         enum { metric_increment, metric_decrement, metric_absolute } type;
      39             :         bool used;
      40             :         uint8_t metric;
      41             : };
      42             : 
      43             : /* `match metric METRIC' */
      44             : /* Match function return 1 if match is success else return zero. */
      45             : static enum route_map_cmd_result_t
      46           0 : route_match_metric(void *rule, const struct prefix *prefix, void *object)
      47             : {
      48           0 :         uint32_t *metric;
      49           0 :         uint32_t check;
      50           0 :         struct rip_info *rinfo;
      51             : 
      52           0 :         metric = rule;
      53           0 :         rinfo = object;
      54             : 
      55             :         /* If external metric is available, the route-map should
      56             :            work on this one (for redistribute purpose)  */
      57           0 :         check = (rinfo->external_metric) ? rinfo->external_metric
      58           0 :                                          : rinfo->metric;
      59           0 :         if (check == *metric)
      60             :                 return RMAP_MATCH;
      61             :         else
      62           0 :                 return RMAP_NOMATCH;
      63             : }
      64             : 
      65             : /* Route map `match metric' match statement. `arg' is METRIC value */
      66           0 : static void *route_match_metric_compile(const char *arg)
      67             : {
      68           0 :         uint32_t *metric;
      69             : 
      70           0 :         metric = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
      71           0 :         *metric = atoi(arg);
      72             : 
      73           0 :         if (*metric > 0)
      74             :                 return metric;
      75             : 
      76           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, metric);
      77           0 :         return NULL;
      78             : }
      79             : 
      80             : /* Free route map's compiled `match metric' value. */
      81           0 : static void route_match_metric_free(void *rule)
      82             : {
      83           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
      84           0 : }
      85             : 
      86             : /* Route map commands for metric matching. */
      87             : static const struct route_map_rule_cmd route_match_metric_cmd = {
      88             :         "metric",
      89             :         route_match_metric,
      90             :         route_match_metric_compile,
      91             :         route_match_metric_free
      92             : };
      93             : 
      94             : /* `match interface IFNAME' */
      95             : /* Match function return 1 if match is success else return zero. */
      96             : static enum route_map_cmd_result_t
      97           0 : route_match_interface(void *rule, const struct prefix *prefix, void *object)
      98             : {
      99           0 :         struct rip_info *rinfo;
     100           0 :         struct interface *ifp;
     101           0 :         char *ifname;
     102             : 
     103           0 :         ifname = rule;
     104           0 :         ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
     105             : 
     106           0 :         if (!ifp)
     107             :                 return RMAP_NOMATCH;
     108             : 
     109           0 :         rinfo = object;
     110             : 
     111           0 :         if (rinfo->ifindex_out == ifp->ifindex
     112           0 :             || rinfo->nh.ifindex == ifp->ifindex)
     113             :                 return RMAP_MATCH;
     114             :         else
     115           0 :                 return RMAP_NOMATCH;
     116             : }
     117             : 
     118             : /* Route map `match interface' match statement. `arg' is IFNAME value */
     119             : /* XXX I don`t know if I need to check does interface exist? */
     120           0 : static void *route_match_interface_compile(const char *arg)
     121             : {
     122           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     123             : }
     124             : 
     125             : /* Free route map's compiled `match interface' value. */
     126           0 : static void route_match_interface_free(void *rule)
     127             : {
     128           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     129           0 : }
     130             : 
     131             : /* Route map commands for interface matching. */
     132             : static const struct route_map_rule_cmd route_match_interface_cmd = {
     133             :         "interface",
     134             :         route_match_interface,
     135             :         route_match_interface_compile,
     136             :         route_match_interface_free
     137             : };
     138             : 
     139             : /* `match ip next-hop IP_ACCESS_LIST' */
     140             : 
     141             : /* Match function return 1 if match is success else return zero. */
     142             : static enum route_map_cmd_result_t
     143           0 : route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object)
     144             : {
     145           0 :         struct access_list *alist;
     146           0 :         struct rip_info *rinfo;
     147           0 :         struct prefix_ipv4 p;
     148             : 
     149           0 :         rinfo = object;
     150           0 :         p.family = AF_INET;
     151           0 :         p.prefix = (rinfo->nh.gate.ipv4.s_addr != INADDR_ANY)
     152             :                            ? rinfo->nh.gate.ipv4
     153           0 :                            : rinfo->from;
     154           0 :         p.prefixlen = IPV4_MAX_BITLEN;
     155             : 
     156           0 :         alist = access_list_lookup(AFI_IP, (char *)rule);
     157           0 :         if (alist == NULL)
     158             :                 return RMAP_NOMATCH;
     159             : 
     160           0 :         return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH
     161           0 :                                                             : RMAP_MATCH);
     162             : }
     163             : 
     164             : /* Route map `ip next-hop' match statement.  `arg' should be
     165             :    access-list name. */
     166           0 : static void *route_match_ip_next_hop_compile(const char *arg)
     167             : {
     168           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     169             : }
     170             : 
     171             : /* Free route map's compiled `. */
     172           0 : static void route_match_ip_next_hop_free(void *rule)
     173             : {
     174           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     175           0 : }
     176             : 
     177             : /* Route map commands for ip next-hop matching. */
     178             : static const struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
     179             :         "ip next-hop",
     180             :         route_match_ip_next_hop,
     181             :         route_match_ip_next_hop_compile,
     182             :         route_match_ip_next_hop_free
     183             : };
     184             : 
     185             : /* `match ip next-hop prefix-list PREFIX_LIST' */
     186             : 
     187             : static enum route_map_cmd_result_t
     188           0 : route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
     189             :                                     void *object)
     190             : {
     191           0 :         struct prefix_list *plist;
     192           0 :         struct rip_info *rinfo;
     193           0 :         struct prefix_ipv4 p;
     194             : 
     195           0 :         rinfo = object;
     196           0 :         p.family = AF_INET;
     197           0 :         p.prefix = (rinfo->nh.gate.ipv4.s_addr != INADDR_ANY)
     198             :                            ? rinfo->nh.gate.ipv4
     199           0 :                            : rinfo->from;
     200           0 :         p.prefixlen = IPV4_MAX_BITLEN;
     201             : 
     202           0 :         plist = prefix_list_lookup(AFI_IP, (char *)rule);
     203           0 :         if (plist == NULL)
     204             :                 return RMAP_NOMATCH;
     205             : 
     206           0 :         return (prefix_list_apply(plist, &p) == PREFIX_DENY ? RMAP_NOMATCH
     207           0 :                                                             : RMAP_MATCH);
     208             : }
     209             : 
     210           0 : static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
     211             : {
     212           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     213             : }
     214             : 
     215           0 : static void route_match_ip_next_hop_prefix_list_free(void *rule)
     216             : {
     217           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     218           0 : }
     219             : 
     220             : static const struct route_map_rule_cmd
     221             :                 route_match_ip_next_hop_prefix_list_cmd = {
     222             :         "ip next-hop prefix-list",
     223             :         route_match_ip_next_hop_prefix_list,
     224             :         route_match_ip_next_hop_prefix_list_compile,
     225             :         route_match_ip_next_hop_prefix_list_free
     226             : };
     227             : 
     228             : /* `match ip next-hop type <blackhole>' */
     229             : 
     230             : static enum route_map_cmd_result_t
     231           0 : route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
     232             :                              void *object)
     233             : {
     234           0 :         struct rip_info *rinfo;
     235             : 
     236           0 :         if (prefix->family == AF_INET) {
     237           0 :                 rinfo = (struct rip_info *)object;
     238           0 :                 if (!rinfo)
     239             :                         return RMAP_NOMATCH;
     240             : 
     241           0 :                 if (rinfo->nh.type == NEXTHOP_TYPE_BLACKHOLE)
     242           0 :                         return RMAP_MATCH;
     243             :         }
     244             :         return RMAP_NOMATCH;
     245             : }
     246             : 
     247           0 : static void *route_match_ip_next_hop_type_compile(const char *arg)
     248             : {
     249           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     250             : }
     251             : 
     252           0 : static void route_match_ip_next_hop_type_free(void *rule)
     253             : {
     254           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     255           0 : }
     256             : 
     257             : static const struct route_map_rule_cmd
     258             :                 route_match_ip_next_hop_type_cmd = {
     259             :         "ip next-hop type",
     260             :         route_match_ip_next_hop_type,
     261             :         route_match_ip_next_hop_type_compile,
     262             :         route_match_ip_next_hop_type_free
     263             : };
     264             : 
     265             : /* `match ip address IP_ACCESS_LIST' */
     266             : 
     267             : /* Match function should return 1 if match is success else return
     268             :    zero. */
     269             : static enum route_map_cmd_result_t
     270           0 : route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
     271             : {
     272           0 :         struct access_list *alist;
     273             : 
     274           0 :         alist = access_list_lookup(AFI_IP, (char *)rule);
     275           0 :         if (alist == NULL)
     276             :                 return RMAP_NOMATCH;
     277             : 
     278           0 :         return (access_list_apply(alist, prefix) == FILTER_DENY ? RMAP_NOMATCH
     279           0 :                                                                 : RMAP_MATCH);
     280             : }
     281             : 
     282             : /* Route map `ip address' match statement.  `arg' should be
     283             :    access-list name. */
     284           0 : static void *route_match_ip_address_compile(const char *arg)
     285             : {
     286           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     287             : }
     288             : 
     289             : /* Free route map's compiled `ip address' value. */
     290           0 : static void route_match_ip_address_free(void *rule)
     291             : {
     292           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     293           0 : }
     294             : 
     295             : /* Route map commands for ip address matching. */
     296             : static const struct route_map_rule_cmd route_match_ip_address_cmd = {
     297             :         "ip address",
     298             :         route_match_ip_address,
     299             :         route_match_ip_address_compile,
     300             :         route_match_ip_address_free
     301             : };
     302             : 
     303             : /* `match ip address prefix-list PREFIX_LIST' */
     304             : 
     305             : static enum route_map_cmd_result_t
     306           0 : route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
     307             :                                    void *object)
     308             : {
     309           0 :         struct prefix_list *plist;
     310             : 
     311           0 :         plist = prefix_list_lookup(AFI_IP, (char *)rule);
     312           0 :         if (plist == NULL)
     313             :                 return RMAP_NOMATCH;
     314             : 
     315           0 :         return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
     316           0 :                                                                 : RMAP_MATCH);
     317             : }
     318             : 
     319           0 : static void *route_match_ip_address_prefix_list_compile(const char *arg)
     320             : {
     321           0 :         return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
     322             : }
     323             : 
     324           0 : static void route_match_ip_address_prefix_list_free(void *rule)
     325             : {
     326           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     327           0 : }
     328             : 
     329             : static const struct route_map_rule_cmd
     330             :                 route_match_ip_address_prefix_list_cmd = {
     331             :         "ip address prefix-list",
     332             :         route_match_ip_address_prefix_list,
     333             :         route_match_ip_address_prefix_list_compile,
     334             :         route_match_ip_address_prefix_list_free
     335             : };
     336             : 
     337             : /* `match tag TAG' */
     338             : /* Match function return 1 if match is success else return zero. */
     339             : static enum route_map_cmd_result_t
     340           0 : route_match_tag(void *rule, const struct prefix *p, void *object)
     341             : {
     342           0 :         route_tag_t *tag;
     343           0 :         struct rip_info *rinfo;
     344           0 :         route_tag_t rinfo_tag;
     345             : 
     346           0 :         tag = rule;
     347           0 :         rinfo = object;
     348             : 
     349             :         /* The information stored by rinfo is host ordered. */
     350           0 :         rinfo_tag = rinfo->tag;
     351           0 :         if (rinfo_tag == *tag)
     352             :                 return RMAP_MATCH;
     353             :         else
     354           0 :                 return RMAP_NOMATCH;
     355             : }
     356             : 
     357             : /* Route map commands for tag matching. */
     358             : static const struct route_map_rule_cmd route_match_tag_cmd = {
     359             :         "tag",
     360             :         route_match_tag,
     361             :         route_map_rule_tag_compile,
     362             :         route_map_rule_tag_free,
     363             : };
     364             : 
     365             : /* `set metric METRIC' */
     366             : 
     367             : /* Set metric to attribute. */
     368             : static enum route_map_cmd_result_t
     369           0 : route_set_metric(void *rule, const struct prefix *prefix, void *object)
     370             : {
     371           0 :         struct rip_metric_modifier *mod;
     372           0 :         struct rip_info *rinfo;
     373             : 
     374           0 :         mod = rule;
     375           0 :         rinfo = object;
     376             : 
     377           0 :         if (!mod->used)
     378             :                 return RMAP_OKAY;
     379             : 
     380           0 :         if (mod->type == metric_increment)
     381           0 :                 rinfo->metric_out += mod->metric;
     382           0 :         else if (mod->type == metric_decrement)
     383           0 :                 rinfo->metric_out -= mod->metric;
     384           0 :         else if (mod->type == metric_absolute)
     385           0 :                 rinfo->metric_out = mod->metric;
     386             : 
     387           0 :         if ((signed int)rinfo->metric_out < 1)
     388           0 :                 rinfo->metric_out = 1;
     389           0 :         if (rinfo->metric_out > RIP_METRIC_INFINITY)
     390           0 :                 rinfo->metric_out = RIP_METRIC_INFINITY;
     391             : 
     392           0 :         rinfo->metric_set = 1;
     393           0 :         return RMAP_OKAY;
     394             : }
     395             : 
     396             : /* set metric compilation. */
     397           0 : static void *route_set_metric_compile(const char *arg)
     398             : {
     399           0 :         int len;
     400           0 :         const char *pnt;
     401           0 :         long metric;
     402           0 :         char *endptr = NULL;
     403           0 :         struct rip_metric_modifier *mod;
     404             : 
     405           0 :         mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
     406             :                       sizeof(struct rip_metric_modifier));
     407           0 :         mod->used = false;
     408             : 
     409           0 :         len = strlen(arg);
     410           0 :         pnt = arg;
     411             : 
     412           0 :         if (len == 0)
     413             :                 return mod;
     414             : 
     415             :         /* Examine first character. */
     416           0 :         if (arg[0] == '+') {
     417           0 :                 mod->type = metric_increment;
     418           0 :                 pnt++;
     419           0 :         } else if (arg[0] == '-') {
     420           0 :                 mod->type = metric_decrement;
     421           0 :                 pnt++;
     422             :         } else
     423           0 :                 mod->type = metric_absolute;
     424             : 
     425             :         /* Check beginning with digit string. */
     426           0 :         if (*pnt < '0' || *pnt > '9')
     427             :                 return mod;
     428             : 
     429             :         /* Convert string to integer. */
     430           0 :         metric = strtol(pnt, &endptr, 10);
     431             : 
     432           0 :         if (*endptr != '\0' || metric < 0) {
     433             :                 return mod;
     434             :         }
     435           0 :         if (metric > RIP_METRIC_INFINITY) {
     436           0 :                 zlog_info(
     437             :                         "%s: Metric specified: %ld is greater than RIP_METRIC_INFINITY, using INFINITY instead",
     438             :                         __func__, metric);
     439           0 :                 mod->metric = RIP_METRIC_INFINITY;
     440             :         } else
     441           0 :                 mod->metric = metric;
     442             : 
     443           0 :         mod->used = true;
     444             : 
     445           0 :         return mod;
     446             : }
     447             : 
     448             : /* Free route map's compiled `set metric' value. */
     449           0 : static void route_set_metric_free(void *rule)
     450             : {
     451           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     452           0 : }
     453             : 
     454             : /* Set metric rule structure. */
     455             : static const struct route_map_rule_cmd route_set_metric_cmd = {
     456             :         "metric",
     457             :         route_set_metric,
     458             :         route_set_metric_compile,
     459             :         route_set_metric_free,
     460             : };
     461             : 
     462             : /* `set ip next-hop IP_ADDRESS' */
     463             : 
     464             : /* Set nexthop to object.  object must be pointer to struct attr. */
     465             : static enum route_map_cmd_result_t
     466           0 : route_set_ip_nexthop(void *rule, const struct prefix *prefix,
     467             : 
     468             :                      void *object)
     469             : {
     470           0 :         struct in_addr *address;
     471           0 :         struct rip_info *rinfo;
     472             : 
     473             :         /* Fetch routemap's rule information. */
     474           0 :         address = rule;
     475           0 :         rinfo = object;
     476             : 
     477             :         /* Set next hop value. */
     478           0 :         rinfo->nexthop_out = *address;
     479             : 
     480           0 :         return RMAP_OKAY;
     481             : }
     482             : 
     483             : /* Route map `ip nexthop' compile function.  Given string is converted
     484             :    to struct in_addr structure. */
     485           0 : static void *route_set_ip_nexthop_compile(const char *arg)
     486             : {
     487           0 :         int ret;
     488           0 :         struct in_addr *address;
     489             : 
     490           0 :         address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in_addr));
     491             : 
     492           0 :         ret = inet_aton(arg, address);
     493             : 
     494           0 :         if (ret == 0) {
     495           0 :                 XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
     496           0 :                 return NULL;
     497             :         }
     498             : 
     499             :         return address;
     500             : }
     501             : 
     502             : /* Free route map's compiled `ip nexthop' value. */
     503           0 : static void route_set_ip_nexthop_free(void *rule)
     504             : {
     505           0 :         XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
     506           0 : }
     507             : 
     508             : /* Route map commands for ip nexthop set. */
     509             : static const struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
     510             :         "ip next-hop",
     511             :         route_set_ip_nexthop,
     512             :         route_set_ip_nexthop_compile,
     513             :         route_set_ip_nexthop_free
     514             : };
     515             : 
     516             : /* `set tag TAG' */
     517             : 
     518             : /* Set tag to object.  object must be pointer to struct attr. */
     519             : static enum route_map_cmd_result_t
     520           0 : route_set_tag(void *rule, const struct prefix *prefix, void *object)
     521             : {
     522           0 :         route_tag_t *tag;
     523           0 :         struct rip_info *rinfo;
     524             : 
     525             :         /* Fetch routemap's rule information. */
     526           0 :         tag = rule;
     527           0 :         rinfo = object;
     528             : 
     529             :         /* Set next hop value. */
     530           0 :         rinfo->tag_out = *tag;
     531             : 
     532           0 :         return RMAP_OKAY;
     533             : }
     534             : 
     535             : /* Route map commands for tag set. */
     536             : static const struct route_map_rule_cmd route_set_tag_cmd = {
     537             :         "tag",
     538             :         route_set_tag,
     539             :         route_map_rule_tag_compile,
     540             :         route_map_rule_tag_free
     541             : };
     542             : 
     543             : #define MATCH_STR "Match values from routing table\n"
     544             : #define SET_STR "Set values in destination routing protocol\n"
     545             : 
     546             : /* Route-map init */
     547           5 : void rip_route_map_init(void)
     548             : {
     549           5 :         route_map_init();
     550             : 
     551           5 :         route_map_match_interface_hook(generic_match_add);
     552           5 :         route_map_no_match_interface_hook(generic_match_delete);
     553             : 
     554           5 :         route_map_match_ip_address_hook(generic_match_add);
     555           5 :         route_map_no_match_ip_address_hook(generic_match_delete);
     556             : 
     557           5 :         route_map_match_ip_address_prefix_list_hook(generic_match_add);
     558           5 :         route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
     559             : 
     560           5 :         route_map_match_ip_next_hop_hook(generic_match_add);
     561           5 :         route_map_no_match_ip_next_hop_hook(generic_match_delete);
     562             : 
     563           5 :         route_map_match_ip_next_hop_prefix_list_hook(generic_match_add);
     564           5 :         route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete);
     565             : 
     566           5 :         route_map_match_ip_next_hop_type_hook(generic_match_add);
     567           5 :         route_map_no_match_ip_next_hop_type_hook(generic_match_delete);
     568             : 
     569           5 :         route_map_match_metric_hook(generic_match_add);
     570           5 :         route_map_no_match_metric_hook(generic_match_delete);
     571             : 
     572           5 :         route_map_match_tag_hook(generic_match_add);
     573           5 :         route_map_no_match_tag_hook(generic_match_delete);
     574             : 
     575           5 :         route_map_set_ip_nexthop_hook(generic_set_add);
     576           5 :         route_map_no_set_ip_nexthop_hook(generic_set_delete);
     577             : 
     578           5 :         route_map_set_metric_hook(generic_set_add);
     579           5 :         route_map_no_set_metric_hook(generic_set_delete);
     580             : 
     581           5 :         route_map_set_tag_hook(generic_set_add);
     582           5 :         route_map_no_set_tag_hook(generic_set_delete);
     583             : 
     584           5 :         route_map_install_match(&route_match_metric_cmd);
     585           5 :         route_map_install_match(&route_match_interface_cmd);
     586           5 :         route_map_install_match(&route_match_ip_next_hop_cmd);
     587           5 :         route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
     588           5 :         route_map_install_match(&route_match_ip_next_hop_type_cmd);
     589           5 :         route_map_install_match(&route_match_ip_address_cmd);
     590           5 :         route_map_install_match(&route_match_ip_address_prefix_list_cmd);
     591           5 :         route_map_install_match(&route_match_tag_cmd);
     592             : 
     593           5 :         route_map_install_set(&route_set_metric_cmd);
     594           5 :         route_map_install_set(&route_set_ip_nexthop_cmd);
     595           5 :         route_map_install_set(&route_set_tag_cmd);
     596           5 : }

Generated by: LCOV version v1.16-topotato