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/zebra_router.h"
37 #include "zebra/redistribute.h"
38 #include "zebra/debug.h"
39 #include "zebra/zebra_rnh.h"
40 #include "zebra/zebra_routemap.h"
42 #ifndef VTYSH_EXTRACT_PL
43 #include "zebra/zebra_routemap_clippy.c"
46 static uint32_t zebra_rmap_update_timer
= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
;
47 static struct thread
*zebra_t_rmap_update
= NULL
;
48 char *zebra_import_table_routemap
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
51 struct nexthop
*nexthop
;
53 uint32_t source_protocol
;
59 static void zebra_route_map_set_delay_timer(uint32_t value
);
62 /* Add zebra route map rule */
63 static int zebra_route_match_add(struct vty
*vty
, const char *command
,
64 const char *arg
, route_map_event_t type
)
66 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
67 enum rmap_compile_rets ret
;
68 int retval
= CMD_SUCCESS
;
70 ret
= route_map_add_match(index
, command
, arg
, type
);
72 case RMAP_RULE_MISSING
:
73 vty_out(vty
, "%% Zebra Can't find rule.\n");
74 retval
= CMD_WARNING_CONFIG_FAILED
;
76 case RMAP_COMPILE_ERROR
:
77 vty_out(vty
, "%% Zebra Argument is malformed.\n");
78 retval
= CMD_WARNING_CONFIG_FAILED
;
80 case RMAP_COMPILE_SUCCESS
:
90 /* Delete zebra route map rule. */
91 static int zebra_route_match_delete(struct vty
*vty
, const char *command
,
92 const char *arg
, route_map_event_t type
)
94 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
95 enum rmap_compile_rets ret
;
96 int retval
= CMD_SUCCESS
;
97 char *dep_name
= NULL
;
99 char *rmap_name
= NULL
;
101 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
102 /* ignore the mundane, the types without any dependency */
104 if ((tmpstr
= route_map_get_match_arg(index
, command
))
107 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
109 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
111 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
114 ret
= route_map_delete_match(index
, command
, arg
, type
);
116 case RMAP_RULE_MISSING
:
117 vty_out(vty
, "%% Zebra Can't find rule.\n");
118 retval
= CMD_WARNING_CONFIG_FAILED
;
120 case RMAP_COMPILE_ERROR
:
121 vty_out(vty
, "%% Zebra Argument is malformed.\n");
122 retval
= CMD_WARNING_CONFIG_FAILED
;
124 case RMAP_COMPILE_SUCCESS
:
131 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 enum route_map_cmd_result_t
141 route_match_tag(void *rule
, const struct prefix
*prefix
,
142 route_map_object_t type
, void *object
)
145 struct nh_rmap_obj
*nh_data
;
147 if (type
== RMAP_ZEBRA
) {
151 if (nh_data
->tag
== *tag
)
157 /* Route map commands for tag matching */
158 static const struct route_map_rule_cmd route_match_tag_cmd
= {
161 route_map_rule_tag_compile
,
162 route_map_rule_tag_free
,
166 /* `match interface IFNAME' */
167 /* Match function return 1 if match is success else return zero. */
168 static enum route_map_cmd_result_t
169 route_match_interface(void *rule
, const struct prefix
*prefix
,
170 route_map_object_t type
, void *object
)
172 struct nh_rmap_obj
*nh_data
;
176 if (type
== RMAP_ZEBRA
) {
177 if (strcasecmp(ifname
, "any") == 0)
180 if (!nh_data
|| !nh_data
->nexthop
)
182 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
185 if (nh_data
->nexthop
->ifindex
== ifindex
)
191 /* Route map `match interface' match statement. `arg' is IFNAME value */
192 static void *route_match_interface_compile(const char *arg
)
194 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
197 /* Free route map's compiled `match interface' value. */
198 static void route_match_interface_free(void *rule
)
200 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
203 static void show_vrf_proto_rm(struct vty
*vty
, struct zebra_vrf
*zvrf
,
208 vty_out(vty
, "Protocol : route-map\n");
209 vty_out(vty
, "-------------------------------------\n");
211 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
212 if (PROTO_RM_NAME(zvrf
, af_type
, i
))
213 vty_out(vty
, "%-24s : %-10s\n", zebra_route_string(i
),
214 PROTO_RM_NAME(zvrf
, af_type
, i
));
216 vty_out(vty
, "%-24s : none\n", zebra_route_string(i
));
219 if (PROTO_RM_NAME(zvrf
, af_type
, i
))
220 vty_out(vty
, "%-24s : %-10s\n", "any",
221 PROTO_RM_NAME(zvrf
, af_type
, i
));
223 vty_out(vty
, "%-24s : none\n", "any");
226 static void show_vrf_nht_rm(struct vty
*vty
, struct zebra_vrf
*zvrf
,
231 vty_out(vty
, "Protocol : route-map\n");
232 vty_out(vty
, "-------------------------------------\n");
234 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
235 if (NHT_RM_NAME(zvrf
, af_type
, i
))
236 vty_out(vty
, "%-24s : %-10s\n", zebra_route_string(i
),
237 NHT_RM_NAME(zvrf
, af_type
, i
));
239 vty_out(vty
, "%-24s : none\n", zebra_route_string(i
));
242 if (NHT_RM_NAME(zvrf
, af_type
, i
))
243 vty_out(vty
, "%-24s : %-10s\n", "any",
244 NHT_RM_NAME(zvrf
, af_type
, i
));
246 vty_out(vty
, "%-24s : none\n", "any");
249 static int show_proto_rm(struct vty
*vty
, int af_type
, const char *vrf_all
,
250 const char *vrf_name
)
252 struct zebra_vrf
*zvrf
;
257 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
258 zvrf
= (struct zebra_vrf
*)vrf
->info
;
261 vty_out(vty
, "VRF: %s\n", zvrf
->vrf
->name
);
262 show_vrf_proto_rm(vty
, zvrf
, af_type
);
265 vrf_id_t vrf_id
= VRF_DEFAULT
;
268 VRF_GET_ID(vrf_id
, vrf_name
, false);
270 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
274 vty_out(vty
, "VRF: %s\n", zvrf
->vrf
->name
);
275 show_vrf_proto_rm(vty
, zvrf
, af_type
);
281 static int show_nht_rm(struct vty
*vty
, int af_type
, const char *vrf_all
,
282 const char *vrf_name
)
284 struct zebra_vrf
*zvrf
;
289 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
290 zvrf
= (struct zebra_vrf
*)vrf
->info
;
294 vty_out(vty
, "VRF: %s\n", zvrf
->vrf
->name
);
295 show_vrf_nht_rm(vty
, zvrf
, af_type
);
298 vrf_id_t vrf_id
= VRF_DEFAULT
;
301 VRF_GET_ID(vrf_id
, vrf_name
, false);
303 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
307 vty_out(vty
, "VRF: %s\n", zvrf
->vrf
->name
);
308 show_vrf_nht_rm(vty
, zvrf
, af_type
);
314 /* Route map commands for interface matching */
315 static const struct route_map_rule_cmd route_match_interface_cmd
= {
317 route_match_interface
,
318 route_match_interface_compile
,
319 route_match_interface_free
322 static int ip_protocol_rm_add(struct zebra_vrf
*zvrf
, const char *rmap
,
323 int rtype
, afi_t afi
, safi_t safi
)
325 struct route_table
*table
;
327 if (PROTO_RM_NAME(zvrf
, afi
, rtype
)) {
328 if (strcmp(PROTO_RM_NAME(zvrf
, afi
, rtype
), rmap
) == 0)
331 XFREE(MTYPE_ROUTE_MAP_NAME
, PROTO_RM_NAME(zvrf
, afi
, rtype
));
333 route_map_counter_decrement(PROTO_RM_MAP(zvrf
, afi
, rtype
));
334 PROTO_RM_NAME(zvrf
, afi
, rtype
) = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
335 PROTO_RM_MAP(zvrf
, afi
, rtype
) =
336 route_map_lookup_by_name(PROTO_RM_NAME(zvrf
, afi
, rtype
));
337 route_map_counter_increment(PROTO_RM_MAP(zvrf
, afi
, rtype
));
339 if (PROTO_RM_MAP(zvrf
, afi
, rtype
)) {
341 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
343 "%u: IPv4 Routemap config for protocol %d scheduling RIB processing",
344 zvrf
->vrf
->vrf_id
, rtype
);
345 /* Process routes of interested address-families. */
346 table
= zebra_vrf_table(afi
, safi
, zvrf
->vrf
->vrf_id
);
348 rib_update_table(table
, RIB_UPDATE_RMAP_CHANGE
);
354 static int ip_protocol_rm_del(struct zebra_vrf
*zvrf
, const char *rmap
,
355 int rtype
, afi_t afi
, safi_t safi
)
357 struct route_table
*table
;
359 if (!PROTO_RM_NAME(zvrf
, afi
, rtype
))
362 if (!rmap
|| strcmp(rmap
, PROTO_RM_NAME(zvrf
, afi
, rtype
)) == 0) {
364 route_map_counter_decrement(PROTO_RM_MAP(zvrf
, afi
, rtype
));
365 if (PROTO_RM_MAP(zvrf
, afi
, rtype
)) {
366 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
368 "%u: IPv4 Routemap unconfig for protocol %d, scheduling RIB processing",
369 zvrf
->vrf
->vrf_id
, rtype
);
370 PROTO_RM_MAP(zvrf
, afi
, rtype
) = NULL
;
372 /* Process routes of interested address-families. */
373 table
= zebra_vrf_table(afi
, safi
, zvrf
->vrf
->vrf_id
);
375 rib_update_table(table
, RIB_UPDATE_RMAP_CHANGE
);
377 XFREE(MTYPE_ROUTE_MAP_NAME
, PROTO_RM_NAME(zvrf
, afi
, rtype
));
382 static int ip_nht_rm_add(struct zebra_vrf
*zvrf
, const char *rmap
, int rtype
,
386 if (NHT_RM_NAME(zvrf
, afi
, rtype
)) {
387 if (strcmp(NHT_RM_NAME(zvrf
, afi
, rtype
), rmap
) == 0)
390 XFREE(MTYPE_ROUTE_MAP_NAME
, NHT_RM_NAME(zvrf
, afi
, rtype
));
392 route_map_counter_decrement(NHT_RM_MAP(zvrf
, afi
, rtype
));
393 NHT_RM_NAME(zvrf
, afi
, rtype
) = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
394 NHT_RM_MAP(zvrf
, afi
, rtype
) =
395 route_map_lookup_by_name(NHT_RM_NAME(zvrf
, afi
, rtype
));
396 route_map_counter_increment(NHT_RM_MAP(zvrf
, afi
, rtype
));
398 if (NHT_RM_MAP(zvrf
, afi
, rtype
))
399 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
404 static int ip_nht_rm_del(struct zebra_vrf
*zvrf
, const char *rmap
, int rtype
,
408 if (!NHT_RM_NAME(zvrf
, afi
, rtype
))
411 if (!rmap
|| strcmp(rmap
, NHT_RM_NAME(zvrf
, afi
, rtype
)) == 0) {
412 route_map_counter_decrement(NHT_RM_MAP(zvrf
, afi
, rtype
));
413 if (NHT_RM_MAP(zvrf
, afi
, rtype
)) {
414 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
416 "%u: IPv4 Routemap unconfig for protocol %d, scheduling RIB processing",
417 zvrf
->vrf
->vrf_id
, rtype
);
418 NHT_RM_MAP(zvrf
, afi
, rtype
) = NULL
;
420 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
,
423 XFREE(MTYPE_ROUTE_MAP_NAME
, NHT_RM_NAME(zvrf
, afi
, rtype
));
428 DEFUN (match_ip_address_prefix_len
,
429 match_ip_address_prefix_len_cmd
,
430 "match ip address prefix-len (0-32)",
433 "Match prefix length of ip address\n"
434 "Match prefix length of ip address\n"
437 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
438 RMAP_EVENT_MATCH_ADDED
);
441 DEFUN (no_match_ip_address_prefix_len
,
442 no_match_ip_address_prefix_len_cmd
,
443 "no match ip address prefix-len [(0-32)]",
447 "Match prefix length of ip address\n"
448 "Match prefix length of ip address\n"
451 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
452 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
453 RMAP_EVENT_MATCH_DELETED
);
456 DEFUN (match_ipv6_address_prefix_len
,
457 match_ipv6_address_prefix_len_cmd
,
458 "match ipv6 address prefix-len (0-128)",
461 "Match prefix length of ipv6 address\n"
462 "Match prefix length of ipv6 address\n"
465 return zebra_route_match_add(vty
, "ipv6 address prefix-len",
466 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
469 DEFUN (no_match_ipv6_address_prefix_len
,
470 no_match_ipv6_address_prefix_len_cmd
,
471 "no match ipv6 address prefix-len [(0-128)]",
475 "Match prefix length of ip address\n"
476 "Match prefix length of ip address\n"
479 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
480 return zebra_route_match_delete(vty
, "ipv6 address prefix-len", plen
,
481 RMAP_EVENT_MATCH_DELETED
);
484 DEFUN (match_ip_nexthop_prefix_len
,
485 match_ip_nexthop_prefix_len_cmd
,
486 "match ip next-hop prefix-len (0-32)",
489 "Match prefixlen of nexthop ip address\n"
490 "Match prefixlen of given nexthop\n"
493 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
494 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
497 DEFUN (no_match_ip_nexthop_prefix_len
,
498 no_match_ip_nexthop_prefix_len_cmd
,
499 "no match ip next-hop prefix-len [(0-32)]",
503 "Match prefixlen of nexthop ip address\n"
504 "Match prefix length of nexthop\n"
507 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
508 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
509 RMAP_EVENT_MATCH_DELETED
);
512 DEFUN (match_source_protocol
,
513 match_source_protocol_cmd
,
514 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
516 "Match protocol via which the route was learnt\n"
527 "Routes from directly connected peer\n"
528 "Routes from system configuration\n"
529 "Routes from kernel\n"
530 "Statically configured routes\n"
533 char *proto
= argv
[2]->text
;
536 i
= proto_name2num(proto
);
538 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
539 return CMD_WARNING_CONFIG_FAILED
;
541 return zebra_route_match_add(vty
, "source-protocol", proto
,
542 RMAP_EVENT_MATCH_ADDED
);
545 DEFUN (no_match_source_protocol
,
546 no_match_source_protocol_cmd
,
547 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
550 "No match protocol via which the route was learnt\n"
561 "Routes from directly connected peer\n"
562 "Routes from system configuration\n"
563 "Routes from kernel\n"
564 "Statically configured routes\n"
567 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
568 return zebra_route_match_delete(vty
, "source-protocol", proto
,
569 RMAP_EVENT_MATCH_DELETED
);
572 DEFUN (match_source_instance
,
573 match_source_instance_cmd
,
574 "match source-instance (0-255)",
576 "Match the protocol's instance number\n"
577 "The instance number\n")
579 char *instance
= argv
[2]->arg
;
581 return zebra_route_match_add(vty
, "source-instance", instance
,
582 RMAP_EVENT_MATCH_ADDED
);
585 DEFUN (no_match_source_instance
,
586 no_match_source_instance_cmd
,
587 "no match source-instance [(0-255)]",
589 "Match the protocol's instance number\n"
590 "The instance number\n")
592 char *instance
= (argc
== 4) ? argv
[3]->arg
: NULL
;
594 return zebra_route_match_delete(vty
, "source-instance", instance
,
595 RMAP_EVENT_MATCH_ADDED
);
602 "set src <A.B.C.D|X:X::X:X>",
604 "src address for route\n"
606 "IPv6 src address\n")
610 struct interface
*pif
= NULL
;
615 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
616 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
617 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
618 return CMD_WARNING_CONFIG_FAILED
;
621 p
.family
= family
= AF_INET6
;
622 p
.u
.prefix6
= src
.ipv6
;
623 p
.prefixlen
= IPV6_MAX_BITLEN
;
625 p
.family
= family
= AF_INET
;
626 p
.u
.prefix4
= src
.ipv4
;
627 p
.prefixlen
= IPV4_MAX_BITLEN
;
630 if (!zebra_check_addr(&p
)) {
631 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
632 return CMD_WARNING_CONFIG_FAILED
;
635 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
636 if (family
== AF_INET
)
637 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
638 AF_INET
, vrf
->vrf_id
);
639 else if (family
== AF_INET6
)
640 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
641 AF_INET6
, vrf
->vrf_id
);
648 vty_out(vty
, "%% not a local address\n");
649 return CMD_WARNING_CONFIG_FAILED
;
652 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
653 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
658 "no set src [<A.B.C.D|X:X::X:X>]",
661 "Source address for route\n"
665 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
666 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
667 return generic_set_delete(vty
, index
, "src", ip
);
670 DEFUN (zebra_route_map_timer
,
671 zebra_route_map_timer_cmd
,
672 "zebra route-map delay-timer (0-600)",
674 "Set route-map parameters\n"
675 "Time to wait before route-map updates are processed\n"
676 "0 means event-driven updates are disabled\n")
679 uint32_t rmap_delay_timer
;
681 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
682 zebra_route_map_set_delay_timer(rmap_delay_timer
);
684 return (CMD_SUCCESS
);
687 DEFUN (no_zebra_route_map_timer
,
688 no_zebra_route_map_timer_cmd
,
689 "no zebra route-map delay-timer [(0-600)]",
692 "Set route-map parameters\n"
693 "Reset delay-timer to default value, 30 secs\n"
694 "0 means event-driven updates are disabled\n")
696 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
698 return (CMD_SUCCESS
);
703 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
704 " $proto route-map ROUTE-MAP$rmap",
706 "Filter routing info exchanged between zebra and protocol\n"
707 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
708 "Specify route-map\n"
716 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
721 if (strcasecmp(proto
, "any") == 0)
722 rtype
= ZEBRA_ROUTE_MAX
;
724 rtype
= proto_name2num(proto
);
726 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
727 return CMD_WARNING_CONFIG_FAILED
;
730 ret
= ip_protocol_rm_add(zvrf
, rmap
, rtype
, AFI_IP
, SAFI_UNICAST
);
735 DEFPY (no_ip_protocol
,
737 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
738 " $proto [route-map ROUTE-MAP$rmap]",
741 "Stop filtering routing info between zebra and protocol\n"
742 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
743 "Specify route-map\n"
750 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
755 if (strcasecmp(proto
, "any") == 0)
756 rtype
= ZEBRA_ROUTE_MAX
;
758 rtype
= proto_name2num(proto
);
760 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
761 return CMD_WARNING_CONFIG_FAILED
;
764 ret
= ip_protocol_rm_del(zvrf
, rmap
, rtype
, AFI_IP
, SAFI_UNICAST
);
769 DEFPY (show_ip_protocol
,
770 show_ip_protocol_cmd
,
771 "show ip protocol [vrf <NAME$vrf_name|all$vrf_all>]",
774 "IP protocol filtering status\n"
775 VRF_FULL_CMD_HELP_STR
)
777 int ret
= show_proto_rm(vty
, AFI_IP
, vrf_all
, vrf_name
);
782 DEFPY (ipv6_protocol
,
784 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
785 " $proto route-map ROUTE-MAP$rmap",
787 "Filter IPv6 routing info exchanged between zebra and protocol\n"
788 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
789 "Specify route-map\n"
797 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
802 if (strcasecmp(proto
, "any") == 0)
803 rtype
= ZEBRA_ROUTE_MAX
;
805 rtype
= proto_name2num(proto
);
807 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
808 return CMD_WARNING_CONFIG_FAILED
;
811 ret
= ip_protocol_rm_add(zvrf
, rmap
, rtype
, AFI_IP6
, SAFI_UNICAST
);
816 DEFPY (no_ipv6_protocol
,
817 no_ipv6_protocol_cmd
,
818 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
819 " $proto [route-map ROUTE-MAP$rmap]",
822 "Stop filtering IPv6 routing info between zebra and protocol\n"
823 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
824 "Specify route-map\n"
831 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
836 if (strcasecmp(proto
, "any") == 0)
837 rtype
= ZEBRA_ROUTE_MAX
;
839 rtype
= proto_name2num(proto
);
841 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
842 return CMD_WARNING_CONFIG_FAILED
;
845 ret
= ip_protocol_rm_del(zvrf
, rmap
, rtype
, AFI_IP6
, SAFI_UNICAST
);
850 DEFPY (show_ipv6_protocol
,
851 show_ipv6_protocol_cmd
,
852 "show ipv6 protocol [vrf <NAME$vrf_name|all$vrf_all>]",
855 "IPv6 protocol filtering status\n"
856 VRF_FULL_CMD_HELP_STR
)
858 int ret
= show_proto_rm(vty
, AFI_IP6
, vrf_all
, vrf_name
);
863 DEFPY (ip_protocol_nht_rmap
,
864 ip_protocol_nht_rmap_cmd
,
865 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
866 " $proto route-map ROUTE-MAP$rmap",
868 "Filter Next Hop tracking route resolution\n"
869 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
870 "Specify route map\n"
879 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
884 if (strcasecmp(proto
, "any") == 0)
885 rtype
= ZEBRA_ROUTE_MAX
;
887 rtype
= proto_name2num(proto
);
889 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
890 return CMD_WARNING_CONFIG_FAILED
;
893 ret
= ip_nht_rm_add(zvrf
, rmap
, rtype
, AFI_IP
);
898 DEFPY (no_ip_protocol_nht_rmap
,
899 no_ip_protocol_nht_rmap_cmd
,
900 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
901 " $proto route-map [ROUTE-MAP$rmap]",
904 "Filter Next Hop tracking route resolution\n"
905 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
906 "Specify route map\n"
913 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
918 if (strcasecmp(proto
, "any") == 0)
919 rtype
= ZEBRA_ROUTE_MAX
;
921 rtype
= proto_name2num(proto
);
923 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
924 return CMD_WARNING_CONFIG_FAILED
;
927 ret
= ip_nht_rm_del(zvrf
, rmap
, rtype
, AFI_IP
);
932 DEFPY (show_ip_protocol_nht
,
933 show_ip_protocol_nht_cmd
,
934 "show ip nht route-map [vrf <NAME$vrf_name|all$vrf_all>]",
937 "IP nexthop tracking table\n"
938 "IP Next Hop tracking filtering status\n"
939 VRF_FULL_CMD_HELP_STR
)
941 int ret
= show_nht_rm(vty
, AFI_IP
, vrf_all
, vrf_name
);
946 DEFPY (ipv6_protocol_nht_rmap
,
947 ipv6_protocol_nht_rmap_cmd
,
948 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
949 " $proto route-map ROUTE-MAP$rmap",
951 "Filter Next Hop tracking route resolution\n"
952 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
953 "Specify route map\n"
961 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
966 if (strcasecmp(proto
, "any") == 0)
967 rtype
= ZEBRA_ROUTE_MAX
;
969 rtype
= proto_name2num(proto
);
971 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
972 return CMD_WARNING_CONFIG_FAILED
;
975 ret
= ip_nht_rm_add(zvrf
, rmap
, rtype
, AFI_IP6
);
980 DEFPY (no_ipv6_protocol_nht_rmap
,
981 no_ipv6_protocol_nht_rmap_cmd
,
982 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
983 " $proto [route-map ROUTE-MAP$rmap]",
986 "Filter Next Hop tracking route resolution\n"
987 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
988 "Specify route map\n"
995 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1000 if (strcasecmp(proto
, "any") == 0)
1001 rtype
= ZEBRA_ROUTE_MAX
;
1003 rtype
= proto_name2num(proto
);
1005 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
1006 return CMD_WARNING_CONFIG_FAILED
;
1009 ret
= ip_nht_rm_del(zvrf
, rmap
, rtype
, AFI_IP6
);
1014 DEFPY (show_ipv6_protocol_nht
,
1015 show_ipv6_protocol_nht_cmd
,
1016 "show ipv6 nht route-map [vrf <NAME$vrf_name|all$vrf_all>]",
1019 "Next Hop filtering status\n"
1021 VRF_FULL_CMD_HELP_STR
)
1023 int ret
= show_nht_rm(vty
, AFI_IP6
, vrf_all
, vrf_name
);
1028 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
1030 /* `match ip next-hop IP_ACCESS_LIST' */
1032 /* Match function return 1 if match is success else return zero. */
1033 static enum route_map_cmd_result_t
1034 route_match_ip_next_hop(void *rule
, const struct prefix
*prefix
,
1035 route_map_object_t type
, void *object
)
1037 struct access_list
*alist
;
1038 struct nh_rmap_obj
*nh_data
;
1039 struct prefix_ipv4 p
;
1041 if (type
== RMAP_ZEBRA
) {
1044 return RMAP_NOMATCH
;
1046 switch (nh_data
->nexthop
->type
) {
1047 case NEXTHOP_TYPE_IFINDEX
:
1048 /* Interface routes can't match ip next-hop */
1049 return RMAP_NOMATCH
;
1050 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1051 case NEXTHOP_TYPE_IPV4
:
1053 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1054 p
.prefixlen
= IPV4_MAX_BITLEN
;
1057 return RMAP_NOMATCH
;
1059 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
1061 return RMAP_NOMATCH
;
1063 return (access_list_apply(alist
, &p
) == FILTER_DENY
1067 return RMAP_NOMATCH
;
1070 /* Route map `ip next-hop' match statement. `arg' should be
1071 access-list name. */
1072 static void *route_match_ip_next_hop_compile(const char *arg
)
1074 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1077 /* Free route map's compiled `. */
1078 static void route_match_ip_next_hop_free(void *rule
)
1080 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1083 /* Route map commands for ip next-hop matching. */
1084 static const struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
1086 route_match_ip_next_hop
,
1087 route_match_ip_next_hop_compile
,
1088 route_match_ip_next_hop_free
1091 /* `match ip next-hop prefix-list PREFIX_LIST' */
1093 static enum route_map_cmd_result_t
1094 route_match_ip_next_hop_prefix_list(void *rule
, const struct prefix
*prefix
,
1095 route_map_object_t type
, void *object
)
1097 struct prefix_list
*plist
;
1098 struct nh_rmap_obj
*nh_data
;
1099 struct prefix_ipv4 p
;
1101 if (type
== RMAP_ZEBRA
) {
1102 nh_data
= (struct nh_rmap_obj
*)object
;
1104 return RMAP_NOMATCH
;
1106 switch (nh_data
->nexthop
->type
) {
1107 case NEXTHOP_TYPE_IFINDEX
:
1108 /* Interface routes can't match ip next-hop */
1109 return RMAP_NOMATCH
;
1110 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1111 case NEXTHOP_TYPE_IPV4
:
1113 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1114 p
.prefixlen
= IPV4_MAX_BITLEN
;
1117 return RMAP_NOMATCH
;
1119 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
1121 return RMAP_NOMATCH
;
1123 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
1127 return RMAP_NOMATCH
;
1130 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
1132 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1135 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
1137 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1140 static const struct route_map_rule_cmd
1141 route_match_ip_next_hop_prefix_list_cmd
= {
1142 "ip next-hop prefix-list",
1143 route_match_ip_next_hop_prefix_list
,
1144 route_match_ip_next_hop_prefix_list_compile
,
1145 route_match_ip_next_hop_prefix_list_free
1148 /* `match ip address IP_ACCESS_LIST' */
1150 /* Match function should return 1 if match is success else return
1152 static enum route_map_cmd_result_t
1153 route_match_address(afi_t afi
, void *rule
, const struct prefix
*prefix
,
1154 route_map_object_t type
, void *object
)
1156 struct access_list
*alist
;
1158 if (type
== RMAP_ZEBRA
) {
1159 alist
= access_list_lookup(afi
, (char *)rule
);
1161 return RMAP_NOMATCH
;
1163 return (access_list_apply(alist
, prefix
) == FILTER_DENY
1167 return RMAP_NOMATCH
;
1170 static enum route_map_cmd_result_t
1171 route_match_ip_address(void *rule
, const struct prefix
*prefix
,
1172 route_map_object_t type
, void *object
)
1174 return route_match_address(AFI_IP
, rule
, prefix
, type
, object
);
1177 static enum route_map_cmd_result_t
1178 route_match_ipv6_address(void *rule
, const struct prefix
*prefix
,
1179 route_map_object_t type
, void *object
)
1181 return route_match_address(AFI_IP6
, rule
, prefix
, type
, object
);
1184 /* Route map `ip address' match statement. `arg' should be
1185 access-list name. */
1186 static void *route_match_address_compile(const char *arg
)
1188 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1191 /* Free route map's compiled `ip address' value. */
1192 static void route_match_address_free(void *rule
)
1194 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1197 /* Route map commands for ip address matching. */
1198 static const struct route_map_rule_cmd route_match_ip_address_cmd
= {
1200 route_match_ip_address
,
1201 route_match_address_compile
,
1202 route_match_address_free
1205 /* Route map commands for ipv6 address matching. */
1206 static const struct route_map_rule_cmd route_match_ipv6_address_cmd
= {
1208 route_match_ipv6_address
,
1209 route_match_address_compile
,
1210 route_match_address_free
1213 /* `match ip address prefix-list PREFIX_LIST' */
1215 static enum route_map_cmd_result_t
1216 route_match_address_prefix_list(void *rule
, const struct prefix
*prefix
,
1217 route_map_object_t type
, void *object
, afi_t afi
)
1219 struct prefix_list
*plist
;
1221 if (type
== RMAP_ZEBRA
) {
1222 plist
= prefix_list_lookup(afi
, (char *)rule
);
1224 return RMAP_NOMATCH
;
1226 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
1230 return RMAP_NOMATCH
;
1233 static enum route_map_cmd_result_t
1234 route_match_ip_address_prefix_list(void *rule
, const struct prefix
*prefix
,
1235 route_map_object_t type
, void *object
)
1237 return (route_match_address_prefix_list(rule
, prefix
, type
, object
,
1241 static void *route_match_address_prefix_list_compile(const char *arg
)
1243 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1246 static void route_match_address_prefix_list_free(void *rule
)
1248 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1251 static const struct route_map_rule_cmd
1252 route_match_ip_address_prefix_list_cmd
= {
1253 "ip address prefix-list",
1254 route_match_ip_address_prefix_list
,
1255 route_match_address_prefix_list_compile
,
1256 route_match_address_prefix_list_free
1259 static enum route_map_cmd_result_t
1260 route_match_ipv6_address_prefix_list(void *rule
, const struct prefix
*prefix
,
1261 route_map_object_t type
, void *object
)
1263 return (route_match_address_prefix_list(rule
, prefix
, type
, object
,
1267 static const struct route_map_rule_cmd
1268 route_match_ipv6_address_prefix_list_cmd
= {
1269 "ipv6 address prefix-list",
1270 route_match_ipv6_address_prefix_list
,
1271 route_match_address_prefix_list_compile
,
1272 route_match_address_prefix_list_free
1275 /* `match ipv6 next-hop type <TYPE>' */
1277 static enum route_map_cmd_result_t
1278 route_match_ipv6_next_hop_type(void *rule
, const struct prefix
*prefix
,
1279 route_map_object_t type
, void *object
)
1281 struct nh_rmap_obj
*nh_data
;
1283 if (type
== RMAP_ZEBRA
&& prefix
->family
== AF_INET6
) {
1284 nh_data
= (struct nh_rmap_obj
*)object
;
1286 return RMAP_NOMATCH
;
1288 if (nh_data
->nexthop
->type
== NEXTHOP_TYPE_BLACKHOLE
)
1291 return RMAP_NOMATCH
;
1294 static void *route_match_ipv6_next_hop_type_compile(const char *arg
)
1296 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1299 static void route_match_ipv6_next_hop_type_free(void *rule
)
1301 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1304 static const struct route_map_rule_cmd
1305 route_match_ipv6_next_hop_type_cmd
= {
1306 "ipv6 next-hop type",
1307 route_match_ipv6_next_hop_type
,
1308 route_match_ipv6_next_hop_type_compile
,
1309 route_match_ipv6_next_hop_type_free
1312 /* `match ip address prefix-len PREFIXLEN' */
1314 static enum route_map_cmd_result_t
1315 route_match_address_prefix_len(void *rule
, const struct prefix
*prefix
,
1316 route_map_object_t type
, void *object
)
1318 uint32_t *prefixlen
= (uint32_t *)rule
;
1320 if (type
== RMAP_ZEBRA
) {
1321 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1324 return RMAP_NOMATCH
;
1327 static void *route_match_address_prefix_len_compile(const char *arg
)
1329 uint32_t *prefix_len
;
1330 char *endptr
= NULL
;
1331 unsigned long tmpval
;
1333 /* prefix len value shoud be integer. */
1334 if (!all_digit(arg
))
1338 tmpval
= strtoul(arg
, &endptr
, 10);
1339 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1342 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1344 *prefix_len
= tmpval
;
1348 static void route_match_address_prefix_len_free(void *rule
)
1350 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1353 static const struct route_map_rule_cmd
1354 route_match_ip_address_prefix_len_cmd
= {
1355 "ip address prefix-len",
1356 route_match_address_prefix_len
,
1357 route_match_address_prefix_len_compile
,
1358 route_match_address_prefix_len_free
1361 static const struct route_map_rule_cmd
1362 route_match_ipv6_address_prefix_len_cmd
= {
1363 "ipv6 address prefix-len",
1364 route_match_address_prefix_len
,
1365 route_match_address_prefix_len_compile
,
1366 route_match_address_prefix_len_free
1369 /* `match ip nexthop prefix-len PREFIXLEN' */
1371 static enum route_map_cmd_result_t
1372 route_match_ip_nexthop_prefix_len(void *rule
, const struct prefix
*prefix
,
1373 route_map_object_t type
, void *object
)
1375 uint32_t *prefixlen
= (uint32_t *)rule
;
1376 struct nh_rmap_obj
*nh_data
;
1377 struct prefix_ipv4 p
;
1379 if (type
== RMAP_ZEBRA
) {
1380 nh_data
= (struct nh_rmap_obj
*)object
;
1381 if (!nh_data
|| !nh_data
->nexthop
)
1382 return RMAP_NOMATCH
;
1384 switch (nh_data
->nexthop
->type
) {
1385 case NEXTHOP_TYPE_IFINDEX
:
1386 /* Interface routes can't match ip next-hop */
1387 return RMAP_NOMATCH
;
1388 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1389 case NEXTHOP_TYPE_IPV4
:
1391 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1392 p
.prefixlen
= IPV4_MAX_BITLEN
;
1395 return RMAP_NOMATCH
;
1397 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1400 return RMAP_NOMATCH
;
1403 static const struct route_map_rule_cmd
1404 route_match_ip_nexthop_prefix_len_cmd
= {
1405 "ip next-hop prefix-len",
1406 route_match_ip_nexthop_prefix_len
,
1407 route_match_address_prefix_len_compile
, /* reuse */
1408 route_match_address_prefix_len_free
/* reuse */
1411 /* `match ip next-hop type <blackhole>' */
1413 static enum route_map_cmd_result_t
1414 route_match_ip_next_hop_type(void *rule
, const struct prefix
*prefix
,
1415 route_map_object_t type
, void *object
)
1417 struct nh_rmap_obj
*nh_data
;
1419 if (type
== RMAP_ZEBRA
&& prefix
->family
== AF_INET
) {
1420 nh_data
= (struct nh_rmap_obj
*)object
;
1422 return RMAP_NOMATCH
;
1424 if (nh_data
->nexthop
->type
== NEXTHOP_TYPE_BLACKHOLE
)
1427 return RMAP_NOMATCH
;
1430 static void *route_match_ip_next_hop_type_compile(const char *arg
)
1432 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1435 static void route_match_ip_next_hop_type_free(void *rule
)
1437 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1440 static const struct route_map_rule_cmd
1441 route_match_ip_next_hop_type_cmd
= {
1443 route_match_ip_next_hop_type
,
1444 route_match_ip_next_hop_type_compile
,
1445 route_match_ip_next_hop_type_free
1448 /* `match source-protocol PROTOCOL' */
1450 static enum route_map_cmd_result_t
1451 route_match_source_protocol(void *rule
, const struct prefix
*p
,
1452 route_map_object_t type
, void *object
)
1454 uint32_t *rib_type
= (uint32_t *)rule
;
1455 struct nh_rmap_obj
*nh_data
;
1457 if (type
== RMAP_ZEBRA
) {
1458 nh_data
= (struct nh_rmap_obj
*)object
;
1460 return RMAP_NOMATCH
;
1462 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1465 return RMAP_NOMATCH
;
1468 static void *route_match_source_protocol_compile(const char *arg
)
1473 i
= proto_name2num(arg
);
1474 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1481 static void route_match_source_protocol_free(void *rule
)
1483 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1486 static const struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1488 route_match_source_protocol
,
1489 route_match_source_protocol_compile
,
1490 route_match_source_protocol_free
1493 /* `source-instance` */
1494 static enum route_map_cmd_result_t
1495 route_match_source_instance(void *rule
, const struct prefix
*p
,
1496 route_map_object_t type
, void *object
)
1498 uint8_t *instance
= (uint8_t *)rule
;
1499 struct nh_rmap_obj
*nh_data
;
1501 if (type
!= RMAP_ZEBRA
)
1502 return RMAP_NOMATCH
;
1504 nh_data
= (struct nh_rmap_obj
*)object
;
1506 return RMAP_NOMATCH
;
1508 return (nh_data
->instance
== *instance
) ? RMAP_MATCH
: RMAP_NOMATCH
;
1511 static void *route_match_source_instance_compile(const char *arg
)
1517 instance
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1524 static void route_match_source_instance_free(void *rule
)
1526 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1529 static const struct route_map_rule_cmd route_match_source_instance_cmd
= {
1531 route_match_source_instance
,
1532 route_match_source_instance_compile
,
1533 route_match_source_instance_free
1536 /* `set src A.B.C.D' */
1539 static enum route_map_cmd_result_t
1540 route_set_src(void *rule
, const struct prefix
*prefix
, route_map_object_t type
,
1543 struct nh_rmap_obj
*nh_data
;
1545 if (type
== RMAP_ZEBRA
) {
1546 nh_data
= (struct nh_rmap_obj
*)object
;
1547 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1552 /* set src compilation. */
1553 static void *route_set_src_compile(const char *arg
)
1555 union g_addr src
, *psrc
;
1557 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1558 || (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)) {
1559 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1566 /* Free route map's compiled `set src' value. */
1567 static void route_set_src_free(void *rule
)
1569 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1572 /* Set src rule structure. */
1573 static const struct route_map_rule_cmd route_set_src_cmd
= {
1576 route_set_src_compile
,
1580 /* The function checks if the changed routemap specified by parameter rmap
1581 * matches the configured protocol routemaps in proto_rm table. If there is
1582 * a match then rib_update_table() to process the routes.
1584 static void zebra_rib_table_rm_update(const char *rmap
)
1587 struct route_table
*table
;
1588 struct vrf
*vrf
= NULL
;
1589 struct zebra_vrf
*zvrf
= NULL
;
1593 struct route_map
*old
= NULL
;
1595 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1599 for (i
= 0; i
<= ZEBRA_ROUTE_MAX
; i
++) {
1600 rmap_name
= PROTO_RM_NAME(zvrf
, AFI_IP
, i
);
1601 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1602 if (IS_ZEBRA_DEBUG_EVENT
)
1604 "%s : AFI_IP rmap %s, route type %s",
1606 zebra_route_string(i
));
1608 old
= PROTO_RM_MAP(zvrf
, AFI_IP
, i
);
1610 PROTO_RM_MAP(zvrf
, AFI_IP
, i
) =
1611 route_map_lookup_by_name(rmap_name
);
1612 /* old is NULL. i.e Route map creation event.
1613 * So update applied_counter.
1614 * If Old is not NULL, i.e It may be routemap
1615 * updation or deletion.
1616 * So no need to update the counter.
1619 route_map_counter_increment(
1620 PROTO_RM_MAP(zvrf
, AFI_IP
, i
));
1621 /* There is single rib table for all protocols
1624 table
= zvrf
->table
[AFI_IP
]
1631 RIB_UPDATE_RMAP_CHANGE
);
1635 rmap_name
= PROTO_RM_NAME(zvrf
, AFI_IP6
, i
);
1636 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1637 if (IS_ZEBRA_DEBUG_EVENT
)
1639 "%s : AFI_IP6 rmap %s, route type %s",
1641 zebra_route_string(i
));
1643 old
= PROTO_RM_MAP(zvrf
, AFI_IP6
, i
);
1645 PROTO_RM_MAP(zvrf
, AFI_IP6
, i
) =
1646 route_map_lookup_by_name(rmap_name
);
1648 route_map_counter_increment(
1649 PROTO_RM_MAP(zvrf
, AFI_IP6
, i
));
1650 /* There is single rib table for all protocols
1652 if (afi_ipv6
== 0) {
1653 table
= zvrf
->table
[AFI_IP6
]
1660 RIB_UPDATE_RMAP_CHANGE
);
1668 /* The function checks if the changed routemap specified by parameter rmap
1669 * matches the configured protocol routemaps in nht_rm table. If there is
1670 * a match then zebra_evaluate_rnh() to process the nexthops.
1672 static void zebra_nht_rm_update(const char *rmap
)
1675 struct route_table
*table
;
1676 struct vrf
*vrf
= NULL
;
1677 struct zebra_vrf
*zvrf
= NULL
;
1681 struct route_map
*old
= NULL
;
1683 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1687 for (i
= 0; i
<= ZEBRA_ROUTE_MAX
; i
++) {
1688 rmap_name
= NHT_RM_NAME(zvrf
, AFI_IP
, i
);
1689 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1690 if (IS_ZEBRA_DEBUG_EVENT
)
1692 "%s : AFI_IP rmap %s, route type %s",
1694 zebra_route_string(i
));
1696 old
= NHT_RM_MAP(zvrf
, AFI_IP
, i
);
1698 NHT_RM_MAP(zvrf
, AFI_IP
, i
) =
1699 route_map_lookup_by_name(rmap_name
);
1701 route_map_counter_increment(
1702 NHT_RM_MAP(zvrf
, AFI_IP
, i
));
1703 /* There is single rib table for all protocols
1706 table
= zvrf
->table
[AFI_IP
]
1714 RNH_NEXTHOP_TYPE
, NULL
);
1719 rmap_name
= NHT_RM_NAME(zvrf
, AFI_IP6
, i
);
1720 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1721 if (IS_ZEBRA_DEBUG_EVENT
)
1723 "%s : AFI_IP6 rmap %s, route type %s",
1725 zebra_route_string(i
));
1727 old
= NHT_RM_MAP(zvrf
, AFI_IP6
, i
);
1729 NHT_RM_MAP(zvrf
, AFI_IP6
, i
) =
1730 route_map_lookup_by_name(rmap_name
);
1732 route_map_counter_increment(
1733 NHT_RM_MAP(zvrf
, AFI_IP6
, i
));
1734 /* There is single rib table for all protocols
1736 if (afi_ipv6
== 0) {
1737 table
= zvrf
->table
[AFI_IP6
]
1745 RNH_NEXTHOP_TYPE
, NULL
);
1753 static void zebra_route_map_process_update_cb(char *rmap_name
)
1755 if (IS_ZEBRA_DEBUG_EVENT
)
1756 zlog_debug("Event handler for route-map: %s",
1758 zebra_import_table_rm_update(rmap_name
);
1759 zebra_rib_table_rm_update(rmap_name
);
1760 zebra_nht_rm_update(rmap_name
);
1763 static int zebra_route_map_update_timer(struct thread
*thread
)
1765 zebra_t_rmap_update
= NULL
;
1767 if (IS_ZEBRA_DEBUG_EVENT
)
1768 zlog_debug("Event driven route-map update triggered");
1770 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1772 "%u: Routemap update-timer fired, scheduling RIB processing",
1775 route_map_walk_update_list(zebra_route_map_process_update_cb
);
1778 * This code needs to be updated to be:
1779 * 1) VRF Aware <sigh>
1780 * 2) Route-map aware
1785 static void zebra_route_map_set_delay_timer(uint32_t value
)
1787 zebra_rmap_update_timer
= value
;
1788 if (!value
&& zebra_t_rmap_update
) {
1789 /* Event driven route map updates is being disabled */
1790 /* But there's a pending timer. Fire it off now */
1791 thread_cancel(zebra_t_rmap_update
);
1792 zebra_route_map_update_timer(zebra_t_rmap_update
);
1796 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1798 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1799 vty_out(vty
, "zebra route-map delay-timer %d\n",
1800 zebra_rmap_update_timer
);
1805 zebra_route_map_check(int family
, int rib_type
, uint8_t instance
,
1806 const struct prefix
*p
, struct nexthop
*nexthop
,
1807 struct zebra_vrf
*zvrf
, route_tag_t tag
)
1809 struct route_map
*rmap
= NULL
;
1810 route_map_result_t ret
= RMAP_PERMITMATCH
;
1811 struct nh_rmap_obj nh_obj
;
1813 nh_obj
.nexthop
= nexthop
;
1814 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1815 nh_obj
.source_protocol
= rib_type
;
1816 nh_obj
.instance
= instance
;
1820 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1821 rmap
= PROTO_RM_MAP(zvrf
, family
, rib_type
);
1822 if (!rmap
&& PROTO_RM_NAME(zvrf
, family
, ZEBRA_ROUTE_MAX
))
1823 rmap
= PROTO_RM_MAP(zvrf
, family
, ZEBRA_ROUTE_MAX
);
1825 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1831 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1833 return zebra_import_table_routemap
[afi
][table
];
1836 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1839 zebra_import_table_routemap
[afi
][table
] =
1840 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1843 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1845 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1849 zebra_import_table_route_map_check(int family
, int re_type
, uint8_t instance
,
1850 const struct prefix
*p
,
1851 struct nexthop
*nexthop
,
1852 vrf_id_t vrf_id
, route_tag_t tag
,
1853 const char *rmap_name
)
1855 struct route_map
*rmap
= NULL
;
1856 route_map_result_t ret
= RMAP_DENYMATCH
;
1857 struct nh_rmap_obj nh_obj
;
1859 nh_obj
.nexthop
= nexthop
;
1860 nh_obj
.vrf_id
= vrf_id
;
1861 nh_obj
.source_protocol
= re_type
;
1862 nh_obj
.instance
= instance
;
1866 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1867 rmap
= route_map_lookup_by_name(rmap_name
);
1869 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1875 route_map_result_t
zebra_nht_route_map_check(afi_t afi
, int client_proto
,
1876 const struct prefix
*p
,
1877 struct zebra_vrf
*zvrf
,
1878 struct route_entry
*re
,
1879 struct nexthop
*nexthop
)
1881 struct route_map
*rmap
= NULL
;
1882 route_map_result_t ret
= RMAP_PERMITMATCH
;
1883 struct nh_rmap_obj nh_obj
;
1885 nh_obj
.nexthop
= nexthop
;
1886 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1887 nh_obj
.source_protocol
= re
->type
;
1888 nh_obj
.instance
= re
->instance
;
1889 nh_obj
.metric
= re
->metric
;
1890 nh_obj
.tag
= re
->tag
;
1892 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1893 rmap
= NHT_RM_MAP(zvrf
, afi
, client_proto
);
1894 if (!rmap
&& NHT_RM_MAP(zvrf
, afi
, ZEBRA_ROUTE_MAX
))
1895 rmap
= NHT_RM_MAP(zvrf
, afi
, ZEBRA_ROUTE_MAX
);
1897 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1902 static void zebra_route_map_mark_update(const char *rmap_name
)
1904 /* rmap_update_timer of 0 means don't do route updates */
1905 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1906 zebra_t_rmap_update
= NULL
;
1907 thread_add_timer(zrouter
.master
, zebra_route_map_update_timer
,
1908 NULL
, zebra_rmap_update_timer
,
1909 &zebra_t_rmap_update
);
1913 static void zebra_route_map_add(const char *rmap_name
)
1915 if (route_map_mark_updated(rmap_name
) == 0)
1916 zebra_route_map_mark_update(rmap_name
);
1918 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1921 static void zebra_route_map_delete(const char *rmap_name
)
1923 if (route_map_mark_updated(rmap_name
) == 0)
1924 zebra_route_map_mark_update(rmap_name
);
1926 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1929 static void zebra_route_map_event(const char *rmap_name
)
1931 if (route_map_mark_updated(rmap_name
) == 0)
1932 zebra_route_map_mark_update(rmap_name
);
1934 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1937 /* ip protocol configuration write function */
1938 void zebra_routemap_config_write_protocol(struct vty
*vty
,
1939 struct zebra_vrf
*zvrf
)
1944 memset(space
, 0, sizeof(space
));
1946 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
1947 sprintf(space
, "%s", " ");
1949 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1950 if (PROTO_RM_NAME(zvrf
, AFI_IP
, i
))
1951 vty_out(vty
, "%sip protocol %s route-map %s\n", space
,
1952 zebra_route_string(i
),
1953 PROTO_RM_NAME(zvrf
, AFI_IP
, i
));
1955 if (PROTO_RM_NAME(zvrf
, AFI_IP6
, i
))
1956 vty_out(vty
, "%sipv6 protocol %s route-map %s\n", space
,
1957 zebra_route_string(i
),
1958 PROTO_RM_NAME(zvrf
, AFI_IP6
, i
));
1960 if (NHT_RM_NAME(zvrf
, AFI_IP
, i
))
1961 vty_out(vty
, "%sip nht %s route-map %s\n", space
,
1962 zebra_route_string(i
),
1963 NHT_RM_NAME(zvrf
, AFI_IP
, i
));
1965 if (NHT_RM_NAME(zvrf
, AFI_IP6
, i
))
1966 vty_out(vty
, "%sipv6 nht %s route-map %s\n", space
,
1967 zebra_route_string(i
),
1968 NHT_RM_NAME(zvrf
, AFI_IP6
, i
));
1971 if (PROTO_RM_NAME(zvrf
, AFI_IP
, ZEBRA_ROUTE_MAX
))
1972 vty_out(vty
, "%sip protocol %s route-map %s\n", space
, "any",
1973 PROTO_RM_NAME(zvrf
, AFI_IP
, ZEBRA_ROUTE_MAX
));
1975 if (PROTO_RM_NAME(zvrf
, AFI_IP6
, ZEBRA_ROUTE_MAX
))
1976 vty_out(vty
, "%sipv6 protocol %s route-map %s\n", space
, "any",
1977 PROTO_RM_NAME(zvrf
, AFI_IP6
, ZEBRA_ROUTE_MAX
));
1979 if (NHT_RM_NAME(zvrf
, AFI_IP
, ZEBRA_ROUTE_MAX
))
1980 vty_out(vty
, "%sip nht %s route-map %s\n", space
, "any",
1981 NHT_RM_NAME(zvrf
, AFI_IP
, ZEBRA_ROUTE_MAX
));
1983 if (NHT_RM_NAME(zvrf
, AFI_IP6
, ZEBRA_ROUTE_MAX
))
1984 vty_out(vty
, "%sipv6 nht %s route-map %s\n", space
, "any",
1985 NHT_RM_NAME(zvrf
, AFI_IP6
, ZEBRA_ROUTE_MAX
));
1987 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1988 vty_out(vty
, "zebra route-map delay-timer %d\n",
1989 zebra_rmap_update_timer
);
1992 void zebra_route_map_init(void)
1994 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1995 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1996 install_element(VRF_NODE
, &ip_protocol_cmd
);
1997 install_element(VRF_NODE
, &no_ip_protocol_cmd
);
1998 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1999 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
2000 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
2001 install_element(VRF_NODE
, &ipv6_protocol_cmd
);
2002 install_element(VRF_NODE
, &no_ipv6_protocol_cmd
);
2003 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
2004 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
2005 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
2006 install_element(VRF_NODE
, &ip_protocol_nht_rmap_cmd
);
2007 install_element(VRF_NODE
, &no_ip_protocol_nht_rmap_cmd
);
2008 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
2009 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
2010 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
2011 install_element(VRF_NODE
, &ipv6_protocol_nht_rmap_cmd
);
2012 install_element(VRF_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
2013 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
2014 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
2015 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
2019 route_map_add_hook(zebra_route_map_add
);
2020 route_map_delete_hook(zebra_route_map_delete
);
2021 route_map_event_hook(zebra_route_map_event
);
2023 route_map_match_interface_hook(generic_match_add
);
2024 route_map_no_match_interface_hook(generic_match_delete
);
2026 route_map_match_ip_address_hook(generic_match_add
);
2027 route_map_no_match_ip_address_hook(generic_match_delete
);
2029 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
2030 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
2032 route_map_match_ip_next_hop_hook(generic_match_add
);
2033 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
2035 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
2036 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
2038 route_map_match_ip_next_hop_type_hook(generic_match_add
);
2039 route_map_no_match_ip_next_hop_type_hook(generic_match_delete
);
2041 route_map_match_tag_hook(generic_match_add
);
2042 route_map_no_match_tag_hook(generic_match_delete
);
2044 route_map_match_ipv6_address_hook(generic_match_add
);
2045 route_map_no_match_ipv6_address_hook(generic_match_delete
);
2047 route_map_match_ipv6_address_prefix_list_hook(generic_match_add
);
2048 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete
);
2050 route_map_match_ipv6_next_hop_type_hook(generic_match_add
);
2051 route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete
);
2053 route_map_install_match(&route_match_tag_cmd
);
2054 route_map_install_match(&route_match_interface_cmd
);
2055 route_map_install_match(&route_match_ip_next_hop_cmd
);
2056 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
2057 route_map_install_match(&route_match_ip_address_cmd
);
2058 route_map_install_match(&route_match_ipv6_address_cmd
);
2059 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
2060 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd
);
2061 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
2062 route_map_install_match(&route_match_ipv6_address_prefix_len_cmd
);
2063 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
2064 route_map_install_match(&route_match_ip_next_hop_type_cmd
);
2065 route_map_install_match(&route_match_ipv6_next_hop_type_cmd
);
2066 route_map_install_match(&route_match_source_protocol_cmd
);
2067 route_map_install_match(&route_match_source_instance_cmd
);
2070 route_map_install_set(&route_set_src_cmd
);
2072 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
2073 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
2074 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
2075 install_element(RMAP_NODE
, &match_ipv6_address_prefix_len_cmd
);
2076 install_element(RMAP_NODE
, &no_match_ipv6_address_prefix_len_cmd
);
2077 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
2078 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
2079 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
2080 install_element(RMAP_NODE
, &match_source_instance_cmd
);
2081 install_element(RMAP_NODE
, &no_match_source_instance_cmd
);
2084 install_element(RMAP_NODE
, &set_src_cmd
);
2085 install_element(RMAP_NODE
, &no_set_src_cmd
);