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 uint32_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 uint32_t source_protocol
;
57 static void zebra_route_map_set_delay_timer(uint32_t value
);
60 /* Add zebra route map rule */
61 static int zebra_route_match_add(struct vty
*vty
, const char *command
,
62 const char *arg
, route_map_event_t type
)
64 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
66 int retval
= CMD_SUCCESS
;
68 ret
= route_map_add_match(index
, command
, arg
);
70 case RMAP_RULE_MISSING
:
71 vty_out(vty
, "%% Zebra Can't find rule.\n");
72 retval
= CMD_WARNING_CONFIG_FAILED
;
74 case RMAP_COMPILE_ERROR
:
75 vty_out(vty
, "%% Zebra Argument is malformed.\n");
76 retval
= CMD_WARNING_CONFIG_FAILED
;
78 case RMAP_COMPILE_SUCCESS
:
79 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
80 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
88 /* Delete zebra route map rule. */
89 static int zebra_route_match_delete(struct vty
*vty
, const char *command
,
90 const char *arg
, route_map_event_t type
)
92 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
94 int retval
= CMD_SUCCESS
;
95 char *dep_name
= NULL
;
97 char *rmap_name
= NULL
;
99 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
100 /* ignore the mundane, the types without any dependency */
102 if ((tmpstr
= route_map_get_match_arg(index
, command
))
105 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
107 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
109 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
112 ret
= route_map_delete_match(index
, command
, arg
);
114 case RMAP_RULE_MISSING
:
115 vty_out(vty
, "%% Zebra Can't find rule.\n");
116 retval
= CMD_WARNING_CONFIG_FAILED
;
118 case RMAP_COMPILE_ERROR
:
119 vty_out(vty
, "%% Zebra Argument is malformed.\n");
120 retval
= CMD_WARNING_CONFIG_FAILED
;
122 case RMAP_COMPILE_SUCCESS
:
123 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
124 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
129 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
131 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
137 * Match function return 1 if match is success else return 0
139 static route_map_result_t
route_match_tag(void *rule
, struct prefix
*prefix
,
140 route_map_object_t type
, void *object
)
143 struct nh_rmap_obj
*nh_data
;
145 if (type
== RMAP_ZEBRA
) {
149 if (nh_data
->tag
== *tag
)
155 /* Route map commands for tag matching */
156 static struct route_map_rule_cmd route_match_tag_cmd
= {
157 "tag", route_match_tag
, route_map_rule_tag_compile
,
158 route_map_rule_tag_free
,
162 /* `match interface IFNAME' */
163 /* Match function return 1 if match is success else return zero. */
164 static route_map_result_t
route_match_interface(void *rule
,
165 struct prefix
*prefix
,
166 route_map_object_t type
,
169 struct nh_rmap_obj
*nh_data
;
173 if (type
== RMAP_ZEBRA
) {
174 if (strcasecmp(ifname
, "any") == 0)
177 if (!nh_data
|| !nh_data
->nexthop
)
179 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
182 if (nh_data
->nexthop
->ifindex
== ifindex
)
188 /* Route map `match interface' match statement. `arg' is IFNAME value */
189 static void *route_match_interface_compile(const char *arg
)
191 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
194 /* Free route map's compiled `match interface' value. */
195 static void route_match_interface_free(void *rule
)
197 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
200 /* Route map commands for interface matching */
201 struct route_map_rule_cmd route_match_interface_cmd
= {
202 "interface", route_match_interface
, route_match_interface_compile
,
203 route_match_interface_free
};
205 DEFUN (match_ip_address_prefix_len
,
206 match_ip_address_prefix_len_cmd
,
207 "match ip address prefix-len (0-32)",
210 "Match prefix length of ip address\n"
211 "Match prefix length of ip address\n"
214 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
215 RMAP_EVENT_MATCH_ADDED
);
218 DEFUN (no_match_ip_address_prefix_len
,
219 no_match_ip_address_prefix_len_cmd
,
220 "no match ip address prefix-len [(0-32)]",
224 "Match prefix length of ip address\n"
225 "Match prefix length of ip address\n"
228 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
229 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
230 RMAP_EVENT_MATCH_DELETED
);
233 DEFUN (match_ipv6_address_prefix_len
,
234 match_ipv6_address_prefix_len_cmd
,
235 "match ipv6 address prefix-len (0-128)",
238 "Match prefix length of ipv6 address\n"
239 "Match prefix length of ipv6 address\n"
242 return zebra_route_match_add(vty
, "ipv6 address prefix-len",
243 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
246 DEFUN (no_match_ipv6_address_prefix_len
,
247 no_match_ipv6_address_prefix_len_cmd
,
248 "no match ipv6 address prefix-len [(0-128)]",
252 "Match prefix length of ip address\n"
253 "Match prefix length of ip address\n"
256 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
257 return zebra_route_match_delete(vty
, "ipv6 address prefix-len", plen
,
258 RMAP_EVENT_MATCH_DELETED
);
261 DEFUN (match_ip_nexthop_prefix_len
,
262 match_ip_nexthop_prefix_len_cmd
,
263 "match ip next-hop prefix-len (0-32)",
266 "Match prefixlen of nexthop ip address\n"
267 "Match prefixlen of given nexthop\n"
270 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
271 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
274 DEFUN (no_match_ip_nexthop_prefix_len
,
275 no_match_ip_nexthop_prefix_len_cmd
,
276 "no match ip next-hop prefix-len [(0-32)]",
280 "Match prefixlen of nexthop ip address\n"
281 "Match prefix length of nexthop\n"
284 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
285 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
286 RMAP_EVENT_MATCH_DELETED
);
289 DEFUN (match_source_protocol
,
290 match_source_protocol_cmd
,
291 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
293 "Match protocol via which the route was learnt\n"
304 "Routes from directly connected peer\n"
305 "Routes from system configuration\n"
306 "Routes from kernel\n"
307 "Statically configured routes\n"
310 char *proto
= argv
[2]->text
;
313 i
= proto_name2num(proto
);
315 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
316 return CMD_WARNING_CONFIG_FAILED
;
318 return zebra_route_match_add(vty
, "source-protocol", proto
,
319 RMAP_EVENT_MATCH_ADDED
);
322 DEFUN (no_match_source_protocol
,
323 no_match_source_protocol_cmd
,
324 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
327 "No match protocol via which the route was learnt\n"
338 "Routes from directly connected peer\n"
339 "Routes from system configuration\n"
340 "Routes from kernel\n"
341 "Statically configured routes\n"
344 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
345 return zebra_route_match_delete(vty
, "source-protocol", proto
,
346 RMAP_EVENT_MATCH_DELETED
);
349 DEFUN (match_source_instance
,
350 match_source_instance_cmd
,
351 "match source-instance (0-255)",
353 "Match the protocol's instance number\n"
354 "The instance number\n")
356 char *instance
= argv
[2]->arg
;
358 return zebra_route_match_add(vty
, "source-instance", instance
,
359 RMAP_EVENT_MATCH_ADDED
);
362 DEFUN (no_match_source_instance
,
363 no_match_source_instance_cmd
,
364 "no match source-instance [(0-255)]",
366 "Match the protocol's instance number\n"
367 "The instance number\n")
369 char *instance
= (argc
== 4) ? argv
[3]->arg
: NULL
;
371 return zebra_route_match_delete(vty
, "source-instance", instance
,
372 RMAP_EVENT_MATCH_ADDED
);
379 "set src <A.B.C.D|X:X::X:X>",
381 "src address for route\n"
383 "IPv6 src address\n")
387 struct interface
*pif
= NULL
;
392 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
393 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
394 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
395 return CMD_WARNING_CONFIG_FAILED
;
398 p
.family
= family
= AF_INET6
;
399 p
.u
.prefix6
= src
.ipv6
;
400 p
.prefixlen
= IPV6_MAX_BITLEN
;
402 p
.family
= family
= AF_INET
;
403 p
.u
.prefix4
= src
.ipv4
;
404 p
.prefixlen
= IPV4_MAX_BITLEN
;
407 if (!zebra_check_addr(&p
)) {
408 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
409 return CMD_WARNING_CONFIG_FAILED
;
412 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
413 if (family
== AF_INET
)
414 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
415 AF_INET
, vrf
->vrf_id
);
416 else if (family
== AF_INET6
)
417 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
418 AF_INET6
, vrf
->vrf_id
);
425 vty_out(vty
, "%% not a local address\n");
426 return CMD_WARNING_CONFIG_FAILED
;
429 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
430 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
435 "no set src [<A.B.C.D|X:X::X:X>]",
438 "Source address for route\n"
442 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
443 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
444 return generic_set_delete(vty
, index
, "src", ip
);
447 DEFUN (zebra_route_map_timer
,
448 zebra_route_map_timer_cmd
,
449 "zebra route-map delay-timer (0-600)",
451 "Set route-map parameters\n"
452 "Time to wait before route-map updates are processed\n"
453 "0 means event-driven updates are disabled\n")
456 uint32_t rmap_delay_timer
;
458 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
459 zebra_route_map_set_delay_timer(rmap_delay_timer
);
461 return (CMD_SUCCESS
);
464 DEFUN (no_zebra_route_map_timer
,
465 no_zebra_route_map_timer_cmd
,
466 "no zebra route-map delay-timer [(0-600)]",
469 "Set route-map parameters\n"
470 "Reset delay-timer to default value, 30 secs\n"
471 "0 means event-driven updates are disabled\n")
473 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
475 return (CMD_SUCCESS
);
481 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
483 "Filter routing info exchanged between zebra and protocol\n"
484 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
485 "Specify route-map\n"
488 char *proto
= argv
[2]->text
;
489 char *rmap
= argv
[4]->arg
;
492 if (strcasecmp(proto
, "any") == 0)
495 i
= proto_name2num(proto
);
497 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
498 return CMD_WARNING_CONFIG_FAILED
;
500 if (proto_rm
[AFI_IP
][i
]) {
501 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
504 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
506 proto_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
508 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
510 "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
513 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
517 DEFUN (no_ip_protocol
,
519 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
522 "Stop filtering routing info between zebra and protocol\n"
523 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
524 "Specify route map\n"
527 char *proto
= argv
[3]->text
;
528 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
531 if (strcasecmp(proto
, "any") == 0)
534 i
= proto_name2num(proto
);
537 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
538 return CMD_WARNING_CONFIG_FAILED
;
541 if (!proto_rm
[AFI_IP
][i
])
544 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP
][i
]) == 0) {
545 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
546 proto_rm
[AFI_IP
][i
] = NULL
;
548 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
550 "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
552 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
557 DEFUN (show_ip_protocol
,
558 show_ip_protocol_cmd
,
562 "IP protocol filtering status\n")
566 vty_out(vty
, "Protocol : route-map \n");
567 vty_out(vty
, "------------------------\n");
568 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
569 if (proto_rm
[AFI_IP
][i
])
570 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
571 proto_rm
[AFI_IP
][i
]);
573 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
575 if (proto_rm
[AFI_IP
][i
])
576 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP
][i
]);
578 vty_out(vty
, "%-10s : none\n", "any");
583 DEFUN (ipv6_protocol
,
585 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
587 "Filter IPv6 routing info exchanged between zebra and protocol\n"
588 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
589 "Specify route map\n"
592 char *proto
= argv
[2]->text
;
593 char *rmap
= argv
[4]->arg
;
596 if (strcasecmp(proto
, "any") == 0)
599 i
= proto_name2num(proto
);
601 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
602 return CMD_WARNING_CONFIG_FAILED
;
604 if (proto_rm
[AFI_IP6
][i
]) {
605 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
608 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
610 proto_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
612 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
614 "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
617 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
621 DEFUN (no_ipv6_protocol
,
622 no_ipv6_protocol_cmd
,
623 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
626 "Stop filtering IPv6 routing info between zebra and protocol\n"
627 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
628 "Specify route map\n"
631 const char *proto
= argv
[3]->text
;
632 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
635 if (strcasecmp(proto
, "any") == 0)
638 i
= proto_name2num(proto
);
640 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
641 return CMD_WARNING_CONFIG_FAILED
;
643 if (!proto_rm
[AFI_IP6
][i
])
646 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0) {
647 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
648 proto_rm
[AFI_IP6
][i
] = NULL
;
650 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
652 "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
655 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
660 DEFUN (show_ipv6_protocol
,
661 show_ipv6_protocol_cmd
,
662 "show ipv6 protocol",
665 "IPv6 protocol filtering status\n")
669 vty_out(vty
, "Protocol : route-map \n");
670 vty_out(vty
, "------------------------\n");
671 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
672 if (proto_rm
[AFI_IP6
][i
])
673 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
674 proto_rm
[AFI_IP6
][i
]);
676 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
678 if (proto_rm
[AFI_IP6
][i
])
679 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP6
][i
]);
681 vty_out(vty
, "%-10s : none\n", "any");
686 DEFUN (ip_protocol_nht_rmap
,
687 ip_protocol_nht_rmap_cmd
,
688 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
690 "Filter Next Hop tracking route resolution\n"
691 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
692 "Specify route map\n"
695 char *proto
= argv
[2]->text
;
696 char *rmap
= argv
[4]->arg
;
699 if (strcasecmp(proto
, "any") == 0)
702 i
= proto_name2num(proto
);
704 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
705 return CMD_WARNING_CONFIG_FAILED
;
707 if (nht_rm
[AFI_IP
][i
]) {
708 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
711 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
714 nht_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
715 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
720 DEFUN (no_ip_protocol_nht_rmap
,
721 no_ip_protocol_nht_rmap_cmd
,
722 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
725 "Filter Next Hop tracking route resolution\n"
726 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
727 "Specify route map\n"
731 char *proto
= argv
[3]->text
;
732 char *rmap
= argv_find(argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
735 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
736 : proto_name2num(proto
);
739 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
740 return CMD_WARNING_CONFIG_FAILED
;
743 if (!nht_rm
[AFI_IP
][i
])
746 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0) {
747 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
748 nht_rm
[AFI_IP
][i
] = NULL
;
749 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
754 DEFUN (show_ip_protocol_nht
,
755 show_ip_protocol_nht_cmd
,
756 "show ip nht route-map",
759 "IP nexthop tracking table\n"
760 "IP Next Hop tracking filtering status\n")
764 vty_out(vty
, "Protocol : route-map \n");
765 vty_out(vty
, "------------------------\n");
766 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
767 if (nht_rm
[AFI_IP
][i
])
768 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
771 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
773 if (nht_rm
[AFI_IP
][i
])
774 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP
][i
]);
776 vty_out(vty
, "%-10s : none\n", "any");
781 DEFUN (ipv6_protocol_nht_rmap
,
782 ipv6_protocol_nht_rmap_cmd
,
783 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
785 "Filter Next Hop tracking route resolution\n"
786 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
787 "Specify route map\n"
790 char *proto
= argv
[2]->text
;
791 char *rmap
= argv
[4]->arg
;
794 if (strcasecmp(proto
, "any") == 0)
797 i
= proto_name2num(proto
);
799 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
800 return CMD_WARNING_CONFIG_FAILED
;
802 if (nht_rm
[AFI_IP6
][i
])
803 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
804 nht_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
805 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
810 DEFUN (no_ipv6_protocol_nht_rmap
,
811 no_ipv6_protocol_nht_rmap_cmd
,
812 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
815 "Filter Next Hop tracking route resolution\n"
816 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
817 "Specify route map\n"
820 char *proto
= argv
[3]->text
;
821 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
824 if (strcasecmp(proto
, "any") == 0)
827 i
= proto_name2num(proto
);
829 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
830 return CMD_WARNING_CONFIG_FAILED
;
833 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
])) {
834 vty_out(vty
, "invalid route-map \"%s\"\n", rmap
);
835 return CMD_WARNING_CONFIG_FAILED
;
838 if (nht_rm
[AFI_IP6
][i
]) {
839 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
840 nht_rm
[AFI_IP6
][i
] = NULL
;
843 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
848 DEFUN (show_ipv6_protocol_nht
,
849 show_ipv6_protocol_nht_cmd
,
850 "show ipv6 nht route-map",
853 "Next Hop filtering status\n"
858 vty_out(vty
, "Protocol : route-map \n");
859 vty_out(vty
, "------------------------\n");
860 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
861 if (nht_rm
[AFI_IP6
][i
])
862 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
865 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
867 if (nht_rm
[AFI_IP
][i
])
868 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP6
][i
]);
870 vty_out(vty
, "%-10s : none\n", "any");
875 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
877 /* `match ip next-hop IP_ACCESS_LIST' */
879 /* Match function return 1 if match is success else return zero. */
880 static route_map_result_t
route_match_ip_next_hop(void *rule
,
881 struct prefix
*prefix
,
882 route_map_object_t type
,
885 struct access_list
*alist
;
886 struct nh_rmap_obj
*nh_data
;
887 struct prefix_ipv4 p
;
889 if (type
== RMAP_ZEBRA
) {
892 return RMAP_DENYMATCH
;
894 switch (nh_data
->nexthop
->type
) {
895 case NEXTHOP_TYPE_IFINDEX
:
896 /* Interface routes can't match ip next-hop */
898 case NEXTHOP_TYPE_IPV4_IFINDEX
:
899 case NEXTHOP_TYPE_IPV4
:
901 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
902 p
.prefixlen
= IPV4_MAX_BITLEN
;
907 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
911 return (access_list_apply(alist
, &p
) == FILTER_DENY
918 /* Route map `ip next-hop' match statement. `arg' should be
920 static void *route_match_ip_next_hop_compile(const char *arg
)
922 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
925 /* Free route map's compiled `. */
926 static void route_match_ip_next_hop_free(void *rule
)
928 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
931 /* Route map commands for ip next-hop matching. */
932 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
933 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
934 route_match_ip_next_hop_free
};
936 /* `match ip next-hop prefix-list PREFIX_LIST' */
938 static route_map_result_t
939 route_match_ip_next_hop_prefix_list(void *rule
, struct prefix
*prefix
,
940 route_map_object_t type
, void *object
)
942 struct prefix_list
*plist
;
943 struct nh_rmap_obj
*nh_data
;
944 struct prefix_ipv4 p
;
946 if (type
== RMAP_ZEBRA
) {
947 nh_data
= (struct nh_rmap_obj
*)object
;
949 return RMAP_DENYMATCH
;
951 switch (nh_data
->nexthop
->type
) {
952 case NEXTHOP_TYPE_IFINDEX
:
953 /* Interface routes can't match ip next-hop */
955 case NEXTHOP_TYPE_IPV4_IFINDEX
:
956 case NEXTHOP_TYPE_IPV4
:
958 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
959 p
.prefixlen
= IPV4_MAX_BITLEN
;
964 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
968 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
975 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
977 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
980 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
982 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
985 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
986 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
987 route_match_ip_next_hop_prefix_list_compile
,
988 route_match_ip_next_hop_prefix_list_free
};
990 /* `match ip address IP_ACCESS_LIST' */
992 /* Match function should return 1 if match is success else return
994 static route_map_result_t
route_match_ip_address(void *rule
,
995 struct prefix
*prefix
,
996 route_map_object_t type
,
999 struct access_list
*alist
;
1001 if (type
== RMAP_ZEBRA
) {
1002 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
1004 return RMAP_NOMATCH
;
1006 return (access_list_apply(alist
, prefix
) == FILTER_DENY
1010 return RMAP_NOMATCH
;
1013 /* Route map `ip address' match statement. `arg' should be
1014 access-list name. */
1015 static void *route_match_ip_address_compile(const char *arg
)
1017 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1020 /* Free route map's compiled `ip address' value. */
1021 static void route_match_ip_address_free(void *rule
)
1023 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1026 /* Route map commands for ip address matching. */
1027 static struct route_map_rule_cmd route_match_ip_address_cmd
= {
1028 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
1029 route_match_ip_address_free
};
1031 /* `match ip address prefix-list PREFIX_LIST' */
1033 static route_map_result_t
1034 route_match_ip_address_prefix_list(void *rule
, struct prefix
*prefix
,
1035 route_map_object_t type
, void *object
)
1037 struct prefix_list
*plist
;
1039 if (type
== RMAP_ZEBRA
) {
1040 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
1042 return RMAP_NOMATCH
;
1044 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
1048 return RMAP_NOMATCH
;
1051 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
1053 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1056 static void route_match_ip_address_prefix_list_free(void *rule
)
1058 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1061 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
1062 "ip address prefix-list", route_match_ip_address_prefix_list
,
1063 route_match_ip_address_prefix_list_compile
,
1064 route_match_ip_address_prefix_list_free
};
1067 /* `match ip address prefix-len PREFIXLEN' */
1069 static route_map_result_t
1070 route_match_address_prefix_len(void *rule
, struct prefix
*prefix
,
1071 route_map_object_t type
, void *object
)
1073 uint32_t *prefixlen
= (uint32_t *)rule
;
1075 if (type
== RMAP_ZEBRA
) {
1076 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1079 return RMAP_NOMATCH
;
1082 static void *route_match_address_prefix_len_compile(const char *arg
)
1084 uint32_t *prefix_len
;
1085 char *endptr
= NULL
;
1086 unsigned long tmpval
;
1088 /* prefix len value shoud be integer. */
1089 if (!all_digit(arg
))
1093 tmpval
= strtoul(arg
, &endptr
, 10);
1094 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1097 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1102 *prefix_len
= tmpval
;
1106 static void route_match_address_prefix_len_free(void *rule
)
1108 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1111 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
= {
1112 "ip address prefix-len", route_match_address_prefix_len
,
1113 route_match_address_prefix_len_compile
,
1114 route_match_address_prefix_len_free
};
1116 static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd
= {
1117 "ipv6 address prefix-len", route_match_address_prefix_len
,
1118 route_match_address_prefix_len_compile
,
1119 route_match_address_prefix_len_free
};
1121 /* `match ip nexthop prefix-len PREFIXLEN' */
1123 static route_map_result_t
1124 route_match_ip_nexthop_prefix_len(void *rule
, struct prefix
*prefix
,
1125 route_map_object_t type
, void *object
)
1127 uint32_t *prefixlen
= (uint32_t *)rule
;
1128 struct nh_rmap_obj
*nh_data
;
1129 struct prefix_ipv4 p
;
1131 if (type
== RMAP_ZEBRA
) {
1132 nh_data
= (struct nh_rmap_obj
*)object
;
1133 if (!nh_data
|| !nh_data
->nexthop
)
1134 return RMAP_DENYMATCH
;
1136 switch (nh_data
->nexthop
->type
) {
1137 case NEXTHOP_TYPE_IFINDEX
:
1138 /* Interface routes can't match ip next-hop */
1139 return RMAP_NOMATCH
;
1140 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1141 case NEXTHOP_TYPE_IPV4
:
1143 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1144 p
.prefixlen
= IPV4_MAX_BITLEN
;
1147 return RMAP_NOMATCH
;
1149 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1152 return RMAP_NOMATCH
;
1155 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
= {
1156 "ip next-hop prefix-len", route_match_ip_nexthop_prefix_len
,
1157 route_match_address_prefix_len_compile
, /* reuse */
1158 route_match_address_prefix_len_free
/* reuse */
1161 /* `match source-protocol PROTOCOL' */
1163 static route_map_result_t
route_match_source_protocol(void *rule
,
1164 struct prefix
*prefix
,
1165 route_map_object_t type
,
1168 uint32_t *rib_type
= (uint32_t *)rule
;
1169 struct nh_rmap_obj
*nh_data
;
1171 if (type
== RMAP_ZEBRA
) {
1172 nh_data
= (struct nh_rmap_obj
*)object
;
1174 return RMAP_DENYMATCH
;
1176 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1179 return RMAP_NOMATCH
;
1182 static void *route_match_source_protocol_compile(const char *arg
)
1187 i
= proto_name2num(arg
);
1188 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1195 static void route_match_source_protocol_free(void *rule
)
1197 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1200 static struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1201 "source-protocol", route_match_source_protocol
,
1202 route_match_source_protocol_compile
, route_match_source_protocol_free
};
1204 /* `source-instance` */
1205 static route_map_result_t
route_match_source_instance(void *rule
,
1206 struct prefix
*prefix
,
1207 route_map_object_t type
,
1210 uint8_t *instance
= (uint8_t *)rule
;
1211 struct nh_rmap_obj
*nh_data
;
1213 if (type
!= RMAP_ZEBRA
)
1214 return RMAP_NOMATCH
;
1216 nh_data
= (struct nh_rmap_obj
*)object
;
1218 return RMAP_DENYMATCH
;
1220 return (nh_data
->instance
== *instance
) ? RMAP_MATCH
: RMAP_NOMATCH
;
1223 static void *route_match_source_instance_compile(const char *arg
)
1229 instance
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1236 static void route_match_source_instance_free(void *rule
)
1238 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1241 static struct route_map_rule_cmd route_match_source_instance_cmd
= {
1242 "source-instance", route_match_source_instance
,
1243 route_match_source_instance_compile
, route_match_source_instance_free
};
1245 /* `set src A.B.C.D' */
1248 static route_map_result_t
route_set_src(void *rule
, struct prefix
*prefix
,
1249 route_map_object_t type
, void *object
)
1251 struct nh_rmap_obj
*nh_data
;
1253 if (type
== RMAP_ZEBRA
) {
1254 nh_data
= (struct nh_rmap_obj
*)object
;
1255 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1260 /* set src compilation. */
1261 static void *route_set_src_compile(const char *arg
)
1263 union g_addr src
, *psrc
;
1265 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1266 || (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)) {
1267 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1274 /* Free route map's compiled `set src' value. */
1275 static void route_set_src_free(void *rule
)
1277 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1280 /* Set src rule structure. */
1281 static struct route_map_rule_cmd route_set_src_cmd
= {
1282 "src", route_set_src
, route_set_src_compile
, route_set_src_free
,
1285 static int zebra_route_map_process_update_cb(char *rmap_name
)
1287 if (IS_ZEBRA_DEBUG_EVENT
)
1288 zlog_debug("Event handler for route-map: %s",
1294 static int zebra_route_map_update_timer(struct thread
*thread
)
1296 zebra_t_rmap_update
= NULL
;
1298 if (IS_ZEBRA_DEBUG_EVENT
)
1299 zlog_debug("Event driven route-map update triggered");
1301 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1303 "%u: Routemap update-timer fired, scheduling RIB processing",
1306 route_map_walk_update_list(zebra_route_map_process_update_cb
);
1309 * This code needs to be updated to be:
1310 * 1) VRF Aware <sigh>
1311 * 2) Route-map aware
1313 zebra_import_table_rm_update();
1314 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1315 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1316 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1321 static void zebra_route_map_set_delay_timer(uint32_t value
)
1323 zebra_rmap_update_timer
= value
;
1324 if (!value
&& zebra_t_rmap_update
) {
1325 /* Event driven route map updates is being disabled */
1326 /* But there's a pending timer. Fire it off now */
1327 thread_cancel(zebra_t_rmap_update
);
1328 zebra_route_map_update_timer(zebra_t_rmap_update
);
1332 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1334 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1335 vty_out(vty
, "zebra route-map delay-timer %d\n",
1336 zebra_rmap_update_timer
);
1340 route_map_result_t
zebra_route_map_check(int family
, int rib_type
,
1341 uint8_t instance
, struct prefix
*p
,
1342 struct nexthop
*nexthop
,
1343 vrf_id_t vrf_id
, route_tag_t tag
)
1345 struct route_map
*rmap
= NULL
;
1346 route_map_result_t ret
= RMAP_MATCH
;
1347 struct nh_rmap_obj nh_obj
;
1349 nh_obj
.nexthop
= nexthop
;
1350 nh_obj
.vrf_id
= vrf_id
;
1351 nh_obj
.source_protocol
= rib_type
;
1352 nh_obj
.instance
= instance
;
1356 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1357 rmap
= route_map_lookup_by_name(proto_rm
[family
][rib_type
]);
1358 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1359 rmap
= route_map_lookup_by_name(
1360 proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1362 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1368 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1370 return zebra_import_table_routemap
[afi
][table
];
1373 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1376 zebra_import_table_routemap
[afi
][table
] =
1377 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1380 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1382 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1386 zebra_import_table_route_map_check(int family
, int re_type
, uint8_t instance
,
1387 struct prefix
*p
, struct nexthop
*nexthop
,
1388 vrf_id_t vrf_id
, route_tag_t tag
,
1389 const char *rmap_name
)
1391 struct route_map
*rmap
= NULL
;
1392 route_map_result_t ret
= RMAP_DENYMATCH
;
1393 struct nh_rmap_obj nh_obj
;
1395 nh_obj
.nexthop
= nexthop
;
1396 nh_obj
.vrf_id
= vrf_id
;
1397 nh_obj
.source_protocol
= re_type
;
1398 nh_obj
.instance
= instance
;
1402 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1403 rmap
= route_map_lookup_by_name(rmap_name
);
1405 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1411 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1413 struct route_entry
*re
,
1414 struct nexthop
*nexthop
)
1416 struct route_map
*rmap
= NULL
;
1417 route_map_result_t ret
= RMAP_MATCH
;
1418 struct nh_rmap_obj nh_obj
;
1420 nh_obj
.nexthop
= nexthop
;
1421 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1422 nh_obj
.source_protocol
= re
->type
;
1423 nh_obj
.instance
= re
->instance
;
1424 nh_obj
.metric
= re
->metric
;
1425 nh_obj
.tag
= re
->tag
;
1427 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1428 rmap
= route_map_lookup_by_name(nht_rm
[family
][client_proto
]);
1429 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1430 rmap
= route_map_lookup_by_name(
1431 nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1433 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1439 static void zebra_route_map_mark_update(const char *rmap_name
)
1441 /* rmap_update_timer of 0 means don't do route updates */
1442 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1443 zebra_t_rmap_update
= NULL
;
1444 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1445 NULL
, zebra_rmap_update_timer
,
1446 &zebra_t_rmap_update
);
1450 static void zebra_route_map_add(const char *rmap_name
)
1452 if (route_map_mark_updated(rmap_name
) == 0)
1453 zebra_route_map_mark_update(rmap_name
);
1455 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1458 static void zebra_route_map_delete(const char *rmap_name
)
1460 if (route_map_mark_updated(rmap_name
) == 0)
1461 zebra_route_map_mark_update(rmap_name
);
1463 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1466 static void zebra_route_map_event(route_map_event_t event
,
1467 const char *rmap_name
)
1469 if (route_map_mark_updated(rmap_name
) == 0)
1470 zebra_route_map_mark_update(rmap_name
);
1472 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1475 /* ip protocol configuration write function */
1476 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1480 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1481 if (proto_rm
[AFI_IP
][i
])
1482 vty_out(vty
, "ip protocol %s route-map %s\n",
1483 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1485 if (proto_rm
[AFI_IP6
][i
])
1486 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1487 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1489 if (nht_rm
[AFI_IP
][i
])
1490 vty_out(vty
, "ip nht %s route-map %s\n",
1491 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1493 if (nht_rm
[AFI_IP6
][i
])
1494 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1495 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1498 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1499 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1500 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1502 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1503 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1504 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1506 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1507 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1508 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1510 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1511 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1512 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1514 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1515 vty_out(vty
, "zebra route-map delay-timer %d\n",
1516 zebra_rmap_update_timer
);
1519 void zebra_route_map_init()
1521 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1522 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1523 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1524 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1525 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1526 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1527 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1528 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1529 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1530 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1531 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1532 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1533 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1534 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1538 route_map_add_hook(zebra_route_map_add
);
1539 route_map_delete_hook(zebra_route_map_delete
);
1540 route_map_event_hook(zebra_route_map_event
);
1542 route_map_match_interface_hook(generic_match_add
);
1543 route_map_no_match_interface_hook(generic_match_delete
);
1545 route_map_match_ip_address_hook(generic_match_add
);
1546 route_map_no_match_ip_address_hook(generic_match_delete
);
1548 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1549 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1551 route_map_match_ip_next_hop_hook(generic_match_add
);
1552 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1554 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1555 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1557 route_map_match_tag_hook(generic_match_add
);
1558 route_map_no_match_tag_hook(generic_match_delete
);
1560 route_map_install_match(&route_match_tag_cmd
);
1561 route_map_install_match(&route_match_interface_cmd
);
1562 route_map_install_match(&route_match_ip_next_hop_cmd
);
1563 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1564 route_map_install_match(&route_match_ip_address_cmd
);
1565 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1566 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1567 route_map_install_match(&route_match_ipv6_address_prefix_len_cmd
);
1568 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1569 route_map_install_match(&route_match_source_protocol_cmd
);
1570 route_map_install_match(&route_match_source_instance_cmd
);
1573 route_map_install_set(&route_set_src_cmd
);
1575 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1576 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1577 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1578 install_element(RMAP_NODE
, &match_ipv6_address_prefix_len_cmd
);
1579 install_element(RMAP_NODE
, &no_match_ipv6_address_prefix_len_cmd
);
1580 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1581 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1582 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1583 install_element(RMAP_NODE
, &match_source_instance_cmd
);
1584 install_element(RMAP_NODE
, &no_match_source_instance_cmd
);
1587 install_element(RMAP_NODE
, &set_src_cmd
);
1588 install_element(RMAP_NODE
, &no_set_src_cmd
);