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_update_timer(struct thread
*thread
)
1287 zebra_t_rmap_update
= NULL
;
1289 if (IS_ZEBRA_DEBUG_EVENT
)
1290 zlog_debug("Event driven route-map update triggered");
1292 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1294 "%u: Routemap update-timer fired, scheduling RIB processing",
1297 zebra_import_table_rm_update();
1298 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1299 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1300 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1305 static void zebra_route_map_set_delay_timer(uint32_t value
)
1307 zebra_rmap_update_timer
= value
;
1308 if (!value
&& zebra_t_rmap_update
) {
1309 /* Event driven route map updates is being disabled */
1310 /* But there's a pending timer. Fire it off now */
1311 thread_cancel(zebra_t_rmap_update
);
1312 zebra_route_map_update_timer(zebra_t_rmap_update
);
1316 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1318 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1319 vty_out(vty
, "zebra route-map delay-timer %d\n",
1320 zebra_rmap_update_timer
);
1324 route_map_result_t
zebra_route_map_check(int family
, int rib_type
,
1325 uint8_t instance
, struct prefix
*p
,
1326 struct nexthop
*nexthop
,
1327 vrf_id_t vrf_id
, route_tag_t tag
)
1329 struct route_map
*rmap
= NULL
;
1330 route_map_result_t ret
= RMAP_MATCH
;
1331 struct nh_rmap_obj nh_obj
;
1333 nh_obj
.nexthop
= nexthop
;
1334 nh_obj
.vrf_id
= vrf_id
;
1335 nh_obj
.source_protocol
= rib_type
;
1336 nh_obj
.instance
= instance
;
1340 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1341 rmap
= route_map_lookup_by_name(proto_rm
[family
][rib_type
]);
1342 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1343 rmap
= route_map_lookup_by_name(
1344 proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1346 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1352 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1354 return zebra_import_table_routemap
[afi
][table
];
1357 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1360 zebra_import_table_routemap
[afi
][table
] =
1361 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1364 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1366 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1370 zebra_import_table_route_map_check(int family
, int re_type
, uint8_t instance
,
1371 struct prefix
*p
, struct nexthop
*nexthop
,
1372 vrf_id_t vrf_id
, route_tag_t tag
,
1373 const char *rmap_name
)
1375 struct route_map
*rmap
= NULL
;
1376 route_map_result_t ret
= RMAP_DENYMATCH
;
1377 struct nh_rmap_obj nh_obj
;
1379 nh_obj
.nexthop
= nexthop
;
1380 nh_obj
.vrf_id
= vrf_id
;
1381 nh_obj
.source_protocol
= re_type
;
1382 nh_obj
.instance
= instance
;
1386 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1387 rmap
= route_map_lookup_by_name(rmap_name
);
1389 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1395 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1397 struct route_entry
*re
,
1398 struct nexthop
*nexthop
)
1400 struct route_map
*rmap
= NULL
;
1401 route_map_result_t ret
= RMAP_MATCH
;
1402 struct nh_rmap_obj nh_obj
;
1404 nh_obj
.nexthop
= nexthop
;
1405 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1406 nh_obj
.source_protocol
= re
->type
;
1407 nh_obj
.instance
= re
->instance
;
1408 nh_obj
.metric
= re
->metric
;
1409 nh_obj
.tag
= re
->tag
;
1411 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1412 rmap
= route_map_lookup_by_name(nht_rm
[family
][client_proto
]);
1413 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1414 rmap
= route_map_lookup_by_name(
1415 nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1417 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1423 static void zebra_route_map_mark_update(const char *rmap_name
)
1425 /* rmap_update_timer of 0 means don't do route updates */
1426 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1427 zebra_t_rmap_update
= NULL
;
1428 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1429 NULL
, zebra_rmap_update_timer
,
1430 &zebra_t_rmap_update
);
1434 static void zebra_route_map_add(const char *rmap_name
)
1436 zebra_route_map_mark_update(rmap_name
);
1437 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1440 static void zebra_route_map_delete(const char *rmap_name
)
1442 zebra_route_map_mark_update(rmap_name
);
1443 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1446 static void zebra_route_map_event(route_map_event_t event
,
1447 const char *rmap_name
)
1449 zebra_route_map_mark_update(rmap_name
);
1450 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1453 /* ip protocol configuration write function */
1454 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1458 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1459 if (proto_rm
[AFI_IP
][i
])
1460 vty_out(vty
, "ip protocol %s route-map %s\n",
1461 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1463 if (proto_rm
[AFI_IP6
][i
])
1464 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1465 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1467 if (nht_rm
[AFI_IP
][i
])
1468 vty_out(vty
, "ip nht %s route-map %s\n",
1469 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1471 if (nht_rm
[AFI_IP6
][i
])
1472 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1473 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1476 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1477 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1478 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1480 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1481 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1482 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1484 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1485 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1486 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1488 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1489 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1490 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1492 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1493 vty_out(vty
, "zebra route-map delay-timer %d\n",
1494 zebra_rmap_update_timer
);
1497 void zebra_route_map_init()
1499 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1500 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1501 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1502 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1503 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1504 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1505 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1506 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1507 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1508 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1509 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1510 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1511 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1512 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1516 route_map_add_hook(zebra_route_map_add
);
1517 route_map_delete_hook(zebra_route_map_delete
);
1518 route_map_event_hook(zebra_route_map_event
);
1520 route_map_match_interface_hook(generic_match_add
);
1521 route_map_no_match_interface_hook(generic_match_delete
);
1523 route_map_match_ip_address_hook(generic_match_add
);
1524 route_map_no_match_ip_address_hook(generic_match_delete
);
1526 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1527 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1529 route_map_match_ip_next_hop_hook(generic_match_add
);
1530 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1532 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1533 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1535 route_map_match_tag_hook(generic_match_add
);
1536 route_map_no_match_tag_hook(generic_match_delete
);
1538 route_map_install_match(&route_match_tag_cmd
);
1539 route_map_install_match(&route_match_interface_cmd
);
1540 route_map_install_match(&route_match_ip_next_hop_cmd
);
1541 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1542 route_map_install_match(&route_match_ip_address_cmd
);
1543 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1544 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1545 route_map_install_match(&route_match_ipv6_address_prefix_len_cmd
);
1546 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1547 route_map_install_match(&route_match_source_protocol_cmd
);
1548 route_map_install_match(&route_match_source_instance_cmd
);
1551 route_map_install_set(&route_set_src_cmd
);
1553 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1554 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1555 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1556 install_element(RMAP_NODE
, &match_ipv6_address_prefix_len_cmd
);
1557 install_element(RMAP_NODE
, &no_match_ipv6_address_prefix_len_cmd
);
1558 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1559 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1560 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1561 install_element(RMAP_NODE
, &match_source_instance_cmd
);
1562 install_element(RMAP_NODE
, &no_match_source_instance_cmd
);
1565 install_element(RMAP_NODE
, &set_src_cmd
);
1566 install_element(RMAP_NODE
, &no_set_src_cmd
);