2 * Copyright (C) 2006 IBM Corporation
4 * This file is part of GNU Zebra.
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
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.
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
24 #include "zebra_memory.h"
35 #include "zebra/zserv.h"
36 #include "zebra/redistribute.h"
37 #include "zebra/debug.h"
38 #include "zebra/zebra_rnh.h"
39 #include "zebra/zebra_routemap.h"
41 static u_int32_t zebra_rmap_update_timer
= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
;
42 static struct thread
*zebra_t_rmap_update
= NULL
;
43 char *proto_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+ 1]; /* "any" == ZEBRA_ROUTE_MAX */
44 /* NH Tracking route map */
45 char *nht_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+ 1]; /* "any" == ZEBRA_ROUTE_MAX */
46 char *zebra_import_table_routemap
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
49 struct nexthop
*nexthop
;
51 u_int32_t source_protocol
;
56 static void zebra_route_map_set_delay_timer(u_int32_t value
);
59 /* Add zebra route map rule */
60 static int zebra_route_match_add(struct vty
*vty
, const char *command
,
61 const char *arg
, route_map_event_t type
)
63 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
65 int retval
= CMD_SUCCESS
;
67 ret
= route_map_add_match(index
, command
, arg
);
69 case RMAP_RULE_MISSING
:
70 vty_out(vty
, "%% Zebra Can't find rule.\n");
71 retval
= CMD_WARNING_CONFIG_FAILED
;
73 case RMAP_COMPILE_ERROR
:
74 vty_out(vty
, "%% Zebra Argument is malformed.\n");
75 retval
= CMD_WARNING_CONFIG_FAILED
;
77 case RMAP_COMPILE_SUCCESS
:
78 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
79 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
87 /* Delete zebra route map rule. */
88 static int zebra_route_match_delete(struct vty
*vty
, const char *command
,
89 const char *arg
, route_map_event_t type
)
91 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
93 int retval
= CMD_SUCCESS
;
94 char *dep_name
= NULL
;
96 char *rmap_name
= NULL
;
98 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
99 /* ignore the mundane, the types without any dependency */
101 if ((tmpstr
= route_map_get_match_arg(index
, command
))
104 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
106 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
108 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
111 ret
= route_map_delete_match(index
, command
, arg
);
113 case RMAP_RULE_MISSING
:
114 vty_out(vty
, "%% Zebra Can't find rule.\n");
115 retval
= CMD_WARNING_CONFIG_FAILED
;
117 case RMAP_COMPILE_ERROR
:
118 vty_out(vty
, "%% Zebra Argument is malformed.\n");
119 retval
= CMD_WARNING_CONFIG_FAILED
;
121 case RMAP_COMPILE_SUCCESS
:
122 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
123 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
128 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
130 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
136 * Match function return 1 if match is success else return 0
138 static route_map_result_t
route_match_tag(void *rule
, struct prefix
*prefix
,
139 route_map_object_t type
, void *object
)
142 struct nh_rmap_obj
*nh_data
;
144 if (type
== RMAP_ZEBRA
) {
148 if (nh_data
->tag
== *tag
)
154 /* Route map commands for tag matching */
155 static struct route_map_rule_cmd route_match_tag_cmd
= {
156 "tag", route_match_tag
, route_map_rule_tag_compile
,
157 route_map_rule_tag_free
,
161 /* `match interface IFNAME' */
162 /* Match function return 1 if match is success else return zero. */
163 static route_map_result_t
route_match_interface(void *rule
,
164 struct prefix
*prefix
,
165 route_map_object_t type
,
168 struct nh_rmap_obj
*nh_data
;
172 if (type
== RMAP_ZEBRA
) {
173 if (strcasecmp(ifname
, "any") == 0)
176 if (!nh_data
|| !nh_data
->nexthop
)
178 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
181 if (nh_data
->nexthop
->ifindex
== ifindex
)
187 /* Route map `match interface' match statement. `arg' is IFNAME value */
188 static void *route_match_interface_compile(const char *arg
)
190 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
193 /* Free route map's compiled `match interface' value. */
194 static void route_match_interface_free(void *rule
)
196 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
199 /* Route map commands for interface matching */
200 struct route_map_rule_cmd route_match_interface_cmd
= {
201 "interface", route_match_interface
, route_match_interface_compile
,
202 route_match_interface_free
};
204 DEFUN (match_ip_address_prefix_len
,
205 match_ip_address_prefix_len_cmd
,
206 "match ip address prefix-len (0-32)",
209 "Match prefix length of ip address\n"
210 "Match prefix length of ip address\n"
213 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
214 RMAP_EVENT_MATCH_ADDED
);
217 DEFUN (no_match_ip_address_prefix_len
,
218 no_match_ip_address_prefix_len_cmd
,
219 "no match ip address prefix-len [(0-32)]",
223 "Match prefix length of ip address\n"
224 "Match prefix length of ip address\n"
227 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
228 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
229 RMAP_EVENT_MATCH_DELETED
);
233 DEFUN (match_ip_nexthop_prefix_len
,
234 match_ip_nexthop_prefix_len_cmd
,
235 "match ip next-hop prefix-len (0-32)",
238 "Match prefixlen of nexthop ip address\n"
239 "Match prefixlen of given nexthop\n"
242 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
243 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
246 DEFUN (no_match_ip_nexthop_prefix_len
,
247 no_match_ip_nexthop_prefix_len_cmd
,
248 "no match ip next-hop prefix-len [(0-32)]",
252 "Match prefixlen of nexthop ip address\n"
253 "Match prefix length of nexthop\n"
256 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
257 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
258 RMAP_EVENT_MATCH_DELETED
);
262 DEFUN (match_source_protocol
,
263 match_source_protocol_cmd
,
264 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static>",
266 "Match protocol via which the route was learnt\n"
277 "Routes from directly connected peer\n"
278 "Routes from system configuration\n"
279 "Routes from kernel\n"
280 "Statically configured routes\n")
282 char *proto
= argv
[2]->text
;
285 i
= proto_name2num(proto
);
287 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
288 return CMD_WARNING_CONFIG_FAILED
;
290 return zebra_route_match_add(vty
, "source-protocol", proto
,
291 RMAP_EVENT_MATCH_ADDED
);
294 DEFUN (no_match_source_protocol
,
295 no_match_source_protocol_cmd
,
296 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static>]",
299 "No match protocol via which the route was learnt\n"
310 "Routes from directly connected peer\n"
311 "Routes from system configuration\n"
312 "Routes from kernel\n"
313 "Statically configured routes\n")
315 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
316 return zebra_route_match_delete(vty
, "source-protocol", proto
,
317 RMAP_EVENT_MATCH_DELETED
);
324 "set src <A.B.C.D|X:X::X:X>",
326 "src address for route\n"
328 "IPv6 src address\n")
332 struct interface
*pif
= NULL
;
337 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
338 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
339 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
340 return CMD_WARNING_CONFIG_FAILED
;
343 p
.family
= family
= AF_INET6
;
344 p
.u
.prefix6
= src
.ipv6
;
345 p
.prefixlen
= IPV6_MAX_BITLEN
;
347 p
.family
= family
= AF_INET
;
348 p
.u
.prefix4
= src
.ipv4
;
349 p
.prefixlen
= IPV4_MAX_BITLEN
;
352 if (!zebra_check_addr(&p
)) {
353 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
354 return CMD_WARNING_CONFIG_FAILED
;
357 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
358 if (family
== AF_INET
)
359 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
360 AF_INET
, vrf
->vrf_id
);
361 else if (family
== AF_INET6
)
362 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
363 AF_INET6
, vrf
->vrf_id
);
370 vty_out(vty
, "%% not a local address\n");
371 return CMD_WARNING_CONFIG_FAILED
;
374 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
375 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
380 "no set src [<A.B.C.D|X:X::X:X>]",
383 "Source address for route\n"
387 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
388 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
389 return generic_set_delete(vty
, index
, "src", ip
);
392 DEFUN (zebra_route_map_timer
,
393 zebra_route_map_timer_cmd
,
394 "zebra route-map delay-timer (0-600)",
396 "Set route-map parameters\n"
397 "Time to wait before route-map updates are processed\n"
398 "0 means event-driven updates are disabled\n")
401 u_int32_t rmap_delay_timer
;
403 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
404 zebra_route_map_set_delay_timer(rmap_delay_timer
);
406 return (CMD_SUCCESS
);
409 DEFUN (no_zebra_route_map_timer
,
410 no_zebra_route_map_timer_cmd
,
411 "no zebra route-map delay-timer [(0-600)]",
414 "Set route-map parameters\n"
415 "Reset delay-timer to default value, 30 secs\n"
416 "0 means event-driven updates are disabled\n")
418 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
420 return (CMD_SUCCESS
);
426 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
428 "Filter routing info exchanged between zebra and protocol\n"
429 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
430 "Specify route-map\n"
433 char *proto
= argv
[2]->text
;
434 char *rmap
= argv
[4]->arg
;
437 if (strcasecmp(proto
, "any") == 0)
440 i
= proto_name2num(proto
);
442 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
443 return CMD_WARNING_CONFIG_FAILED
;
445 if (proto_rm
[AFI_IP
][i
]) {
446 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
449 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
451 proto_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
453 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
455 "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
458 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
462 DEFUN (no_ip_protocol
,
464 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
467 "Stop filtering routing info between zebra and protocol\n"
468 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
469 "Specify route map\n"
472 char *proto
= argv
[3]->text
;
473 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
476 if (strcasecmp(proto
, "any") == 0)
479 i
= proto_name2num(proto
);
482 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
483 return CMD_WARNING_CONFIG_FAILED
;
486 if (!proto_rm
[AFI_IP
][i
])
489 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP
][i
]) == 0) {
490 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
491 proto_rm
[AFI_IP
][i
] = NULL
;
493 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
495 "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
497 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
502 DEFUN (show_ip_protocol
,
503 show_ip_protocol_cmd
,
507 "IP protocol filtering status\n")
511 vty_out(vty
, "Protocol : route-map \n");
512 vty_out(vty
, "------------------------\n");
513 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
514 if (proto_rm
[AFI_IP
][i
])
515 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
516 proto_rm
[AFI_IP
][i
]);
518 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
520 if (proto_rm
[AFI_IP
][i
])
521 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP
][i
]);
523 vty_out(vty
, "%-10s : none\n", "any");
528 DEFUN (ipv6_protocol
,
530 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
532 "Filter IPv6 routing info exchanged between zebra and protocol\n"
533 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
534 "Specify route map\n"
537 char *proto
= argv
[2]->text
;
538 char *rmap
= argv
[4]->arg
;
541 if (strcasecmp(proto
, "any") == 0)
544 i
= proto_name2num(proto
);
546 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
547 return CMD_WARNING_CONFIG_FAILED
;
549 if (proto_rm
[AFI_IP6
][i
]) {
550 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
553 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
555 proto_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
557 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
559 "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
562 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
566 DEFUN (no_ipv6_protocol
,
567 no_ipv6_protocol_cmd
,
568 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
571 "Stop filtering IPv6 routing info between zebra and protocol\n"
572 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
573 "Specify route map\n"
576 const char *proto
= argv
[3]->text
;
577 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
580 if (strcasecmp(proto
, "any") == 0)
583 i
= proto_name2num(proto
);
585 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
586 return CMD_WARNING_CONFIG_FAILED
;
588 if (!proto_rm
[AFI_IP6
][i
])
591 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0) {
592 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
593 proto_rm
[AFI_IP6
][i
] = NULL
;
595 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
597 "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
600 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
605 DEFUN (show_ipv6_protocol
,
606 show_ipv6_protocol_cmd
,
607 "show ipv6 protocol",
610 "IPv6 protocol filtering status\n")
614 vty_out(vty
, "Protocol : route-map \n");
615 vty_out(vty
, "------------------------\n");
616 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
617 if (proto_rm
[AFI_IP6
][i
])
618 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
619 proto_rm
[AFI_IP6
][i
]);
621 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
623 if (proto_rm
[AFI_IP6
][i
])
624 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP6
][i
]);
626 vty_out(vty
, "%-10s : none\n", "any");
631 DEFUN (ip_protocol_nht_rmap
,
632 ip_protocol_nht_rmap_cmd
,
633 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
635 "Filter Next Hop tracking route resolution\n"
636 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
637 "Specify route map\n"
640 char *proto
= argv
[2]->text
;
641 char *rmap
= argv
[4]->arg
;
644 if (strcasecmp(proto
, "any") == 0)
647 i
= proto_name2num(proto
);
649 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
650 return CMD_WARNING_CONFIG_FAILED
;
652 if (nht_rm
[AFI_IP
][i
]) {
653 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
656 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
659 nht_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
660 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
665 DEFUN (no_ip_protocol_nht_rmap
,
666 no_ip_protocol_nht_rmap_cmd
,
667 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
670 "Filter Next Hop tracking route resolution\n"
671 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
672 "Specify route map\n"
676 char *proto
= argv
[3]->text
;
677 char *rmap
= argv_find(argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
680 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
681 : proto_name2num(proto
);
684 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
685 return CMD_WARNING_CONFIG_FAILED
;
688 if (!nht_rm
[AFI_IP
][i
])
691 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0) {
692 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
693 nht_rm
[AFI_IP
][i
] = NULL
;
694 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
699 DEFUN (show_ip_protocol_nht
,
700 show_ip_protocol_nht_cmd
,
701 "show ip nht route-map",
704 "IP nexthop tracking table\n"
705 "IP Next Hop tracking filtering status\n")
709 vty_out(vty
, "Protocol : route-map \n");
710 vty_out(vty
, "------------------------\n");
711 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
712 if (nht_rm
[AFI_IP
][i
])
713 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
716 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
718 if (nht_rm
[AFI_IP
][i
])
719 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP
][i
]);
721 vty_out(vty
, "%-10s : none\n", "any");
726 DEFUN (ipv6_protocol_nht_rmap
,
727 ipv6_protocol_nht_rmap_cmd
,
728 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
730 "Filter Next Hop tracking route resolution\n"
731 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
732 "Specify route map\n"
735 char *proto
= argv
[2]->text
;
736 char *rmap
= argv
[4]->arg
;
739 if (strcasecmp(proto
, "any") == 0)
742 i
= proto_name2num(proto
);
744 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
745 return CMD_WARNING_CONFIG_FAILED
;
747 if (nht_rm
[AFI_IP6
][i
])
748 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
749 nht_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
750 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
755 DEFUN (no_ipv6_protocol_nht_rmap
,
756 no_ipv6_protocol_nht_rmap_cmd
,
757 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
760 "Filter Next Hop tracking route resolution\n"
761 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
762 "Specify route map\n"
765 char *proto
= argv
[3]->text
;
766 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
769 if (strcasecmp(proto
, "any") == 0)
772 i
= proto_name2num(proto
);
774 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
775 return CMD_WARNING_CONFIG_FAILED
;
778 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
])) {
779 vty_out(vty
, "invalid route-map \"%s\"\n", rmap
);
780 return CMD_WARNING_CONFIG_FAILED
;
783 if (nht_rm
[AFI_IP6
][i
]) {
784 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
785 nht_rm
[AFI_IP6
][i
] = NULL
;
788 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
793 DEFUN (show_ipv6_protocol_nht
,
794 show_ipv6_protocol_nht_cmd
,
795 "show ipv6 nht route-map",
798 "Next Hop filtering status\n"
803 vty_out(vty
, "Protocol : route-map \n");
804 vty_out(vty
, "------------------------\n");
805 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
806 if (nht_rm
[AFI_IP6
][i
])
807 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
810 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
812 if (nht_rm
[AFI_IP
][i
])
813 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP6
][i
]);
815 vty_out(vty
, "%-10s : none\n", "any");
820 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
822 /* `match ip next-hop IP_ACCESS_LIST' */
824 /* Match function return 1 if match is success else return zero. */
825 static route_map_result_t
route_match_ip_next_hop(void *rule
,
826 struct prefix
*prefix
,
827 route_map_object_t type
,
830 struct access_list
*alist
;
831 struct nh_rmap_obj
*nh_data
;
832 struct prefix_ipv4 p
;
834 if (type
== RMAP_ZEBRA
) {
837 return RMAP_DENYMATCH
;
839 switch (nh_data
->nexthop
->type
) {
840 case NEXTHOP_TYPE_IFINDEX
:
841 /* Interface routes can't match ip next-hop */
843 case NEXTHOP_TYPE_IPV4_IFINDEX
:
844 case NEXTHOP_TYPE_IPV4
:
846 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
847 p
.prefixlen
= IPV4_MAX_BITLEN
;
852 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
856 return (access_list_apply(alist
, &p
) == FILTER_DENY
863 /* Route map `ip next-hop' match statement. `arg' should be
865 static void *route_match_ip_next_hop_compile(const char *arg
)
867 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
870 /* Free route map's compiled `. */
871 static void route_match_ip_next_hop_free(void *rule
)
873 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
876 /* Route map commands for ip next-hop matching. */
877 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
878 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
879 route_match_ip_next_hop_free
};
881 /* `match ip next-hop prefix-list PREFIX_LIST' */
883 static route_map_result_t
884 route_match_ip_next_hop_prefix_list(void *rule
, struct prefix
*prefix
,
885 route_map_object_t type
, void *object
)
887 struct prefix_list
*plist
;
888 struct nh_rmap_obj
*nh_data
;
889 struct prefix_ipv4 p
;
891 if (type
== RMAP_ZEBRA
) {
892 nh_data
= (struct nh_rmap_obj
*)object
;
894 return RMAP_DENYMATCH
;
896 switch (nh_data
->nexthop
->type
) {
897 case NEXTHOP_TYPE_IFINDEX
:
898 /* Interface routes can't match ip next-hop */
900 case NEXTHOP_TYPE_IPV4_IFINDEX
:
901 case NEXTHOP_TYPE_IPV4
:
903 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
904 p
.prefixlen
= IPV4_MAX_BITLEN
;
909 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
913 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
920 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
922 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
925 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
927 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
930 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
931 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
932 route_match_ip_next_hop_prefix_list_compile
,
933 route_match_ip_next_hop_prefix_list_free
};
935 /* `match ip address IP_ACCESS_LIST' */
937 /* Match function should return 1 if match is success else return
939 static route_map_result_t
route_match_ip_address(void *rule
,
940 struct prefix
*prefix
,
941 route_map_object_t type
,
944 struct access_list
*alist
;
946 if (type
== RMAP_ZEBRA
) {
947 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
951 return (access_list_apply(alist
, prefix
) == FILTER_DENY
958 /* Route map `ip address' match statement. `arg' should be
960 static void *route_match_ip_address_compile(const char *arg
)
962 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
965 /* Free route map's compiled `ip address' value. */
966 static void route_match_ip_address_free(void *rule
)
968 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
971 /* Route map commands for ip address matching. */
972 static struct route_map_rule_cmd route_match_ip_address_cmd
= {
973 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
974 route_match_ip_address_free
};
976 /* `match ip address prefix-list PREFIX_LIST' */
978 static route_map_result_t
979 route_match_ip_address_prefix_list(void *rule
, struct prefix
*prefix
,
980 route_map_object_t type
, void *object
)
982 struct prefix_list
*plist
;
984 if (type
== RMAP_ZEBRA
) {
985 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
989 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
996 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
998 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1001 static void route_match_ip_address_prefix_list_free(void *rule
)
1003 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1006 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
1007 "ip address prefix-list", route_match_ip_address_prefix_list
,
1008 route_match_ip_address_prefix_list_compile
,
1009 route_match_ip_address_prefix_list_free
};
1012 /* `match ip address prefix-len PREFIXLEN' */
1014 static route_map_result_t
1015 route_match_ip_address_prefix_len(void *rule
, struct prefix
*prefix
,
1016 route_map_object_t type
, void *object
)
1018 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1020 if (type
== RMAP_ZEBRA
) {
1021 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1024 return RMAP_NOMATCH
;
1027 static void *route_match_ip_address_prefix_len_compile(const char *arg
)
1029 u_int32_t
*prefix_len
;
1030 char *endptr
= NULL
;
1031 unsigned long tmpval
;
1033 /* prefix len value shoud be integer. */
1034 if (!all_digit(arg
))
1038 tmpval
= strtoul(arg
, &endptr
, 10);
1039 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1042 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(u_int32_t
));
1047 *prefix_len
= tmpval
;
1051 static void route_match_ip_address_prefix_len_free(void *rule
)
1053 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1056 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
= {
1057 "ip address prefix-len", route_match_ip_address_prefix_len
,
1058 route_match_ip_address_prefix_len_compile
,
1059 route_match_ip_address_prefix_len_free
};
1062 /* `match ip nexthop prefix-len PREFIXLEN' */
1064 static route_map_result_t
1065 route_match_ip_nexthop_prefix_len(void *rule
, struct prefix
*prefix
,
1066 route_map_object_t type
, void *object
)
1068 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1069 struct nh_rmap_obj
*nh_data
;
1070 struct prefix_ipv4 p
;
1072 if (type
== RMAP_ZEBRA
) {
1073 nh_data
= (struct nh_rmap_obj
*)object
;
1074 if (!nh_data
|| !nh_data
->nexthop
)
1075 return RMAP_DENYMATCH
;
1077 switch (nh_data
->nexthop
->type
) {
1078 case NEXTHOP_TYPE_IFINDEX
:
1079 /* Interface routes can't match ip next-hop */
1080 return RMAP_NOMATCH
;
1081 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1082 case NEXTHOP_TYPE_IPV4
:
1084 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1085 p
.prefixlen
= IPV4_MAX_BITLEN
;
1088 return RMAP_NOMATCH
;
1090 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1093 return RMAP_NOMATCH
;
1096 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
= {
1097 "ip next-hop prefix-len", route_match_ip_nexthop_prefix_len
,
1098 route_match_ip_address_prefix_len_compile
, /* reuse */
1099 route_match_ip_address_prefix_len_free
/* reuse */
1102 /* `match source-protocol PROTOCOL' */
1104 static route_map_result_t
route_match_source_protocol(void *rule
,
1105 struct prefix
*prefix
,
1106 route_map_object_t type
,
1109 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1110 struct nh_rmap_obj
*nh_data
;
1112 if (type
== RMAP_ZEBRA
) {
1113 nh_data
= (struct nh_rmap_obj
*)object
;
1115 return RMAP_DENYMATCH
;
1117 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1120 return RMAP_NOMATCH
;
1123 static void *route_match_source_protocol_compile(const char *arg
)
1125 u_int32_t
*rib_type
;
1128 i
= proto_name2num(arg
);
1129 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(u_int32_t
));
1136 static void route_match_source_protocol_free(void *rule
)
1138 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1141 static struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1142 "source-protocol", route_match_source_protocol
,
1143 route_match_source_protocol_compile
, route_match_source_protocol_free
};
1145 /* `set src A.B.C.D' */
1148 static route_map_result_t
route_set_src(void *rule
, struct prefix
*prefix
,
1149 route_map_object_t type
, void *object
)
1151 struct nh_rmap_obj
*nh_data
;
1153 if (type
== RMAP_ZEBRA
) {
1154 nh_data
= (struct nh_rmap_obj
*)object
;
1155 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1160 /* set src compilation. */
1161 static void *route_set_src_compile(const char *arg
)
1163 union g_addr src
, *psrc
;
1165 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1166 || (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1))) {
1167 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1174 /* Free route map's compiled `set src' value. */
1175 static void route_set_src_free(void *rule
)
1177 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1180 /* Set src rule structure. */
1181 static struct route_map_rule_cmd route_set_src_cmd
= {
1182 "src", route_set_src
, route_set_src_compile
, route_set_src_free
,
1185 static int zebra_route_map_update_timer(struct thread
*thread
)
1187 zebra_t_rmap_update
= NULL
;
1189 if (IS_ZEBRA_DEBUG_EVENT
)
1190 zlog_debug("Event driven route-map update triggered");
1192 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1194 "%u: Routemap update-timer fired, scheduling RIB processing",
1197 zebra_import_table_rm_update();
1198 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1199 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1200 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1205 static void zebra_route_map_set_delay_timer(u_int32_t value
)
1207 zebra_rmap_update_timer
= value
;
1208 if (!value
&& zebra_t_rmap_update
) {
1209 /* Event driven route map updates is being disabled */
1210 /* But there's a pending timer. Fire it off now */
1211 thread_cancel(zebra_t_rmap_update
);
1212 zebra_route_map_update_timer(zebra_t_rmap_update
);
1216 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1218 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1219 vty_out(vty
, "zebra route-map delay-timer %d\n",
1220 zebra_rmap_update_timer
);
1224 route_map_result_t
zebra_route_map_check(int family
, int rib_type
,
1226 struct nexthop
*nexthop
,
1227 vrf_id_t vrf_id
, route_tag_t tag
)
1229 struct route_map
*rmap
= NULL
;
1230 route_map_result_t ret
= RMAP_MATCH
;
1231 struct nh_rmap_obj nh_obj
;
1233 nh_obj
.nexthop
= nexthop
;
1234 nh_obj
.vrf_id
= vrf_id
;
1235 nh_obj
.source_protocol
= rib_type
;
1239 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1240 rmap
= route_map_lookup_by_name(proto_rm
[family
][rib_type
]);
1241 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1242 rmap
= route_map_lookup_by_name(
1243 proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1245 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1251 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1253 return zebra_import_table_routemap
[afi
][table
];
1256 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1259 zebra_import_table_routemap
[afi
][table
] =
1260 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1263 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1265 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1269 zebra_import_table_route_map_check(int family
, int re_type
, struct prefix
*p
,
1270 struct nexthop
*nexthop
, vrf_id_t vrf_id
,
1271 route_tag_t tag
, const char *rmap_name
)
1273 struct route_map
*rmap
= NULL
;
1274 route_map_result_t ret
= RMAP_DENYMATCH
;
1275 struct nh_rmap_obj nh_obj
;
1277 nh_obj
.nexthop
= nexthop
;
1278 nh_obj
.vrf_id
= vrf_id
;
1279 nh_obj
.source_protocol
= re_type
;
1283 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1284 rmap
= route_map_lookup_by_name(rmap_name
);
1286 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1292 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1294 struct route_entry
*re
,
1295 struct nexthop
*nexthop
)
1297 struct route_map
*rmap
= NULL
;
1298 route_map_result_t ret
= RMAP_MATCH
;
1299 struct nh_rmap_obj nh_obj
;
1301 nh_obj
.nexthop
= nexthop
;
1302 nh_obj
.vrf_id
= re
->vrf_id
;
1303 nh_obj
.source_protocol
= re
->type
;
1304 nh_obj
.metric
= re
->metric
;
1305 nh_obj
.tag
= re
->tag
;
1307 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1308 rmap
= route_map_lookup_by_name(nht_rm
[family
][client_proto
]);
1309 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1310 rmap
= route_map_lookup_by_name(
1311 nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1313 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1319 static void zebra_route_map_mark_update(const char *rmap_name
)
1321 /* rmap_update_timer of 0 means don't do route updates */
1322 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1323 zebra_t_rmap_update
= NULL
;
1324 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1325 NULL
, zebra_rmap_update_timer
,
1326 &zebra_t_rmap_update
);
1330 static void zebra_route_map_add(const char *rmap_name
)
1332 zebra_route_map_mark_update(rmap_name
);
1333 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1336 static void zebra_route_map_delete(const char *rmap_name
)
1338 zebra_route_map_mark_update(rmap_name
);
1339 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1342 static void zebra_route_map_event(route_map_event_t event
,
1343 const char *rmap_name
)
1345 zebra_route_map_mark_update(rmap_name
);
1346 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1349 /* ip protocol configuration write function */
1350 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1354 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1355 if (proto_rm
[AFI_IP
][i
])
1356 vty_out(vty
, "ip protocol %s route-map %s\n",
1357 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1359 if (proto_rm
[AFI_IP6
][i
])
1360 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1361 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1363 if (nht_rm
[AFI_IP
][i
])
1364 vty_out(vty
, "ip nht %s route-map %s\n",
1365 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1367 if (nht_rm
[AFI_IP6
][i
])
1368 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1369 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1372 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1373 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1374 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1376 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1377 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1378 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1380 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1381 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1382 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1384 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1385 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1386 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1388 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1389 vty_out(vty
, "zebra route-map delay-timer %d\n",
1390 zebra_rmap_update_timer
);
1393 void zebra_route_map_init()
1395 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1396 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1397 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1398 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1399 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1400 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1401 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1402 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1403 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1404 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1405 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1406 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1407 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1408 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1412 route_map_add_hook(zebra_route_map_add
);
1413 route_map_delete_hook(zebra_route_map_delete
);
1414 route_map_event_hook(zebra_route_map_event
);
1416 route_map_match_interface_hook(generic_match_add
);
1417 route_map_no_match_interface_hook(generic_match_delete
);
1419 route_map_match_ip_address_hook(generic_match_add
);
1420 route_map_no_match_ip_address_hook(generic_match_delete
);
1422 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1423 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1425 route_map_match_ip_next_hop_hook(generic_match_add
);
1426 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1428 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1429 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1431 route_map_match_tag_hook(generic_match_add
);
1432 route_map_no_match_tag_hook(generic_match_delete
);
1434 route_map_install_match(&route_match_tag_cmd
);
1435 route_map_install_match(&route_match_interface_cmd
);
1436 route_map_install_match(&route_match_ip_next_hop_cmd
);
1437 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1438 route_map_install_match(&route_match_ip_address_cmd
);
1439 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1440 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1441 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1442 route_map_install_match(&route_match_source_protocol_cmd
);
1444 route_map_install_set(&route_set_src_cmd
);
1446 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1447 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1448 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1449 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1450 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1451 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1453 install_element(RMAP_NODE
, &set_src_cmd
);
1454 install_element(RMAP_NODE
, &no_set_src_cmd
);