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
);
66 ret
= route_map_add_match(index
, command
, arg
);
69 case RMAP_RULE_MISSING
:
70 vty_out(vty
, "%% Zebra Can't find rule.\n");
71 return CMD_WARNING_CONFIG_FAILED
;
72 case RMAP_COMPILE_ERROR
:
73 vty_out(vty
, "%% Zebra Argument is malformed.\n");
74 return CMD_WARNING_CONFIG_FAILED
;
78 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
79 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
84 /* Delete zebra route map rule. */
85 static int zebra_route_match_delete(struct vty
*vty
, const char *command
,
86 const char *arg
, route_map_event_t type
)
88 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
90 char *dep_name
= NULL
;
92 char *rmap_name
= NULL
;
94 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
95 /* ignore the mundane, the types without any dependency */
97 if ((tmpstr
= route_map_get_match_arg(index
, command
))
100 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
102 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
104 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
107 ret
= route_map_delete_match(index
, command
, arg
);
110 case RMAP_RULE_MISSING
:
111 vty_out(vty
, "%% Zebra Can't find rule.\n");
112 return CMD_WARNING_CONFIG_FAILED
;
113 case RMAP_COMPILE_ERROR
:
114 vty_out(vty
, "%% Zebra Argument is malformed.\n");
115 return CMD_WARNING_CONFIG_FAILED
;
119 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
120 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
123 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
125 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
131 * Match function return 1 if match is success else return 0
133 static route_map_result_t
route_match_tag(void *rule
, struct prefix
*prefix
,
134 route_map_object_t type
, void *object
)
137 struct nh_rmap_obj
*nh_data
;
139 if (type
== RMAP_ZEBRA
) {
143 if (nh_data
->tag
== *tag
)
149 /* Route map commands for tag matching */
150 static struct route_map_rule_cmd route_match_tag_cmd
= {
151 "tag", route_match_tag
, route_map_rule_tag_compile
,
152 route_map_rule_tag_free
,
156 /* `match interface IFNAME' */
157 /* Match function return 1 if match is success else return zero. */
158 static route_map_result_t
route_match_interface(void *rule
,
159 struct prefix
*prefix
,
160 route_map_object_t type
,
163 struct nh_rmap_obj
*nh_data
;
167 if (type
== RMAP_ZEBRA
) {
168 if (strcasecmp(ifname
, "any") == 0)
171 if (!nh_data
|| !nh_data
->nexthop
)
173 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
176 if (nh_data
->nexthop
->ifindex
== ifindex
)
182 /* Route map `match interface' match statement. `arg' is IFNAME value */
183 static void *route_match_interface_compile(const char *arg
)
185 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
188 /* Free route map's compiled `match interface' value. */
189 static void route_match_interface_free(void *rule
)
191 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
194 /* Route map commands for interface matching */
195 struct route_map_rule_cmd route_match_interface_cmd
= {
196 "interface", route_match_interface
, route_match_interface_compile
,
197 route_match_interface_free
};
199 DEFUN (match_ip_address_prefix_len
,
200 match_ip_address_prefix_len_cmd
,
201 "match ip address prefix-len (0-32)",
204 "Match prefix length of ip address\n"
205 "Match prefix length of ip address\n"
208 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
209 RMAP_EVENT_MATCH_ADDED
);
212 DEFUN (no_match_ip_address_prefix_len
,
213 no_match_ip_address_prefix_len_cmd
,
214 "no match ip address prefix-len [(0-32)]",
218 "Match prefix length of ip address\n"
219 "Match prefix length of ip address\n"
222 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
223 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
224 RMAP_EVENT_MATCH_DELETED
);
228 DEFUN (match_ip_nexthop_prefix_len
,
229 match_ip_nexthop_prefix_len_cmd
,
230 "match ip next-hop prefix-len (0-32)",
233 "Match prefixlen of nexthop ip address\n"
234 "Match prefixlen of given nexthop\n"
237 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
238 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
241 DEFUN (no_match_ip_nexthop_prefix_len
,
242 no_match_ip_nexthop_prefix_len_cmd
,
243 "no match ip next-hop prefix-len [(0-32)]",
247 "Match prefixlen of nexthop ip address\n"
248 "Match prefix length of nexthop\n"
251 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
252 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
253 RMAP_EVENT_MATCH_DELETED
);
257 DEFUN (match_source_protocol
,
258 match_source_protocol_cmd
,
259 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>",
261 "Match protocol via which the route was learnt\n"
268 "Routes from directly connected peer\n"
269 "Routes from system configuration\n"
270 "Routes from kernel\n"
271 "Statically configured routes\n")
273 char *proto
= argv
[2]->text
;
276 i
= proto_name2num(proto
);
278 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
279 return CMD_WARNING_CONFIG_FAILED
;
281 return zebra_route_match_add(vty
, "source-protocol", proto
,
282 RMAP_EVENT_MATCH_ADDED
);
285 DEFUN (no_match_source_protocol
,
286 no_match_source_protocol_cmd
,
287 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>]",
290 "No match protocol via which the route was learnt\n"
297 "Routes from directly connected peer\n"
298 "Routes from system configuration\n"
299 "Routes from kernel\n"
300 "Statically configured routes\n")
302 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
303 return zebra_route_match_delete(vty
, "source-protocol", proto
,
304 RMAP_EVENT_MATCH_DELETED
);
311 "set src <A.B.C.D|X:X::X:X>",
313 "src address for route\n"
315 "IPv6 src address\n")
319 struct interface
*pif
= NULL
;
324 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
325 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
326 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
327 return CMD_WARNING_CONFIG_FAILED
;
330 p
.family
= family
= AF_INET6
;
331 p
.u
.prefix6
= src
.ipv6
;
332 p
.prefixlen
= IPV6_MAX_BITLEN
;
334 p
.family
= family
= AF_INET
;
335 p
.u
.prefix4
= src
.ipv4
;
336 p
.prefixlen
= IPV4_MAX_BITLEN
;
339 if (!zebra_check_addr(&p
)) {
340 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
341 return CMD_WARNING_CONFIG_FAILED
;
344 RB_FOREACH(vrf
, vrf_id_head
, &vrfs_by_id
)
346 if (family
== AF_INET
)
347 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
348 AF_INET
, vrf
->vrf_id
);
349 else if (family
== AF_INET6
)
350 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
351 AF_INET6
, vrf
->vrf_id
);
358 vty_out(vty
, "%% not a local address\n");
359 return CMD_WARNING_CONFIG_FAILED
;
362 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
363 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
368 "no set src [<A.B.C.D|X:X::X:X>]",
371 "Source address for route\n"
375 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
376 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
377 return generic_set_delete(vty
, index
, "src", ip
);
380 DEFUN (zebra_route_map_timer
,
381 zebra_route_map_timer_cmd
,
382 "zebra route-map delay-timer (0-600)",
383 "Zebra information\n"
384 "Set route-map parameters\n"
385 "Time to wait before route-map updates are processed\n"
386 "0 means event-driven updates are disabled\n")
389 u_int32_t rmap_delay_timer
;
391 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
392 zebra_route_map_set_delay_timer(rmap_delay_timer
);
394 return (CMD_SUCCESS
);
397 DEFUN (no_zebra_route_map_timer
,
398 no_zebra_route_map_timer_cmd
,
399 "no zebra route-map delay-timer [(0-600)]",
401 "Zebra information\n"
402 "Set route-map parameters\n"
403 "Reset delay-timer to default value, 30 secs\n"
404 "0 means event-driven updates are disabled\n")
406 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
408 return (CMD_SUCCESS
);
414 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
416 "Filter routing info exchanged between zebra and protocol\n"
417 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
418 "Specify route-map\n"
421 char *proto
= argv
[2]->text
;
422 char *rmap
= argv
[4]->arg
;
425 if (strcasecmp(proto
, "any") == 0)
428 i
= proto_name2num(proto
);
430 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
431 return CMD_WARNING_CONFIG_FAILED
;
433 if (proto_rm
[AFI_IP
][i
]) {
434 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
437 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
439 proto_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
441 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
443 "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
446 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
450 DEFUN (no_ip_protocol
,
452 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
455 "Stop filtering routing info between zebra and protocol\n"
456 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
457 "Specify route map\n"
460 char *proto
= argv
[3]->text
;
461 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
464 if (strcasecmp(proto
, "any") == 0)
467 i
= proto_name2num(proto
);
470 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
471 return CMD_WARNING_CONFIG_FAILED
;
474 if (!proto_rm
[AFI_IP
][i
])
477 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP
][i
]) == 0) {
478 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
479 proto_rm
[AFI_IP
][i
] = NULL
;
481 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
483 "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
485 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
490 DEFUN (show_ip_protocol
,
491 show_ip_protocol_cmd
,
495 "IP protocol filtering status\n")
499 vty_out(vty
, "Protocol : route-map \n");
500 vty_out(vty
, "------------------------\n");
501 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
502 if (proto_rm
[AFI_IP
][i
])
503 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
504 proto_rm
[AFI_IP
][i
]);
506 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
508 if (proto_rm
[AFI_IP
][i
])
509 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP
][i
]);
511 vty_out(vty
, "%-10s : none\n", "any");
516 DEFUN (ipv6_protocol
,
518 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
520 "Filter IPv6 routing info exchanged between zebra and protocol\n"
521 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
522 "Specify route map\n"
525 char *proto
= argv
[2]->text
;
526 char *rmap
= argv
[4]->arg
;
529 if (strcasecmp(proto
, "any") == 0)
532 i
= proto_name2num(proto
);
534 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
535 return CMD_WARNING_CONFIG_FAILED
;
537 if (proto_rm
[AFI_IP6
][i
]) {
538 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
541 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
543 proto_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
545 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
547 "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
550 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
554 DEFUN (no_ipv6_protocol
,
555 no_ipv6_protocol_cmd
,
556 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
559 "Stop filtering IPv6 routing info between zebra and protocol\n"
560 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
561 "Specify route map\n"
564 const char *proto
= argv
[3]->text
;
565 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
568 if (strcasecmp(proto
, "any") == 0)
571 i
= proto_name2num(proto
);
573 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
574 return CMD_WARNING_CONFIG_FAILED
;
576 if (!proto_rm
[AFI_IP6
][i
])
579 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0) {
580 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
581 proto_rm
[AFI_IP6
][i
] = NULL
;
583 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
585 "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
588 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
593 DEFUN (show_ipv6_protocol
,
594 show_ipv6_protocol_cmd
,
595 "show ipv6 protocol",
598 "IPv6 protocol filtering status\n")
602 vty_out(vty
, "Protocol : route-map \n");
603 vty_out(vty
, "------------------------\n");
604 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
605 if (proto_rm
[AFI_IP6
][i
])
606 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
607 proto_rm
[AFI_IP6
][i
]);
609 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
611 if (proto_rm
[AFI_IP6
][i
])
612 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP6
][i
]);
614 vty_out(vty
, "%-10s : none\n", "any");
619 DEFUN (ip_protocol_nht_rmap
,
620 ip_protocol_nht_rmap_cmd
,
621 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
623 "Filter Next Hop tracking route resolution\n"
624 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
625 "Specify route map\n"
628 char *proto
= argv
[2]->text
;
629 char *rmap
= argv
[4]->arg
;
632 if (strcasecmp(proto
, "any") == 0)
635 i
= proto_name2num(proto
);
637 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
638 return CMD_WARNING_CONFIG_FAILED
;
640 if (nht_rm
[AFI_IP
][i
]) {
641 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
644 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
647 nht_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
648 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
653 DEFUN (no_ip_protocol_nht_rmap
,
654 no_ip_protocol_nht_rmap_cmd
,
655 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
658 "Filter Next Hop tracking route resolution\n"
659 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
660 "Specify route map\n"
664 char *proto
= argv
[3]->text
;
665 char *rmap
= argv_find(argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
668 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
669 : proto_name2num(proto
);
672 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
673 return CMD_WARNING_CONFIG_FAILED
;
676 if (!nht_rm
[AFI_IP
][i
])
679 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0) {
680 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
681 nht_rm
[AFI_IP
][i
] = NULL
;
682 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
687 DEFUN (show_ip_protocol_nht
,
688 show_ip_protocol_nht_cmd
,
689 "show ip nht route-map",
692 "IP nexthop tracking table\n"
693 "IP Next Hop tracking filtering status\n")
697 vty_out(vty
, "Protocol : route-map \n");
698 vty_out(vty
, "------------------------\n");
699 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
700 if (nht_rm
[AFI_IP
][i
])
701 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
704 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
706 if (nht_rm
[AFI_IP
][i
])
707 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP
][i
]);
709 vty_out(vty
, "%-10s : none\n", "any");
714 DEFUN (ipv6_protocol_nht_rmap
,
715 ipv6_protocol_nht_rmap_cmd
,
716 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
718 "Filter Next Hop tracking route resolution\n"
719 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
720 "Specify route map\n"
723 char *proto
= argv
[2]->text
;
724 char *rmap
= argv
[4]->arg
;
727 if (strcasecmp(proto
, "any") == 0)
730 i
= proto_name2num(proto
);
732 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
733 return CMD_WARNING_CONFIG_FAILED
;
735 if (nht_rm
[AFI_IP6
][i
])
736 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
737 nht_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
738 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
743 DEFUN (no_ipv6_protocol_nht_rmap
,
744 no_ipv6_protocol_nht_rmap_cmd
,
745 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
748 "Filter Next Hop tracking route resolution\n"
749 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
750 "Specify route map\n"
753 char *proto
= argv
[3]->text
;
754 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
757 if (strcasecmp(proto
, "any") == 0)
760 i
= proto_name2num(proto
);
762 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
763 return CMD_WARNING_CONFIG_FAILED
;
766 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
])) {
767 vty_out(vty
, "invalid route-map \"%s\"\n", rmap
);
768 return CMD_WARNING_CONFIG_FAILED
;
771 if (nht_rm
[AFI_IP6
][i
]) {
772 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
773 nht_rm
[AFI_IP6
][i
] = NULL
;
776 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
781 DEFUN (show_ipv6_protocol_nht
,
782 show_ipv6_protocol_nht_cmd
,
783 "show ipv6 nht route-map",
786 "Next Hop filtering status\n"
791 vty_out(vty
, "Protocol : route-map \n");
792 vty_out(vty
, "------------------------\n");
793 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
794 if (nht_rm
[AFI_IP6
][i
])
795 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
798 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
800 if (nht_rm
[AFI_IP
][i
])
801 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP6
][i
]);
803 vty_out(vty
, "%-10s : none\n", "any");
808 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
810 /* `match ip next-hop IP_ACCESS_LIST' */
812 /* Match function return 1 if match is success else return zero. */
813 static route_map_result_t
route_match_ip_next_hop(void *rule
,
814 struct prefix
*prefix
,
815 route_map_object_t type
,
818 struct access_list
*alist
;
819 struct nh_rmap_obj
*nh_data
;
820 struct prefix_ipv4 p
;
822 if (type
== RMAP_ZEBRA
) {
825 return RMAP_DENYMATCH
;
827 switch (nh_data
->nexthop
->type
) {
828 case NEXTHOP_TYPE_IFINDEX
:
829 /* Interface routes can't match ip next-hop */
831 case NEXTHOP_TYPE_IPV4_IFINDEX
:
832 case NEXTHOP_TYPE_IPV4
:
834 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
835 p
.prefixlen
= IPV4_MAX_BITLEN
;
840 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
844 return (access_list_apply(alist
, &p
) == FILTER_DENY
851 /* Route map `ip next-hop' match statement. `arg' should be
853 static void *route_match_ip_next_hop_compile(const char *arg
)
855 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
858 /* Free route map's compiled `. */
859 static void route_match_ip_next_hop_free(void *rule
)
861 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
864 /* Route map commands for ip next-hop matching. */
865 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
866 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
867 route_match_ip_next_hop_free
};
869 /* `match ip next-hop prefix-list PREFIX_LIST' */
871 static route_map_result_t
872 route_match_ip_next_hop_prefix_list(void *rule
, struct prefix
*prefix
,
873 route_map_object_t type
, void *object
)
875 struct prefix_list
*plist
;
876 struct nh_rmap_obj
*nh_data
;
877 struct prefix_ipv4 p
;
879 if (type
== RMAP_ZEBRA
) {
880 nh_data
= (struct nh_rmap_obj
*)object
;
882 return RMAP_DENYMATCH
;
884 switch (nh_data
->nexthop
->type
) {
885 case NEXTHOP_TYPE_IFINDEX
:
886 /* Interface routes can't match ip next-hop */
888 case NEXTHOP_TYPE_IPV4_IFINDEX
:
889 case NEXTHOP_TYPE_IPV4
:
891 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
892 p
.prefixlen
= IPV4_MAX_BITLEN
;
897 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
901 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
908 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
910 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
913 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
915 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
918 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
919 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
920 route_match_ip_next_hop_prefix_list_compile
,
921 route_match_ip_next_hop_prefix_list_free
};
923 /* `match ip address IP_ACCESS_LIST' */
925 /* Match function should return 1 if match is success else return
927 static route_map_result_t
route_match_ip_address(void *rule
,
928 struct prefix
*prefix
,
929 route_map_object_t type
,
932 struct access_list
*alist
;
934 if (type
== RMAP_ZEBRA
) {
935 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
939 return (access_list_apply(alist
, prefix
) == FILTER_DENY
946 /* Route map `ip address' match statement. `arg' should be
948 static void *route_match_ip_address_compile(const char *arg
)
950 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
953 /* Free route map's compiled `ip address' value. */
954 static void route_match_ip_address_free(void *rule
)
956 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
959 /* Route map commands for ip address matching. */
960 static struct route_map_rule_cmd route_match_ip_address_cmd
= {
961 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
962 route_match_ip_address_free
};
964 /* `match ip address prefix-list PREFIX_LIST' */
966 static route_map_result_t
967 route_match_ip_address_prefix_list(void *rule
, struct prefix
*prefix
,
968 route_map_object_t type
, void *object
)
970 struct prefix_list
*plist
;
972 if (type
== RMAP_ZEBRA
) {
973 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
977 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
984 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
986 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
989 static void route_match_ip_address_prefix_list_free(void *rule
)
991 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
994 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
995 "ip address prefix-list", route_match_ip_address_prefix_list
,
996 route_match_ip_address_prefix_list_compile
,
997 route_match_ip_address_prefix_list_free
};
1000 /* `match ip address prefix-len PREFIXLEN' */
1002 static route_map_result_t
1003 route_match_ip_address_prefix_len(void *rule
, struct prefix
*prefix
,
1004 route_map_object_t type
, void *object
)
1006 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1008 if (type
== RMAP_ZEBRA
) {
1009 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1012 return RMAP_NOMATCH
;
1015 static void *route_match_ip_address_prefix_len_compile(const char *arg
)
1017 u_int32_t
*prefix_len
;
1018 char *endptr
= NULL
;
1019 unsigned long tmpval
;
1021 /* prefix len value shoud be integer. */
1022 if (!all_digit(arg
))
1026 tmpval
= strtoul(arg
, &endptr
, 10);
1027 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1030 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(u_int32_t
));
1035 *prefix_len
= tmpval
;
1039 static void route_match_ip_address_prefix_len_free(void *rule
)
1041 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1044 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
= {
1045 "ip address prefix-len", route_match_ip_address_prefix_len
,
1046 route_match_ip_address_prefix_len_compile
,
1047 route_match_ip_address_prefix_len_free
};
1050 /* `match ip nexthop prefix-len PREFIXLEN' */
1052 static route_map_result_t
1053 route_match_ip_nexthop_prefix_len(void *rule
, struct prefix
*prefix
,
1054 route_map_object_t type
, void *object
)
1056 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1057 struct nh_rmap_obj
*nh_data
;
1058 struct prefix_ipv4 p
;
1060 if (type
== RMAP_ZEBRA
) {
1061 nh_data
= (struct nh_rmap_obj
*)object
;
1062 if (!nh_data
|| !nh_data
->nexthop
)
1063 return RMAP_DENYMATCH
;
1065 switch (nh_data
->nexthop
->type
) {
1066 case NEXTHOP_TYPE_IFINDEX
:
1067 /* Interface routes can't match ip next-hop */
1068 return RMAP_NOMATCH
;
1069 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1070 case NEXTHOP_TYPE_IPV4
:
1072 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1073 p
.prefixlen
= IPV4_MAX_BITLEN
;
1076 return RMAP_NOMATCH
;
1078 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1081 return RMAP_NOMATCH
;
1084 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
= {
1085 "ip next-hop prefix-len", route_match_ip_nexthop_prefix_len
,
1086 route_match_ip_address_prefix_len_compile
, /* reuse */
1087 route_match_ip_address_prefix_len_free
/* reuse */
1090 /* `match source-protocol PROTOCOL' */
1092 static route_map_result_t
route_match_source_protocol(void *rule
,
1093 struct prefix
*prefix
,
1094 route_map_object_t type
,
1097 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1098 struct nh_rmap_obj
*nh_data
;
1100 if (type
== RMAP_ZEBRA
) {
1101 nh_data
= (struct nh_rmap_obj
*)object
;
1103 return RMAP_DENYMATCH
;
1105 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1108 return RMAP_NOMATCH
;
1111 static void *route_match_source_protocol_compile(const char *arg
)
1113 u_int32_t
*rib_type
;
1116 i
= proto_name2num(arg
);
1117 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(u_int32_t
));
1124 static void route_match_source_protocol_free(void *rule
)
1126 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1129 static struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1130 "source-protocol", route_match_source_protocol
,
1131 route_match_source_protocol_compile
, route_match_source_protocol_free
};
1133 /* `set src A.B.C.D' */
1136 static route_map_result_t
route_set_src(void *rule
, struct prefix
*prefix
,
1137 route_map_object_t type
, void *object
)
1139 struct nh_rmap_obj
*nh_data
;
1141 if (type
== RMAP_ZEBRA
) {
1142 nh_data
= (struct nh_rmap_obj
*)object
;
1143 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1148 /* set src compilation. */
1149 static void *route_set_src_compile(const char *arg
)
1151 union g_addr src
, *psrc
;
1153 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1154 || (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1))) {
1155 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1162 /* Free route map's compiled `set src' value. */
1163 static void route_set_src_free(void *rule
)
1165 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1168 /* Set src rule structure. */
1169 static struct route_map_rule_cmd route_set_src_cmd
= {
1170 "src", route_set_src
, route_set_src_compile
, route_set_src_free
,
1173 static int zebra_route_map_update_timer(struct thread
*thread
)
1175 zebra_t_rmap_update
= NULL
;
1177 if (IS_ZEBRA_DEBUG_EVENT
)
1178 zlog_debug("Event driven route-map update triggered");
1180 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1182 "%u: Routemap update-timer fired, scheduling RIB processing",
1185 zebra_import_table_rm_update();
1186 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1187 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1188 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1193 static void zebra_route_map_set_delay_timer(u_int32_t value
)
1195 zebra_rmap_update_timer
= value
;
1196 if (!value
&& zebra_t_rmap_update
) {
1197 /* Event driven route map updates is being disabled */
1198 /* But there's a pending timer. Fire it off now */
1199 thread_cancel(zebra_t_rmap_update
);
1200 zebra_route_map_update_timer(zebra_t_rmap_update
);
1204 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1206 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1207 vty_out(vty
, "zebra route-map delay-timer %d\n",
1208 zebra_rmap_update_timer
);
1212 route_map_result_t
zebra_route_map_check(int family
, int rib_type
,
1214 struct nexthop
*nexthop
,
1215 vrf_id_t vrf_id
, route_tag_t tag
)
1217 struct route_map
*rmap
= NULL
;
1218 route_map_result_t ret
= RMAP_MATCH
;
1219 struct nh_rmap_obj nh_obj
;
1221 nh_obj
.nexthop
= nexthop
;
1222 nh_obj
.vrf_id
= vrf_id
;
1223 nh_obj
.source_protocol
= rib_type
;
1227 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1228 rmap
= route_map_lookup_by_name(proto_rm
[family
][rib_type
]);
1229 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1230 rmap
= route_map_lookup_by_name(
1231 proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1233 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1239 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1241 return zebra_import_table_routemap
[afi
][table
];
1244 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1247 zebra_import_table_routemap
[afi
][table
] =
1248 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1251 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1253 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1257 zebra_import_table_route_map_check(int family
, int re_type
, struct prefix
*p
,
1258 struct nexthop
*nexthop
, vrf_id_t vrf_id
,
1259 route_tag_t tag
, const char *rmap_name
)
1261 struct route_map
*rmap
= NULL
;
1262 route_map_result_t ret
= RMAP_DENYMATCH
;
1263 struct nh_rmap_obj nh_obj
;
1265 nh_obj
.nexthop
= nexthop
;
1266 nh_obj
.vrf_id
= vrf_id
;
1267 nh_obj
.source_protocol
= re_type
;
1271 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1272 rmap
= route_map_lookup_by_name(rmap_name
);
1274 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1280 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1282 struct route_entry
*re
,
1283 struct nexthop
*nexthop
)
1285 struct route_map
*rmap
= NULL
;
1286 route_map_result_t ret
= RMAP_MATCH
;
1287 struct nh_rmap_obj nh_obj
;
1289 nh_obj
.nexthop
= nexthop
;
1290 nh_obj
.vrf_id
= re
->vrf_id
;
1291 nh_obj
.source_protocol
= re
->type
;
1292 nh_obj
.metric
= re
->metric
;
1293 nh_obj
.tag
= re
->tag
;
1295 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1296 rmap
= route_map_lookup_by_name(nht_rm
[family
][client_proto
]);
1297 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1298 rmap
= route_map_lookup_by_name(
1299 nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1301 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1307 static void zebra_route_map_mark_update(const char *rmap_name
)
1309 /* rmap_update_timer of 0 means don't do route updates */
1310 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1311 zebra_t_rmap_update
= NULL
;
1312 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1313 NULL
, zebra_rmap_update_timer
,
1314 &zebra_t_rmap_update
);
1318 static void zebra_route_map_add(const char *rmap_name
)
1320 zebra_route_map_mark_update(rmap_name
);
1321 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1324 static void zebra_route_map_delete(const char *rmap_name
)
1326 zebra_route_map_mark_update(rmap_name
);
1327 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1330 static void zebra_route_map_event(route_map_event_t event
,
1331 const char *rmap_name
)
1333 zebra_route_map_mark_update(rmap_name
);
1334 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1337 /* ip protocol configuration write function */
1338 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1342 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1343 if (proto_rm
[AFI_IP
][i
])
1344 vty_out(vty
, "ip protocol %s route-map %s\n",
1345 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1347 if (proto_rm
[AFI_IP6
][i
])
1348 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1349 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1351 if (nht_rm
[AFI_IP
][i
])
1352 vty_out(vty
, "ip nht %s route-map %s\n",
1353 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1355 if (nht_rm
[AFI_IP6
][i
])
1356 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1357 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1360 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1361 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1362 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1364 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1365 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1366 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1368 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1369 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1370 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1372 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1373 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1374 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1376 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1377 vty_out(vty
, "zebra route-map delay-timer %d\n",
1378 zebra_rmap_update_timer
);
1381 void zebra_route_map_init()
1383 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1384 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1385 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1386 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1387 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1388 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1389 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1390 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1391 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1392 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1393 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1394 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1395 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1396 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1400 route_map_add_hook(zebra_route_map_add
);
1401 route_map_delete_hook(zebra_route_map_delete
);
1402 route_map_event_hook(zebra_route_map_event
);
1404 route_map_match_interface_hook(generic_match_add
);
1405 route_map_no_match_interface_hook(generic_match_delete
);
1407 route_map_match_ip_address_hook(generic_match_add
);
1408 route_map_no_match_ip_address_hook(generic_match_delete
);
1410 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1411 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1413 route_map_match_ip_next_hop_hook(generic_match_add
);
1414 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1416 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1417 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1419 route_map_match_tag_hook(generic_match_add
);
1420 route_map_no_match_tag_hook(generic_match_delete
);
1422 route_map_install_match(&route_match_tag_cmd
);
1423 route_map_install_match(&route_match_interface_cmd
);
1424 route_map_install_match(&route_match_ip_next_hop_cmd
);
1425 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1426 route_map_install_match(&route_match_ip_address_cmd
);
1427 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1428 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1429 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1430 route_map_install_match(&route_match_source_protocol_cmd
);
1432 route_map_install_set(&route_set_src_cmd
);
1434 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1435 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1436 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1437 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1438 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1439 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1441 install_element(RMAP_NODE
, &set_src_cmd
);
1442 install_element(RMAP_NODE
, &no_set_src_cmd
);