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"
36 #include "zebra/zserv.h"
37 #include "zebra/redistribute.h"
38 #include "zebra/debug.h"
39 #include "zebra/zebra_rnh.h"
40 #include "zebra/zebra_routemap.h"
42 static uint32_t zebra_rmap_update_timer
= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
;
43 static struct thread
*zebra_t_rmap_update
= NULL
;
44 char *proto_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+ 1]; /* "any" == ZEBRA_ROUTE_MAX */
45 /* NH Tracking route map */
46 char *nht_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+ 1]; /* "any" == ZEBRA_ROUTE_MAX */
47 char *zebra_import_table_routemap
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
50 struct nexthop
*nexthop
;
52 uint32_t source_protocol
;
58 static void zebra_route_map_set_delay_timer(uint32_t value
);
61 /* Add zebra route map rule */
62 static int zebra_route_match_add(struct vty
*vty
, const char *command
,
63 const char *arg
, route_map_event_t type
)
65 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
67 int retval
= CMD_SUCCESS
;
69 ret
= route_map_add_match(index
, command
, arg
);
71 case RMAP_RULE_MISSING
:
72 vty_out(vty
, "%% Zebra Can't find rule.\n");
73 retval
= CMD_WARNING_CONFIG_FAILED
;
75 case RMAP_COMPILE_ERROR
:
76 vty_out(vty
, "%% Zebra Argument is malformed.\n");
77 retval
= CMD_WARNING_CONFIG_FAILED
;
79 case RMAP_COMPILE_SUCCESS
:
80 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
81 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
89 /* Delete zebra route map rule. */
90 static int zebra_route_match_delete(struct vty
*vty
, const char *command
,
91 const char *arg
, route_map_event_t type
)
93 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
95 int retval
= CMD_SUCCESS
;
96 char *dep_name
= NULL
;
98 char *rmap_name
= NULL
;
100 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
101 /* ignore the mundane, the types without any dependency */
103 if ((tmpstr
= route_map_get_match_arg(index
, command
))
106 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
108 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
110 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
113 ret
= route_map_delete_match(index
, command
, arg
);
115 case RMAP_RULE_MISSING
:
116 vty_out(vty
, "%% Zebra Can't find rule.\n");
117 retval
= CMD_WARNING_CONFIG_FAILED
;
119 case RMAP_COMPILE_ERROR
:
120 vty_out(vty
, "%% Zebra Argument is malformed.\n");
121 retval
= CMD_WARNING_CONFIG_FAILED
;
123 case RMAP_COMPILE_SUCCESS
:
124 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
125 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
130 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
132 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
138 * Match function return 1 if match is success else return 0
140 static route_map_result_t
route_match_tag(void *rule
, struct prefix
*prefix
,
141 route_map_object_t type
, void *object
)
144 struct nh_rmap_obj
*nh_data
;
146 if (type
== RMAP_ZEBRA
) {
150 if (nh_data
->tag
== *tag
)
156 /* Route map commands for tag matching */
157 static struct route_map_rule_cmd route_match_tag_cmd
= {
158 "tag", route_match_tag
, route_map_rule_tag_compile
,
159 route_map_rule_tag_free
,
163 /* `match interface IFNAME' */
164 /* Match function return 1 if match is success else return zero. */
165 static route_map_result_t
route_match_interface(void *rule
,
166 struct prefix
*prefix
,
167 route_map_object_t type
,
170 struct nh_rmap_obj
*nh_data
;
174 if (type
== RMAP_ZEBRA
) {
175 if (strcasecmp(ifname
, "any") == 0)
178 if (!nh_data
|| !nh_data
->nexthop
)
180 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
183 if (nh_data
->nexthop
->ifindex
== ifindex
)
189 /* Route map `match interface' match statement. `arg' is IFNAME value */
190 static void *route_match_interface_compile(const char *arg
)
192 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
195 /* Free route map's compiled `match interface' value. */
196 static void route_match_interface_free(void *rule
)
198 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
201 /* Route map commands for interface matching */
202 struct route_map_rule_cmd route_match_interface_cmd
= {
203 "interface", route_match_interface
, route_match_interface_compile
,
204 route_match_interface_free
};
206 DEFUN (match_ip_address_prefix_len
,
207 match_ip_address_prefix_len_cmd
,
208 "match ip address prefix-len (0-32)",
211 "Match prefix length of ip address\n"
212 "Match prefix length of ip address\n"
215 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
216 RMAP_EVENT_MATCH_ADDED
);
219 DEFUN (no_match_ip_address_prefix_len
,
220 no_match_ip_address_prefix_len_cmd
,
221 "no match ip address prefix-len [(0-32)]",
225 "Match prefix length of ip address\n"
226 "Match prefix length of ip address\n"
229 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
230 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
231 RMAP_EVENT_MATCH_DELETED
);
234 DEFUN (match_ipv6_address_prefix_len
,
235 match_ipv6_address_prefix_len_cmd
,
236 "match ipv6 address prefix-len (0-128)",
239 "Match prefix length of ipv6 address\n"
240 "Match prefix length of ipv6 address\n"
243 return zebra_route_match_add(vty
, "ipv6 address prefix-len",
244 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
247 DEFUN (no_match_ipv6_address_prefix_len
,
248 no_match_ipv6_address_prefix_len_cmd
,
249 "no match ipv6 address prefix-len [(0-128)]",
253 "Match prefix length of ip address\n"
254 "Match prefix length of ip address\n"
257 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
258 return zebra_route_match_delete(vty
, "ipv6 address prefix-len", plen
,
259 RMAP_EVENT_MATCH_DELETED
);
262 DEFUN (match_ip_nexthop_prefix_len
,
263 match_ip_nexthop_prefix_len_cmd
,
264 "match ip next-hop prefix-len (0-32)",
267 "Match prefixlen of nexthop ip address\n"
268 "Match prefixlen of given nexthop\n"
271 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
272 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
275 DEFUN (no_match_ip_nexthop_prefix_len
,
276 no_match_ip_nexthop_prefix_len_cmd
,
277 "no match ip next-hop prefix-len [(0-32)]",
281 "Match prefixlen of nexthop ip address\n"
282 "Match prefix length of nexthop\n"
285 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
286 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
287 RMAP_EVENT_MATCH_DELETED
);
290 DEFUN (match_source_protocol
,
291 match_source_protocol_cmd
,
292 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
294 "Match protocol via which the route was learnt\n"
305 "Routes from directly connected peer\n"
306 "Routes from system configuration\n"
307 "Routes from kernel\n"
308 "Statically configured routes\n"
311 char *proto
= argv
[2]->text
;
314 i
= proto_name2num(proto
);
316 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
317 return CMD_WARNING_CONFIG_FAILED
;
319 return zebra_route_match_add(vty
, "source-protocol", proto
,
320 RMAP_EVENT_MATCH_ADDED
);
323 DEFUN (no_match_source_protocol
,
324 no_match_source_protocol_cmd
,
325 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
328 "No match protocol via which the route was learnt\n"
339 "Routes from directly connected peer\n"
340 "Routes from system configuration\n"
341 "Routes from kernel\n"
342 "Statically configured routes\n"
345 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
346 return zebra_route_match_delete(vty
, "source-protocol", proto
,
347 RMAP_EVENT_MATCH_DELETED
);
350 DEFUN (match_source_instance
,
351 match_source_instance_cmd
,
352 "match source-instance (0-255)",
354 "Match the protocol's instance number\n"
355 "The instance number\n")
357 char *instance
= argv
[2]->arg
;
359 return zebra_route_match_add(vty
, "source-instance", instance
,
360 RMAP_EVENT_MATCH_ADDED
);
363 DEFUN (no_match_source_instance
,
364 no_match_source_instance_cmd
,
365 "no match source-instance [(0-255)]",
367 "Match the protocol's instance number\n"
368 "The instance number\n")
370 char *instance
= (argc
== 4) ? argv
[3]->arg
: NULL
;
372 return zebra_route_match_delete(vty
, "source-instance", instance
,
373 RMAP_EVENT_MATCH_ADDED
);
380 "set src <A.B.C.D|X:X::X:X>",
382 "src address for route\n"
384 "IPv6 src address\n")
388 struct interface
*pif
= NULL
;
393 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
394 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
395 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
396 return CMD_WARNING_CONFIG_FAILED
;
399 p
.family
= family
= AF_INET6
;
400 p
.u
.prefix6
= src
.ipv6
;
401 p
.prefixlen
= IPV6_MAX_BITLEN
;
403 p
.family
= family
= AF_INET
;
404 p
.u
.prefix4
= src
.ipv4
;
405 p
.prefixlen
= IPV4_MAX_BITLEN
;
408 if (!zebra_check_addr(&p
)) {
409 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
410 return CMD_WARNING_CONFIG_FAILED
;
413 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
414 if (family
== AF_INET
)
415 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
416 AF_INET
, vrf
->vrf_id
);
417 else if (family
== AF_INET6
)
418 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
419 AF_INET6
, vrf
->vrf_id
);
426 vty_out(vty
, "%% not a local address\n");
427 return CMD_WARNING_CONFIG_FAILED
;
430 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
431 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
436 "no set src [<A.B.C.D|X:X::X:X>]",
439 "Source address for route\n"
443 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
444 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
445 return generic_set_delete(vty
, index
, "src", ip
);
448 DEFUN (zebra_route_map_timer
,
449 zebra_route_map_timer_cmd
,
450 "zebra route-map delay-timer (0-600)",
452 "Set route-map parameters\n"
453 "Time to wait before route-map updates are processed\n"
454 "0 means event-driven updates are disabled\n")
457 uint32_t rmap_delay_timer
;
459 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
460 zebra_route_map_set_delay_timer(rmap_delay_timer
);
462 return (CMD_SUCCESS
);
465 DEFUN (no_zebra_route_map_timer
,
466 no_zebra_route_map_timer_cmd
,
467 "no zebra route-map delay-timer [(0-600)]",
470 "Set route-map parameters\n"
471 "Reset delay-timer to default value, 30 secs\n"
472 "0 means event-driven updates are disabled\n")
474 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
476 return (CMD_SUCCESS
);
482 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
484 "Filter routing info exchanged between zebra and protocol\n"
485 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
486 "Specify route-map\n"
489 char *proto
= argv
[2]->text
;
490 char *rmap
= argv
[4]->arg
;
493 if (strcasecmp(proto
, "any") == 0)
496 i
= proto_name2num(proto
);
498 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
499 return CMD_WARNING_CONFIG_FAILED
;
501 if (proto_rm
[AFI_IP
][i
]) {
502 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
505 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
507 proto_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
509 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
511 "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
514 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
518 DEFUN (no_ip_protocol
,
520 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
523 "Stop filtering routing info between zebra and protocol\n"
524 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
525 "Specify route map\n"
528 char *proto
= argv
[3]->text
;
529 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
532 if (strcasecmp(proto
, "any") == 0)
535 i
= proto_name2num(proto
);
538 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
539 return CMD_WARNING_CONFIG_FAILED
;
542 if (!proto_rm
[AFI_IP
][i
])
545 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP
][i
]) == 0) {
546 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
547 proto_rm
[AFI_IP
][i
] = NULL
;
549 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
551 "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
553 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
558 DEFUN (show_ip_protocol
,
559 show_ip_protocol_cmd
,
563 "IP protocol filtering status\n")
567 vty_out(vty
, "Protocol : route-map \n");
568 vty_out(vty
, "------------------------\n");
569 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
570 if (proto_rm
[AFI_IP
][i
])
571 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
572 proto_rm
[AFI_IP
][i
]);
574 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
576 if (proto_rm
[AFI_IP
][i
])
577 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP
][i
]);
579 vty_out(vty
, "%-10s : none\n", "any");
584 DEFUN (ipv6_protocol
,
586 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
588 "Filter IPv6 routing info exchanged between zebra and protocol\n"
589 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
590 "Specify route map\n"
593 char *proto
= argv
[2]->text
;
594 char *rmap
= argv
[4]->arg
;
597 if (strcasecmp(proto
, "any") == 0)
600 i
= proto_name2num(proto
);
602 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
603 return CMD_WARNING_CONFIG_FAILED
;
605 if (proto_rm
[AFI_IP6
][i
]) {
606 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
609 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
611 proto_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
613 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
615 "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
618 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
622 DEFUN (no_ipv6_protocol
,
623 no_ipv6_protocol_cmd
,
624 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
627 "Stop filtering IPv6 routing info between zebra and protocol\n"
628 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
629 "Specify route map\n"
632 const char *proto
= argv
[3]->text
;
633 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
636 if (strcasecmp(proto
, "any") == 0)
639 i
= proto_name2num(proto
);
641 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
642 return CMD_WARNING_CONFIG_FAILED
;
644 if (!proto_rm
[AFI_IP6
][i
])
647 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0) {
648 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
649 proto_rm
[AFI_IP6
][i
] = NULL
;
651 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
653 "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
656 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
661 DEFUN (show_ipv6_protocol
,
662 show_ipv6_protocol_cmd
,
663 "show ipv6 protocol",
666 "IPv6 protocol filtering status\n")
670 vty_out(vty
, "Protocol : route-map \n");
671 vty_out(vty
, "------------------------\n");
672 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
673 if (proto_rm
[AFI_IP6
][i
])
674 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
675 proto_rm
[AFI_IP6
][i
]);
677 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
679 if (proto_rm
[AFI_IP6
][i
])
680 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP6
][i
]);
682 vty_out(vty
, "%-10s : none\n", "any");
687 DEFUN (ip_protocol_nht_rmap
,
688 ip_protocol_nht_rmap_cmd
,
689 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
691 "Filter Next Hop tracking route resolution\n"
692 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
693 "Specify route map\n"
696 char *proto
= argv
[2]->text
;
697 char *rmap
= argv
[4]->arg
;
700 if (strcasecmp(proto
, "any") == 0)
703 i
= proto_name2num(proto
);
705 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
706 return CMD_WARNING_CONFIG_FAILED
;
708 if (nht_rm
[AFI_IP
][i
]) {
709 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
712 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
715 nht_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
716 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
721 DEFUN (no_ip_protocol_nht_rmap
,
722 no_ip_protocol_nht_rmap_cmd
,
723 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
726 "Filter Next Hop tracking route resolution\n"
727 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
728 "Specify route map\n"
732 char *proto
= argv
[3]->text
;
733 char *rmap
= argv_find(argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
736 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
737 : proto_name2num(proto
);
740 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
741 return CMD_WARNING_CONFIG_FAILED
;
744 if (!nht_rm
[AFI_IP
][i
])
747 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0) {
748 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
749 nht_rm
[AFI_IP
][i
] = NULL
;
750 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
755 DEFUN (show_ip_protocol_nht
,
756 show_ip_protocol_nht_cmd
,
757 "show ip nht route-map",
760 "IP nexthop tracking table\n"
761 "IP Next Hop tracking filtering status\n")
765 vty_out(vty
, "Protocol : route-map \n");
766 vty_out(vty
, "------------------------\n");
767 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
768 if (nht_rm
[AFI_IP
][i
])
769 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
772 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
774 if (nht_rm
[AFI_IP
][i
])
775 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP
][i
]);
777 vty_out(vty
, "%-10s : none\n", "any");
782 DEFUN (ipv6_protocol_nht_rmap
,
783 ipv6_protocol_nht_rmap_cmd
,
784 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
786 "Filter Next Hop tracking route resolution\n"
787 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
788 "Specify route map\n"
791 char *proto
= argv
[2]->text
;
792 char *rmap
= argv
[4]->arg
;
795 if (strcasecmp(proto
, "any") == 0)
798 i
= proto_name2num(proto
);
800 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
801 return CMD_WARNING_CONFIG_FAILED
;
803 if (nht_rm
[AFI_IP6
][i
])
804 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
805 nht_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
806 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
811 DEFUN (no_ipv6_protocol_nht_rmap
,
812 no_ipv6_protocol_nht_rmap_cmd
,
813 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
816 "Filter Next Hop tracking route resolution\n"
817 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
818 "Specify route map\n"
821 char *proto
= argv
[3]->text
;
822 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
825 if (strcasecmp(proto
, "any") == 0)
828 i
= proto_name2num(proto
);
830 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
831 return CMD_WARNING_CONFIG_FAILED
;
834 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
])) {
835 vty_out(vty
, "invalid route-map \"%s\"\n", rmap
);
836 return CMD_WARNING_CONFIG_FAILED
;
839 if (nht_rm
[AFI_IP6
][i
]) {
840 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
841 nht_rm
[AFI_IP6
][i
] = NULL
;
844 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
849 DEFUN (show_ipv6_protocol_nht
,
850 show_ipv6_protocol_nht_cmd
,
851 "show ipv6 nht route-map",
854 "Next Hop filtering status\n"
859 vty_out(vty
, "Protocol : route-map \n");
860 vty_out(vty
, "------------------------\n");
861 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
862 if (nht_rm
[AFI_IP6
][i
])
863 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
866 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
868 if (nht_rm
[AFI_IP
][i
])
869 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP6
][i
]);
871 vty_out(vty
, "%-10s : none\n", "any");
876 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
878 /* `match ip next-hop IP_ACCESS_LIST' */
880 /* Match function return 1 if match is success else return zero. */
881 static route_map_result_t
route_match_ip_next_hop(void *rule
,
882 struct prefix
*prefix
,
883 route_map_object_t type
,
886 struct access_list
*alist
;
887 struct nh_rmap_obj
*nh_data
;
888 struct prefix_ipv4 p
;
890 if (type
== RMAP_ZEBRA
) {
893 return RMAP_DENYMATCH
;
895 switch (nh_data
->nexthop
->type
) {
896 case NEXTHOP_TYPE_IFINDEX
:
897 /* Interface routes can't match ip next-hop */
899 case NEXTHOP_TYPE_IPV4_IFINDEX
:
900 case NEXTHOP_TYPE_IPV4
:
902 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
903 p
.prefixlen
= IPV4_MAX_BITLEN
;
908 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
912 return (access_list_apply(alist
, &p
) == FILTER_DENY
919 /* Route map `ip next-hop' match statement. `arg' should be
921 static void *route_match_ip_next_hop_compile(const char *arg
)
923 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
926 /* Free route map's compiled `. */
927 static void route_match_ip_next_hop_free(void *rule
)
929 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
932 /* Route map commands for ip next-hop matching. */
933 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
934 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
935 route_match_ip_next_hop_free
};
937 /* `match ip next-hop prefix-list PREFIX_LIST' */
939 static route_map_result_t
940 route_match_ip_next_hop_prefix_list(void *rule
, struct prefix
*prefix
,
941 route_map_object_t type
, void *object
)
943 struct prefix_list
*plist
;
944 struct nh_rmap_obj
*nh_data
;
945 struct prefix_ipv4 p
;
947 if (type
== RMAP_ZEBRA
) {
948 nh_data
= (struct nh_rmap_obj
*)object
;
950 return RMAP_DENYMATCH
;
952 switch (nh_data
->nexthop
->type
) {
953 case NEXTHOP_TYPE_IFINDEX
:
954 /* Interface routes can't match ip next-hop */
956 case NEXTHOP_TYPE_IPV4_IFINDEX
:
957 case NEXTHOP_TYPE_IPV4
:
959 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
960 p
.prefixlen
= IPV4_MAX_BITLEN
;
965 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
969 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
976 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
978 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
981 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
983 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
986 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
987 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
988 route_match_ip_next_hop_prefix_list_compile
,
989 route_match_ip_next_hop_prefix_list_free
};
991 /* `match ip address IP_ACCESS_LIST' */
993 /* Match function should return 1 if match is success else return
995 static route_map_result_t
route_match_ip_address(void *rule
,
996 struct prefix
*prefix
,
997 route_map_object_t type
,
1000 struct access_list
*alist
;
1002 if (type
== RMAP_ZEBRA
) {
1003 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
1005 return RMAP_NOMATCH
;
1007 return (access_list_apply(alist
, prefix
) == FILTER_DENY
1011 return RMAP_NOMATCH
;
1014 /* Route map `ip address' match statement. `arg' should be
1015 access-list name. */
1016 static void *route_match_ip_address_compile(const char *arg
)
1018 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1021 /* Free route map's compiled `ip address' value. */
1022 static void route_match_ip_address_free(void *rule
)
1024 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1027 /* Route map commands for ip address matching. */
1028 static struct route_map_rule_cmd route_match_ip_address_cmd
= {
1029 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
1030 route_match_ip_address_free
};
1032 /* `match ip address prefix-list PREFIX_LIST' */
1034 static route_map_result_t
1035 route_match_ip_address_prefix_list(void *rule
, struct prefix
*prefix
,
1036 route_map_object_t type
, void *object
)
1038 struct prefix_list
*plist
;
1040 if (type
== RMAP_ZEBRA
) {
1041 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
1043 return RMAP_NOMATCH
;
1045 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
1049 return RMAP_NOMATCH
;
1052 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
1054 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1057 static void route_match_ip_address_prefix_list_free(void *rule
)
1059 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1062 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
1063 "ip address prefix-list", route_match_ip_address_prefix_list
,
1064 route_match_ip_address_prefix_list_compile
,
1065 route_match_ip_address_prefix_list_free
};
1068 /* `match ip address prefix-len PREFIXLEN' */
1070 static route_map_result_t
1071 route_match_address_prefix_len(void *rule
, struct prefix
*prefix
,
1072 route_map_object_t type
, void *object
)
1074 uint32_t *prefixlen
= (uint32_t *)rule
;
1076 if (type
== RMAP_ZEBRA
) {
1077 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1080 return RMAP_NOMATCH
;
1083 static void *route_match_address_prefix_len_compile(const char *arg
)
1085 uint32_t *prefix_len
;
1086 char *endptr
= NULL
;
1087 unsigned long tmpval
;
1089 /* prefix len value shoud be integer. */
1090 if (!all_digit(arg
))
1094 tmpval
= strtoul(arg
, &endptr
, 10);
1095 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1098 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1103 *prefix_len
= tmpval
;
1107 static void route_match_address_prefix_len_free(void *rule
)
1109 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1112 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
= {
1113 "ip address prefix-len", route_match_address_prefix_len
,
1114 route_match_address_prefix_len_compile
,
1115 route_match_address_prefix_len_free
};
1117 static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd
= {
1118 "ipv6 address prefix-len", route_match_address_prefix_len
,
1119 route_match_address_prefix_len_compile
,
1120 route_match_address_prefix_len_free
};
1122 /* `match ip nexthop prefix-len PREFIXLEN' */
1124 static route_map_result_t
1125 route_match_ip_nexthop_prefix_len(void *rule
, struct prefix
*prefix
,
1126 route_map_object_t type
, void *object
)
1128 uint32_t *prefixlen
= (uint32_t *)rule
;
1129 struct nh_rmap_obj
*nh_data
;
1130 struct prefix_ipv4 p
;
1132 if (type
== RMAP_ZEBRA
) {
1133 nh_data
= (struct nh_rmap_obj
*)object
;
1134 if (!nh_data
|| !nh_data
->nexthop
)
1135 return RMAP_DENYMATCH
;
1137 switch (nh_data
->nexthop
->type
) {
1138 case NEXTHOP_TYPE_IFINDEX
:
1139 /* Interface routes can't match ip next-hop */
1140 return RMAP_NOMATCH
;
1141 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1142 case NEXTHOP_TYPE_IPV4
:
1144 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1145 p
.prefixlen
= IPV4_MAX_BITLEN
;
1148 return RMAP_NOMATCH
;
1150 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1153 return RMAP_NOMATCH
;
1156 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
= {
1157 "ip next-hop prefix-len", route_match_ip_nexthop_prefix_len
,
1158 route_match_address_prefix_len_compile
, /* reuse */
1159 route_match_address_prefix_len_free
/* reuse */
1162 /* `match source-protocol PROTOCOL' */
1164 static route_map_result_t
route_match_source_protocol(void *rule
,
1165 struct prefix
*prefix
,
1166 route_map_object_t type
,
1169 uint32_t *rib_type
= (uint32_t *)rule
;
1170 struct nh_rmap_obj
*nh_data
;
1172 if (type
== RMAP_ZEBRA
) {
1173 nh_data
= (struct nh_rmap_obj
*)object
;
1175 return RMAP_DENYMATCH
;
1177 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1180 return RMAP_NOMATCH
;
1183 static void *route_match_source_protocol_compile(const char *arg
)
1188 i
= proto_name2num(arg
);
1189 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1196 static void route_match_source_protocol_free(void *rule
)
1198 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1201 static struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1202 "source-protocol", route_match_source_protocol
,
1203 route_match_source_protocol_compile
, route_match_source_protocol_free
};
1205 /* `source-instance` */
1206 static route_map_result_t
route_match_source_instance(void *rule
,
1207 struct prefix
*prefix
,
1208 route_map_object_t type
,
1211 uint8_t *instance
= (uint8_t *)rule
;
1212 struct nh_rmap_obj
*nh_data
;
1214 if (type
!= RMAP_ZEBRA
)
1215 return RMAP_NOMATCH
;
1217 nh_data
= (struct nh_rmap_obj
*)object
;
1219 return RMAP_DENYMATCH
;
1221 return (nh_data
->instance
== *instance
) ? RMAP_MATCH
: RMAP_NOMATCH
;
1224 static void *route_match_source_instance_compile(const char *arg
)
1230 instance
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1237 static void route_match_source_instance_free(void *rule
)
1239 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1242 static struct route_map_rule_cmd route_match_source_instance_cmd
= {
1243 "source-instance", route_match_source_instance
,
1244 route_match_source_instance_compile
, route_match_source_instance_free
};
1246 /* `set src A.B.C.D' */
1249 static route_map_result_t
route_set_src(void *rule
, struct prefix
*prefix
,
1250 route_map_object_t type
, void *object
)
1252 struct nh_rmap_obj
*nh_data
;
1254 if (type
== RMAP_ZEBRA
) {
1255 nh_data
= (struct nh_rmap_obj
*)object
;
1256 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1261 /* set src compilation. */
1262 static void *route_set_src_compile(const char *arg
)
1264 union g_addr src
, *psrc
;
1266 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1267 || (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)) {
1268 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1275 /* Free route map's compiled `set src' value. */
1276 static void route_set_src_free(void *rule
)
1278 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1281 /* Set src rule structure. */
1282 static struct route_map_rule_cmd route_set_src_cmd
= {
1283 "src", route_set_src
, route_set_src_compile
, route_set_src_free
,
1286 static void zebra_route_map_process_update_cb(char *rmap_name
)
1288 if (IS_ZEBRA_DEBUG_EVENT
)
1289 zlog_debug("Event handler for route-map: %s",
1293 static int zebra_route_map_update_timer(struct thread
*thread
)
1295 zebra_t_rmap_update
= NULL
;
1297 if (IS_ZEBRA_DEBUG_EVENT
)
1298 zlog_debug("Event driven route-map update triggered");
1300 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1302 "%u: Routemap update-timer fired, scheduling RIB processing",
1305 route_map_walk_update_list(zebra_route_map_process_update_cb
);
1308 * This code needs to be updated to be:
1309 * 1) VRF Aware <sigh>
1310 * 2) Route-map aware
1312 zebra_import_table_rm_update();
1313 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1314 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1315 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1320 static void zebra_route_map_set_delay_timer(uint32_t value
)
1322 zebra_rmap_update_timer
= value
;
1323 if (!value
&& zebra_t_rmap_update
) {
1324 /* Event driven route map updates is being disabled */
1325 /* But there's a pending timer. Fire it off now */
1326 thread_cancel(zebra_t_rmap_update
);
1327 zebra_route_map_update_timer(zebra_t_rmap_update
);
1331 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1333 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1334 vty_out(vty
, "zebra route-map delay-timer %d\n",
1335 zebra_rmap_update_timer
);
1339 route_map_result_t
zebra_route_map_check(int family
, int rib_type
,
1340 uint8_t instance
, struct prefix
*p
,
1341 struct nexthop
*nexthop
,
1342 vrf_id_t vrf_id
, route_tag_t tag
)
1344 struct route_map
*rmap
= NULL
;
1345 route_map_result_t ret
= RMAP_MATCH
;
1346 struct nh_rmap_obj nh_obj
;
1348 nh_obj
.nexthop
= nexthop
;
1349 nh_obj
.vrf_id
= vrf_id
;
1350 nh_obj
.source_protocol
= rib_type
;
1351 nh_obj
.instance
= instance
;
1355 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1356 rmap
= route_map_lookup_by_name(proto_rm
[family
][rib_type
]);
1357 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1358 rmap
= route_map_lookup_by_name(
1359 proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1361 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1367 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1369 return zebra_import_table_routemap
[afi
][table
];
1372 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1375 zebra_import_table_routemap
[afi
][table
] =
1376 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1379 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1381 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1385 zebra_import_table_route_map_check(int family
, int re_type
, uint8_t instance
,
1386 struct prefix
*p
, struct nexthop
*nexthop
,
1387 vrf_id_t vrf_id
, route_tag_t tag
,
1388 const char *rmap_name
)
1390 struct route_map
*rmap
= NULL
;
1391 route_map_result_t ret
= RMAP_DENYMATCH
;
1392 struct nh_rmap_obj nh_obj
;
1394 nh_obj
.nexthop
= nexthop
;
1395 nh_obj
.vrf_id
= vrf_id
;
1396 nh_obj
.source_protocol
= re_type
;
1397 nh_obj
.instance
= instance
;
1401 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1402 rmap
= route_map_lookup_by_name(rmap_name
);
1404 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1410 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1412 struct route_entry
*re
,
1413 struct nexthop
*nexthop
)
1415 struct route_map
*rmap
= NULL
;
1416 route_map_result_t ret
= RMAP_MATCH
;
1417 struct nh_rmap_obj nh_obj
;
1419 nh_obj
.nexthop
= nexthop
;
1420 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1421 nh_obj
.source_protocol
= re
->type
;
1422 nh_obj
.instance
= re
->instance
;
1423 nh_obj
.metric
= re
->metric
;
1424 nh_obj
.tag
= re
->tag
;
1426 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1427 rmap
= route_map_lookup_by_name(nht_rm
[family
][client_proto
]);
1428 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1429 rmap
= route_map_lookup_by_name(
1430 nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1432 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1438 static void zebra_route_map_mark_update(const char *rmap_name
)
1440 /* rmap_update_timer of 0 means don't do route updates */
1441 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1442 zebra_t_rmap_update
= NULL
;
1443 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1444 NULL
, zebra_rmap_update_timer
,
1445 &zebra_t_rmap_update
);
1449 static void zebra_route_map_add(const char *rmap_name
)
1451 if (route_map_mark_updated(rmap_name
) == 0)
1452 zebra_route_map_mark_update(rmap_name
);
1454 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1457 static void zebra_route_map_delete(const char *rmap_name
)
1459 if (route_map_mark_updated(rmap_name
) == 0)
1460 zebra_route_map_mark_update(rmap_name
);
1462 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1465 static void zebra_route_map_event(route_map_event_t event
,
1466 const char *rmap_name
)
1468 if (route_map_mark_updated(rmap_name
) == 0)
1469 zebra_route_map_mark_update(rmap_name
);
1471 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1474 /* ip protocol configuration write function */
1475 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1479 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1480 if (proto_rm
[AFI_IP
][i
])
1481 vty_out(vty
, "ip protocol %s route-map %s\n",
1482 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1484 if (proto_rm
[AFI_IP6
][i
])
1485 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1486 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1488 if (nht_rm
[AFI_IP
][i
])
1489 vty_out(vty
, "ip nht %s route-map %s\n",
1490 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1492 if (nht_rm
[AFI_IP6
][i
])
1493 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1494 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1497 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1498 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1499 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1501 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1502 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1503 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1505 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1506 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1507 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1509 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1510 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1511 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1513 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1514 vty_out(vty
, "zebra route-map delay-timer %d\n",
1515 zebra_rmap_update_timer
);
1518 void zebra_route_map_init()
1520 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1521 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1522 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1523 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1524 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1525 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1526 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1527 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1528 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1529 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1530 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1531 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1532 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1533 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1537 route_map_add_hook(zebra_route_map_add
);
1538 route_map_delete_hook(zebra_route_map_delete
);
1539 route_map_event_hook(zebra_route_map_event
);
1541 route_map_match_interface_hook(generic_match_add
);
1542 route_map_no_match_interface_hook(generic_match_delete
);
1544 route_map_match_ip_address_hook(generic_match_add
);
1545 route_map_no_match_ip_address_hook(generic_match_delete
);
1547 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1548 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1550 route_map_match_ip_next_hop_hook(generic_match_add
);
1551 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1553 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1554 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1556 route_map_match_tag_hook(generic_match_add
);
1557 route_map_no_match_tag_hook(generic_match_delete
);
1559 route_map_install_match(&route_match_tag_cmd
);
1560 route_map_install_match(&route_match_interface_cmd
);
1561 route_map_install_match(&route_match_ip_next_hop_cmd
);
1562 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1563 route_map_install_match(&route_match_ip_address_cmd
);
1564 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1565 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1566 route_map_install_match(&route_match_ipv6_address_prefix_len_cmd
);
1567 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1568 route_map_install_match(&route_match_source_protocol_cmd
);
1569 route_map_install_match(&route_match_source_instance_cmd
);
1572 route_map_install_set(&route_set_src_cmd
);
1574 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1575 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1576 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1577 install_element(RMAP_NODE
, &match_ipv6_address_prefix_len_cmd
);
1578 install_element(RMAP_NODE
, &no_match_ipv6_address_prefix_len_cmd
);
1579 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1580 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1581 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1582 install_element(RMAP_NODE
, &match_source_instance_cmd
);
1583 install_element(RMAP_NODE
, &no_match_source_instance_cmd
);
1586 install_element(RMAP_NODE
, &set_src_cmd
);
1587 install_element(RMAP_NODE
, &no_set_src_cmd
);