]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_routemap.c
topotests: increase OSPF convergence speed
[mirror_frr.git] / ospfd / ospf_routemap.c
CommitLineData
718e3744 1/*
2 * Route map function of ospfd.
3 * Copyright (C) 2000 IP Infusion Inc.
4 *
5 * Written by Toshiaki Takada.
6 *
7 * This file is part of GNU Zebra.
8 *
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
12 * later version.
13 *
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
896014f4
DL
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 22 */
23
24#include <zebra.h>
25
26#include "memory.h"
27#include "prefix.h"
28#include "table.h"
82f97584 29#include "vty.h"
718e3744 30#include "routemap.h"
31#include "command.h"
32#include "log.h"
33#include "plist.h"
1306c09a 34#include "vrf.h"
5d5ba018 35#include "frrstr.h"
a623b526 36#include "northbound_cli.h"
718e3744 37
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_asbr.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_route.h"
43#include "ospfd/ospf_zebra.h"
45301f8c 44#include "ospfd/ospf_errors.h"
718e3744 45
46/* Hook function for updating route_map assignment. */
d62a17ae 47static void ospf_route_map_update(const char *name)
48{
49 struct ospf *ospf;
50 int type;
b5a8894d 51 struct listnode *n1 = NULL;
d62a17ae 52
53 /* If OSPF instatnce does not exist, return right now. */
b5a8894d 54 if (listcount(om->ospf) == 0)
d62a17ae 55 return;
56
43b8d1d8 57 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
b5a8894d
CS
58 /* Update route-map */
59 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
60 struct list *red_list;
61 struct listnode *node;
62 struct ospf_redist *red;
63
64 red_list = ospf->redist[type];
65 if (!red_list)
66 continue;
67
68 for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
69 if (ROUTEMAP_NAME(red)
70 && strcmp(ROUTEMAP_NAME(red), name) == 0) {
71 /* Keep old route-map. */
72 struct route_map *old = ROUTEMAP(red);
73
0fddd864
IR
74 ROUTEMAP(red) =
75 route_map_lookup_by_name(
76 ROUTEMAP_NAME(red));
77
78 if (!old)
79 route_map_counter_increment(
80 ROUTEMAP(red));
81
996c9314
LB
82 /* No update for this distribute type.
83 */
84 if (old == NULL
85 && ROUTEMAP(red) == NULL)
b5a8894d
CS
86 continue;
87
996c9314
LB
88 ospf_distribute_list_update(
89 ospf, type, red->instance);
b5a8894d 90 }
d62a17ae 91 }
92 }
93 }
718e3744 94}
95
097b5973 96static void ospf_route_map_event(const char *name)
718e3744 97{
d62a17ae 98 struct ospf *ospf;
99 int type;
b5a8894d
CS
100 struct listnode *n1 = NULL;
101
102 for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
103 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
104 struct list *red_list;
105 struct listnode *node;
106 struct ospf_redist *red;
107
108 red_list = ospf->redist[type];
109 if (!red_list)
110 continue;
111
112 for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
113 if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
114 && !strcmp(ROUTEMAP_NAME(red), name)) {
996c9314
LB
115 ospf_distribute_list_update(
116 ospf, type, red->instance);
b5a8894d 117 }
d62a17ae 118 }
119 }
120 }
718e3744 121}
122
718e3744 123/* `match ip netxthop ' */
124/* Match function return 1 if match is success else return zero. */
b68885f9 125static enum route_map_cmd_result_t
1782514f 126route_match_ip_nexthop(void *rule, const struct prefix *prefix, void *object)
d62a17ae 127{
128 struct access_list *alist;
129 struct external_info *ei = object;
130 struct prefix_ipv4 p;
131
1782514f
DS
132 p.family = AF_INET;
133 p.prefix = ei->nexthop;
134 p.prefixlen = IPV4_MAX_BITLEN;
d62a17ae 135
1782514f
DS
136 alist = access_list_lookup(AFI_IP, (char *)rule);
137 if (alist == NULL)
138 return RMAP_NOMATCH;
d62a17ae 139
1782514f
DS
140 return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH
141 : RMAP_MATCH);
718e3744 142}
143
144/* Route map `ip next-hop' match statement. `arg' should be
145 access-list name. */
d62a17ae 146static void *route_match_ip_nexthop_compile(const char *arg)
718e3744 147{
d62a17ae 148 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 149}
150
151/* Free route map's compiled `ip address' value. */
d62a17ae 152static void route_match_ip_nexthop_free(void *rule)
718e3744 153{
d62a17ae 154 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 155}
156
157/* Route map commands for metric matching. */
364deb04
DL
158static const struct route_map_rule_cmd route_match_ip_nexthop_cmd = {
159 "ip next-hop",
160 route_match_ip_nexthop,
161 route_match_ip_nexthop_compile,
162 route_match_ip_nexthop_free
163};
718e3744 164
165/* `match ip next-hop prefix-list PREFIX_LIST' */
166
b68885f9 167static enum route_map_cmd_result_t
123214ef 168route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
1782514f 169 void *object)
718e3744 170{
d62a17ae 171 struct prefix_list *plist;
172 struct external_info *ei = object;
173 struct prefix_ipv4 p;
174
1782514f
DS
175 p.family = AF_INET;
176 p.prefix = ei->nexthop;
177 p.prefixlen = IPV4_MAX_BITLEN;
d62a17ae 178
1782514f
DS
179 plist = prefix_list_lookup(AFI_IP, (char *)rule);
180 if (plist == NULL)
181 return RMAP_NOMATCH;
d62a17ae 182
1782514f
DS
183 return (prefix_list_apply(plist, &p) == PREFIX_DENY ? RMAP_NOMATCH
184 : RMAP_MATCH);
718e3744 185}
186
d62a17ae 187static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
718e3744 188{
d62a17ae 189 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 190}
191
d62a17ae 192static void route_match_ip_next_hop_prefix_list_free(void *rule)
718e3744 193{
d62a17ae 194 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 195}
196
364deb04
DL
197static const struct route_map_rule_cmd
198 route_match_ip_next_hop_prefix_list_cmd = {
199 "ip next-hop prefix-list",
200 route_match_ip_next_hop_prefix_list,
d62a17ae 201 route_match_ip_next_hop_prefix_list_compile,
364deb04
DL
202 route_match_ip_next_hop_prefix_list_free
203};
718e3744 204
b6c0e913
DA
205/* `match ip next-hop type <blackhole>' */
206
b68885f9 207static enum route_map_cmd_result_t
b6c0e913 208route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
1782514f 209 void *object)
b6c0e913
DA
210{
211 struct external_info *ei = object;
212
1782514f 213 if (prefix->family == AF_INET) {
b6c0e913
DA
214 ei = (struct external_info *)object;
215 if (!ei)
b68885f9 216 return RMAP_NOMATCH;
b6c0e913
DA
217
218 if (ei->nexthop.s_addr == INADDR_ANY && !ei->ifindex)
219 return RMAP_MATCH;
220 }
221 return RMAP_NOMATCH;
222}
223
224static void *route_match_ip_next_hop_type_compile(const char *arg)
225{
226 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
227}
228
229static void route_match_ip_next_hop_type_free(void *rule)
230{
231 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
232}
233
364deb04
DL
234static const struct route_map_rule_cmd
235 route_match_ip_next_hop_type_cmd = {
236 "ip next-hop type",
237 route_match_ip_next_hop_type,
b6c0e913 238 route_match_ip_next_hop_type_compile,
364deb04
DL
239 route_match_ip_next_hop_type_free
240};
b6c0e913 241
718e3744 242/* `match ip address IP_ACCESS_LIST' */
243/* Match function should return 1 if match is success else return
244 zero. */
b68885f9 245static enum route_map_cmd_result_t
1782514f 246route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
d62a17ae 247{
248 struct access_list *alist;
249 /* struct prefix_ipv4 match; */
250
1782514f
DS
251 alist = access_list_lookup(AFI_IP, (char *)rule);
252 if (alist == NULL)
253 return RMAP_NOMATCH;
d62a17ae 254
1782514f
DS
255 return (access_list_apply(alist, prefix) == FILTER_DENY ? RMAP_NOMATCH
256 : RMAP_MATCH);
718e3744 257}
258
259/* Route map `ip address' match statement. `arg' should be
260 access-list name. */
d62a17ae 261static void *route_match_ip_address_compile(const char *arg)
718e3744 262{
d62a17ae 263 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 264}
265
266/* Free route map's compiled `ip address' value. */
d62a17ae 267static void route_match_ip_address_free(void *rule)
718e3744 268{
d62a17ae 269 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 270}
271
272/* Route map commands for ip address matching. */
364deb04
DL
273static const struct route_map_rule_cmd route_match_ip_address_cmd = {
274 "ip address",
275 route_match_ip_address,
276 route_match_ip_address_compile,
277 route_match_ip_address_free
278};
718e3744 279
280/* `match ip address prefix-list PREFIX_LIST' */
b68885f9 281static enum route_map_cmd_result_t
123214ef 282route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
1782514f 283 void *object)
718e3744 284{
d62a17ae 285 struct prefix_list *plist;
286
1782514f
DS
287 plist = prefix_list_lookup(AFI_IP, (char *)rule);
288 if (plist == NULL)
289 return RMAP_NOMATCH;
d62a17ae 290
1782514f
DS
291 return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
292 : RMAP_MATCH);
718e3744 293}
294
d62a17ae 295static void *route_match_ip_address_prefix_list_compile(const char *arg)
718e3744 296{
d62a17ae 297 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 298}
299
d62a17ae 300static void route_match_ip_address_prefix_list_free(void *rule)
718e3744 301{
d62a17ae 302 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 303}
304
364deb04
DL
305static const struct route_map_rule_cmd
306 route_match_ip_address_prefix_list_cmd = {
307 "ip address prefix-list",
308 route_match_ip_address_prefix_list,
d62a17ae 309 route_match_ip_address_prefix_list_compile,
364deb04
DL
310 route_match_ip_address_prefix_list_free
311};
718e3744 312
313/* `match interface IFNAME' */
314/* Match function should return 1 if match is success else return
315 zero. */
b68885f9 316static enum route_map_cmd_result_t
1782514f 317route_match_interface(void *rule, const struct prefix *prefix, void *object)
718e3744 318{
d62a17ae 319 struct interface *ifp;
320 struct external_info *ei;
718e3744 321
1782514f
DS
322 ei = object;
323 ifp = if_lookup_by_name_all_vrf((char *)rule);
718e3744 324
1782514f
DS
325 if (ifp == NULL || ifp->ifindex != ei->ifindex)
326 return RMAP_NOMATCH;
718e3744 327
1782514f 328 return RMAP_MATCH;
718e3744 329}
330
331/* Route map `interface' match statement. `arg' should be
332 interface name. */
d62a17ae 333static void *route_match_interface_compile(const char *arg)
718e3744 334{
d62a17ae 335 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 336}
337
338/* Free route map's compiled `interface' value. */
d62a17ae 339static void route_match_interface_free(void *rule)
718e3744 340{
d62a17ae 341 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 342}
343
344/* Route map commands for ip address matching. */
364deb04
DL
345static const struct route_map_rule_cmd route_match_interface_cmd = {
346 "interface",
347 route_match_interface,
348 route_match_interface_compile,
349 route_match_interface_free
350};
718e3744 351
0d9551dc 352/* Match function return 1 if match is success else return zero. */
b68885f9 353static enum route_map_cmd_result_t
1782514f 354route_match_tag(void *rule, const struct prefix *prefix, void *object)
0d9551dc 355{
d62a17ae 356 route_tag_t *tag;
357 struct external_info *ei;
0d9551dc 358
1782514f
DS
359 tag = rule;
360 ei = object;
0d9551dc 361
1782514f 362 return ((ei->tag == *tag) ? RMAP_MATCH : RMAP_NOMATCH);
0d9551dc
DS
363}
364
0d9551dc 365/* Route map commands for tag matching. */
364deb04
DL
366static const struct route_map_rule_cmd route_match_tag_cmd = {
367 "tag",
368 route_match_tag,
369 route_map_rule_tag_compile,
d62a17ae 370 route_map_rule_tag_free,
0d9551dc
DS
371};
372
6a74c5f9 373struct ospf_metric {
7a5e6e46 374 enum { metric_increment, metric_decrement, metric_absolute } type;
6a74c5f9 375 bool used;
d7c0a89a 376 uint32_t metric;
6a74c5f9 377};
0d9551dc 378
718e3744 379/* `set metric METRIC' */
380/* Set metric to attribute. */
b68885f9 381static enum route_map_cmd_result_t
1782514f 382route_set_metric(void *rule, const struct prefix *prefix, void *object)
718e3744 383{
6a74c5f9 384 struct ospf_metric *metric;
d62a17ae 385 struct external_info *ei;
386
1782514f
DS
387 /* Fetch routemap's rule information. */
388 metric = rule;
389 ei = object;
d62a17ae 390
1782514f
DS
391 /* Set metric out value. */
392 if (!metric->used)
393 return RMAP_OKAY;
236e900c 394
1782514f 395 ei->route_map_set.metric = DEFAULT_DEFAULT_METRIC;
236e900c 396
1782514f
DS
397 if (metric->type == metric_increment)
398 ei->route_map_set.metric += metric->metric;
399 else if (metric->type == metric_decrement)
400 ei->route_map_set.metric -= metric->metric;
401 else if (metric->type == metric_absolute)
402 ei->route_map_set.metric = metric->metric;
403
404 if (ei->route_map_set.metric > OSPF_LS_INFINITY)
405 ei->route_map_set.metric = OSPF_LS_INFINITY;
7a5e6e46 406
d62a17ae 407 return RMAP_OKAY;
718e3744 408}
409
410/* set metric compilation. */
d62a17ae 411static void *route_set_metric_compile(const char *arg)
412{
6a74c5f9
DS
413 struct ospf_metric *metric;
414
cf0f13de 415 metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*metric));
6a74c5f9 416 metric->used = false;
d62a17ae 417
7a5e6e46 418 if (all_digit(arg))
419 metric->type = metric_absolute;
420
421 if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) {
cf444bcf 422 flog_warn(EC_OSPF_SET_METRIC_PLUS,
45301f8c 423 "OSPF does not support 'set metric +rtt / -rtt'");
7a5e6e46 424 return metric;
425 }
426
427 if ((arg[0] == '+') && all_digit(arg + 1)) {
428 metric->type = metric_increment;
429 arg++;
ed2eb093 430 }
7a5e6e46 431
432 if ((arg[0] == '-') && all_digit(arg + 1)) {
433 metric->type = metric_decrement;
434 arg++;
435 }
436
6a74c5f9 437 metric->metric = strtoul(arg, NULL, 10);
7a5e6e46 438
439 if (metric->metric)
440 metric->used = true;
d62a17ae 441
442 return metric;
718e3744 443}
444
445/* Free route map's compiled `set metric' value. */
d62a17ae 446static void route_set_metric_free(void *rule)
718e3744 447{
d62a17ae 448 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 449}
450
451/* Set metric rule structure. */
364deb04
DL
452static const struct route_map_rule_cmd route_set_metric_cmd = {
453 "metric",
454 route_set_metric,
455 route_set_metric_compile,
d62a17ae 456 route_set_metric_free,
718e3744 457};
458
459/* `set metric-type TYPE' */
460/* Set metric-type to attribute. */
b68885f9 461static enum route_map_cmd_result_t
1782514f 462route_set_metric_type(void *rule, const struct prefix *prefix, void *object)
718e3744 463{
d7c0a89a 464 uint32_t *metric_type;
d62a17ae 465 struct external_info *ei;
466
1782514f
DS
467 /* Fetch routemap's rule information. */
468 metric_type = rule;
469 ei = object;
470
471 /* Set metric out value. */
472 ei->route_map_set.metric_type = *metric_type;
d62a17ae 473
d62a17ae 474 return RMAP_OKAY;
718e3744 475}
476
477/* set metric-type compilation. */
d62a17ae 478static void *route_set_metric_type_compile(const char *arg)
718e3744 479{
d7c0a89a 480 uint32_t *metric_type;
718e3744 481
d7c0a89a 482 metric_type = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
d62a17ae 483 if (strcmp(arg, "type-1") == 0)
484 *metric_type = EXTERNAL_METRIC_TYPE_1;
485 else if (strcmp(arg, "type-2") == 0)
486 *metric_type = EXTERNAL_METRIC_TYPE_2;
718e3744 487
d62a17ae 488 if (*metric_type == EXTERNAL_METRIC_TYPE_1
489 || *metric_type == EXTERNAL_METRIC_TYPE_2)
490 return metric_type;
718e3744 491
d62a17ae 492 XFREE(MTYPE_ROUTE_MAP_COMPILED, metric_type);
493 return NULL;
718e3744 494}
495
496/* Free route map's compiled `set metric-type' value. */
d62a17ae 497static void route_set_metric_type_free(void *rule)
718e3744 498{
d62a17ae 499 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
718e3744 500}
501
502/* Set metric rule structure. */
364deb04
DL
503static const struct route_map_rule_cmd route_set_metric_type_cmd = {
504 "metric-type",
505 route_set_metric_type,
506 route_set_metric_type_compile,
d62a17ae 507 route_set_metric_type_free,
718e3744 508};
509
b68885f9 510static enum route_map_cmd_result_t
1782514f 511route_set_tag(void *rule, const struct prefix *prefix, void *object)
0d9551dc 512{
d62a17ae 513 route_tag_t *tag;
514 struct external_info *ei;
0d9551dc 515
1782514f
DS
516 tag = rule;
517 ei = object;
0d9551dc 518
1782514f
DS
519 /* Set tag value */
520 ei->tag = *tag;
0d9551dc 521
d62a17ae 522 return RMAP_OKAY;
0d9551dc
DS
523}
524
0d9551dc 525/* Route map commands for tag set. */
364deb04
DL
526static const struct route_map_rule_cmd route_set_tag_cmd = {
527 "tag",
528 route_set_tag,
529 route_map_rule_tag_compile,
d62a17ae 530 route_map_rule_tag_free,
0d9551dc
DS
531};
532
a623b526 533DEFUN_YANG (set_metric_type,
718e3744 534 set_metric_type_cmd,
6147e2c6 535 "set metric-type <type-1|type-2>",
718e3744 536 SET_STR
537 "Type of metric for destination routing protocol\n"
73ffb25b 538 "OSPF[6] external type 1 metric\n"
539 "OSPF[6] external type 2 metric\n")
718e3744 540{
d62a17ae 541 char *ext = argv[2]->text;
a623b526
SP
542
543 const char *xpath =
544 "./set-action[action='frr-ospf-route-map:metric-type']";
545 char xpath_value[XPATH_MAXLEN];
546
547 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
548 snprintf(xpath_value, sizeof(xpath_value),
549 "%s/rmap-set-action/frr-ospf-route-map:metric-type", xpath);
550 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ext);
551 return nb_cli_apply_changes(vty, NULL);
718e3744 552}
553
a623b526 554DEFUN_YANG (no_set_metric_type,
718e3744 555 no_set_metric_type_cmd,
692b4c65 556 "no set metric-type [<type-1|type-2>]",
718e3744 557 NO_STR
558 SET_STR
ff788d08 559 "Type of metric for destination routing protocol\n"
692b4c65 560 "OSPF[6] external type 1 metric\n"
ff788d08 561 "OSPF[6] external type 2 metric\n")
718e3744 562{
a623b526
SP
563 const char *xpath =
564 "./set-action[action='frr-ospf-route-map:metric-type']";
565
566 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
567 return nb_cli_apply_changes(vty, NULL);
0d9551dc
DS
568}
569
718e3744 570/* Route-map init */
d62a17ae 571void ospf_route_map_init(void)
718e3744 572{
d62a17ae 573 route_map_init();
574
575 route_map_add_hook(ospf_route_map_update);
576 route_map_delete_hook(ospf_route_map_update);
577 route_map_event_hook(ospf_route_map_event);
718e3744 578
d62a17ae 579 route_map_set_metric_hook(generic_set_add);
580 route_map_no_set_metric_hook(generic_set_delete);
82f97584 581
d62a17ae 582 route_map_match_ip_next_hop_hook(generic_match_add);
583 route_map_no_match_ip_next_hop_hook(generic_match_delete);
58b0878a 584
d62a17ae 585 route_map_match_interface_hook(generic_match_add);
586 route_map_no_match_interface_hook(generic_match_delete);
58b0878a 587
d62a17ae 588 route_map_match_ip_address_hook(generic_match_add);
589 route_map_no_match_ip_address_hook(generic_match_delete);
82f97584 590
d62a17ae 591 route_map_match_ip_address_prefix_list_hook(generic_match_add);
592 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
82f97584 593
d62a17ae 594 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add);
595 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete);
82f97584 596
b6c0e913
DA
597 route_map_match_ip_next_hop_type_hook(generic_match_add);
598 route_map_no_match_ip_next_hop_type_hook(generic_match_delete);
599
d62a17ae 600 route_map_match_tag_hook(generic_match_add);
601 route_map_no_match_tag_hook(generic_match_delete);
82f97584 602
d62a17ae 603 route_map_set_metric_hook(generic_set_add);
604 route_map_no_set_metric_hook(generic_set_delete);
82f97584 605
d62a17ae 606 route_map_set_tag_hook(generic_set_add);
607 route_map_no_set_tag_hook(generic_set_delete);
82f97584 608
d62a17ae 609 route_map_install_match(&route_match_ip_nexthop_cmd);
610 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
611 route_map_install_match(&route_match_ip_address_cmd);
612 route_map_install_match(&route_match_ip_address_prefix_list_cmd);
b6c0e913 613 route_map_install_match(&route_match_ip_next_hop_type_cmd);
d62a17ae 614 route_map_install_match(&route_match_interface_cmd);
615 route_map_install_match(&route_match_tag_cmd);
718e3744 616
d62a17ae 617 route_map_install_set(&route_set_metric_cmd);
618 route_map_install_set(&route_set_metric_type_cmd);
619 route_map_install_set(&route_set_tag_cmd);
718e3744 620
d62a17ae 621 install_element(RMAP_NODE, &set_metric_type_cmd);
622 install_element(RMAP_NODE, &no_set_metric_type_cmd);
718e3744 623}