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
,
141 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 struct route_map_rule_cmd route_match_tag_cmd
= {
159 "tag", route_match_tag
, route_map_rule_tag_compile
,
160 route_map_rule_tag_free
,
164 /* `match interface IFNAME' */
165 /* Match function return 1 if match is success else return zero. */
166 static route_map_result_t
route_match_interface(void *rule
,
167 const struct prefix
*prefix
,
168 route_map_object_t type
,
171 struct nh_rmap_obj
*nh_data
;
175 if (type
== RMAP_ZEBRA
) {
176 if (strcasecmp(ifname
, "any") == 0)
179 if (!nh_data
|| !nh_data
->nexthop
)
181 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
184 if (nh_data
->nexthop
->ifindex
== ifindex
)
190 /* Route map `match interface' match statement. `arg' is IFNAME value */
191 static void *route_match_interface_compile(const char *arg
)
193 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
196 /* Free route map's compiled `match interface' value. */
197 static void route_match_interface_free(void *rule
)
199 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
202 /* Route map commands for interface matching */
203 struct route_map_rule_cmd route_match_interface_cmd
= {
204 "interface", route_match_interface
, route_match_interface_compile
,
205 route_match_interface_free
};
207 DEFUN (match_ip_address_prefix_len
,
208 match_ip_address_prefix_len_cmd
,
209 "match ip address prefix-len (0-32)",
212 "Match prefix length of ip address\n"
213 "Match prefix length of ip address\n"
216 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
217 RMAP_EVENT_MATCH_ADDED
);
220 DEFUN (no_match_ip_address_prefix_len
,
221 no_match_ip_address_prefix_len_cmd
,
222 "no match ip address prefix-len [(0-32)]",
226 "Match prefix length of ip address\n"
227 "Match prefix length of ip address\n"
230 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
231 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
232 RMAP_EVENT_MATCH_DELETED
);
235 DEFUN (match_ipv6_address_prefix_len
,
236 match_ipv6_address_prefix_len_cmd
,
237 "match ipv6 address prefix-len (0-128)",
240 "Match prefix length of ipv6 address\n"
241 "Match prefix length of ipv6 address\n"
244 return zebra_route_match_add(vty
, "ipv6 address prefix-len",
245 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
248 DEFUN (no_match_ipv6_address_prefix_len
,
249 no_match_ipv6_address_prefix_len_cmd
,
250 "no match ipv6 address prefix-len [(0-128)]",
254 "Match prefix length of ip address\n"
255 "Match prefix length of ip address\n"
258 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
259 return zebra_route_match_delete(vty
, "ipv6 address prefix-len", plen
,
260 RMAP_EVENT_MATCH_DELETED
);
263 DEFUN (match_ip_nexthop_prefix_len
,
264 match_ip_nexthop_prefix_len_cmd
,
265 "match ip next-hop prefix-len (0-32)",
268 "Match prefixlen of nexthop ip address\n"
269 "Match prefixlen of given nexthop\n"
272 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
273 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
276 DEFUN (no_match_ip_nexthop_prefix_len
,
277 no_match_ip_nexthop_prefix_len_cmd
,
278 "no match ip next-hop prefix-len [(0-32)]",
282 "Match prefixlen of nexthop ip address\n"
283 "Match prefix length of nexthop\n"
286 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
287 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
288 RMAP_EVENT_MATCH_DELETED
);
291 DEFUN (match_source_protocol
,
292 match_source_protocol_cmd
,
293 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
295 "Match protocol via which the route was learnt\n"
306 "Routes from directly connected peer\n"
307 "Routes from system configuration\n"
308 "Routes from kernel\n"
309 "Statically configured routes\n"
312 char *proto
= argv
[2]->text
;
315 i
= proto_name2num(proto
);
317 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
318 return CMD_WARNING_CONFIG_FAILED
;
320 return zebra_route_match_add(vty
, "source-protocol", proto
,
321 RMAP_EVENT_MATCH_ADDED
);
324 DEFUN (no_match_source_protocol
,
325 no_match_source_protocol_cmd
,
326 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
329 "No match protocol via which the route was learnt\n"
340 "Routes from directly connected peer\n"
341 "Routes from system configuration\n"
342 "Routes from kernel\n"
343 "Statically configured routes\n"
346 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
347 return zebra_route_match_delete(vty
, "source-protocol", proto
,
348 RMAP_EVENT_MATCH_DELETED
);
351 DEFUN (match_source_instance
,
352 match_source_instance_cmd
,
353 "match source-instance (0-255)",
355 "Match the protocol's instance number\n"
356 "The instance number\n")
358 char *instance
= argv
[2]->arg
;
360 return zebra_route_match_add(vty
, "source-instance", instance
,
361 RMAP_EVENT_MATCH_ADDED
);
364 DEFUN (no_match_source_instance
,
365 no_match_source_instance_cmd
,
366 "no match source-instance [(0-255)]",
368 "Match the protocol's instance number\n"
369 "The instance number\n")
371 char *instance
= (argc
== 4) ? argv
[3]->arg
: NULL
;
373 return zebra_route_match_delete(vty
, "source-instance", instance
,
374 RMAP_EVENT_MATCH_ADDED
);
381 "set src <A.B.C.D|X:X::X:X>",
383 "src address for route\n"
385 "IPv6 src address\n")
389 struct interface
*pif
= NULL
;
394 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
395 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
396 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
397 return CMD_WARNING_CONFIG_FAILED
;
400 p
.family
= family
= AF_INET6
;
401 p
.u
.prefix6
= src
.ipv6
;
402 p
.prefixlen
= IPV6_MAX_BITLEN
;
404 p
.family
= family
= AF_INET
;
405 p
.u
.prefix4
= src
.ipv4
;
406 p
.prefixlen
= IPV4_MAX_BITLEN
;
409 if (!zebra_check_addr(&p
)) {
410 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
411 return CMD_WARNING_CONFIG_FAILED
;
414 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
415 if (family
== AF_INET
)
416 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
417 AF_INET
, vrf
->vrf_id
);
418 else if (family
== AF_INET6
)
419 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
420 AF_INET6
, vrf
->vrf_id
);
427 vty_out(vty
, "%% not a local address\n");
428 return CMD_WARNING_CONFIG_FAILED
;
431 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
432 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
437 "no set src [<A.B.C.D|X:X::X:X>]",
440 "Source address for route\n"
444 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
445 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
446 return generic_set_delete(vty
, index
, "src", ip
);
449 DEFUN (zebra_route_map_timer
,
450 zebra_route_map_timer_cmd
,
451 "zebra route-map delay-timer (0-600)",
453 "Set route-map parameters\n"
454 "Time to wait before route-map updates are processed\n"
455 "0 means event-driven updates are disabled\n")
458 uint32_t rmap_delay_timer
;
460 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
461 zebra_route_map_set_delay_timer(rmap_delay_timer
);
463 return (CMD_SUCCESS
);
466 DEFUN (no_zebra_route_map_timer
,
467 no_zebra_route_map_timer_cmd
,
468 "no zebra route-map delay-timer [(0-600)]",
471 "Set route-map parameters\n"
472 "Reset delay-timer to default value, 30 secs\n"
473 "0 means event-driven updates are disabled\n")
475 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
477 return (CMD_SUCCESS
);
483 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
485 "Filter routing info exchanged between zebra and protocol\n"
486 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
487 "Specify route-map\n"
490 char *proto
= argv
[2]->text
;
491 char *rmap
= argv
[4]->arg
;
494 if (strcasecmp(proto
, "any") == 0)
497 i
= proto_name2num(proto
);
499 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
500 return CMD_WARNING_CONFIG_FAILED
;
502 if (proto_rm
[AFI_IP
][i
]) {
503 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
506 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
508 proto_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
510 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
512 "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
515 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
519 DEFUN (no_ip_protocol
,
521 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
524 "Stop filtering routing info between zebra and protocol\n"
525 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
526 "Specify route map\n"
529 char *proto
= argv
[3]->text
;
530 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
533 if (strcasecmp(proto
, "any") == 0)
536 i
= proto_name2num(proto
);
539 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
540 return CMD_WARNING_CONFIG_FAILED
;
543 if (!proto_rm
[AFI_IP
][i
])
546 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP
][i
]) == 0) {
547 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
548 proto_rm
[AFI_IP
][i
] = NULL
;
550 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
552 "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
554 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
559 DEFUN (show_ip_protocol
,
560 show_ip_protocol_cmd
,
564 "IP protocol filtering status\n")
568 vty_out(vty
, "Protocol : route-map \n");
569 vty_out(vty
, "------------------------\n");
570 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
571 if (proto_rm
[AFI_IP
][i
])
572 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
573 proto_rm
[AFI_IP
][i
]);
575 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
577 if (proto_rm
[AFI_IP
][i
])
578 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP
][i
]);
580 vty_out(vty
, "%-10s : none\n", "any");
585 DEFUN (ipv6_protocol
,
587 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
589 "Filter IPv6 routing info exchanged between zebra and protocol\n"
590 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
591 "Specify route map\n"
594 char *proto
= argv
[2]->text
;
595 char *rmap
= argv
[4]->arg
;
598 if (strcasecmp(proto
, "any") == 0)
601 i
= proto_name2num(proto
);
603 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
604 return CMD_WARNING_CONFIG_FAILED
;
606 if (proto_rm
[AFI_IP6
][i
]) {
607 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
610 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
612 proto_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
614 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
616 "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
619 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
623 DEFUN (no_ipv6_protocol
,
624 no_ipv6_protocol_cmd
,
625 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
628 "Stop filtering IPv6 routing info between zebra and protocol\n"
629 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
630 "Specify route map\n"
633 const char *proto
= argv
[3]->text
;
634 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
637 if (strcasecmp(proto
, "any") == 0)
640 i
= proto_name2num(proto
);
642 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
643 return CMD_WARNING_CONFIG_FAILED
;
645 if (!proto_rm
[AFI_IP6
][i
])
648 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0) {
649 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
650 proto_rm
[AFI_IP6
][i
] = NULL
;
652 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
654 "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
657 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
662 DEFUN (show_ipv6_protocol
,
663 show_ipv6_protocol_cmd
,
664 "show ipv6 protocol",
667 "IPv6 protocol filtering status\n")
671 vty_out(vty
, "Protocol : route-map \n");
672 vty_out(vty
, "------------------------\n");
673 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
674 if (proto_rm
[AFI_IP6
][i
])
675 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
676 proto_rm
[AFI_IP6
][i
]);
678 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
680 if (proto_rm
[AFI_IP6
][i
])
681 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP6
][i
]);
683 vty_out(vty
, "%-10s : none\n", "any");
688 DEFUN (ip_protocol_nht_rmap
,
689 ip_protocol_nht_rmap_cmd
,
690 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
692 "Filter Next Hop tracking route resolution\n"
693 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
694 "Specify route map\n"
697 char *proto
= argv
[2]->text
;
698 char *rmap
= argv
[4]->arg
;
701 if (strcasecmp(proto
, "any") == 0)
704 i
= proto_name2num(proto
);
706 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
707 return CMD_WARNING_CONFIG_FAILED
;
709 if (nht_rm
[AFI_IP
][i
]) {
710 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
713 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
716 nht_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
717 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
722 DEFUN (no_ip_protocol_nht_rmap
,
723 no_ip_protocol_nht_rmap_cmd
,
724 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
727 "Filter Next Hop tracking route resolution\n"
728 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
729 "Specify route map\n"
733 char *proto
= argv
[3]->text
;
734 char *rmap
= argv_find(argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
737 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
738 : proto_name2num(proto
);
741 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
742 return CMD_WARNING_CONFIG_FAILED
;
745 if (!nht_rm
[AFI_IP
][i
])
748 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0) {
749 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
750 nht_rm
[AFI_IP
][i
] = NULL
;
751 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
756 DEFUN (show_ip_protocol_nht
,
757 show_ip_protocol_nht_cmd
,
758 "show ip nht route-map",
761 "IP nexthop tracking table\n"
762 "IP Next Hop tracking filtering status\n")
766 vty_out(vty
, "Protocol : route-map \n");
767 vty_out(vty
, "------------------------\n");
768 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
769 if (nht_rm
[AFI_IP
][i
])
770 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
773 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
775 if (nht_rm
[AFI_IP
][i
])
776 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP
][i
]);
778 vty_out(vty
, "%-10s : none\n", "any");
783 DEFUN (ipv6_protocol_nht_rmap
,
784 ipv6_protocol_nht_rmap_cmd
,
785 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
787 "Filter Next Hop tracking route resolution\n"
788 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
789 "Specify route map\n"
792 char *proto
= argv
[2]->text
;
793 char *rmap
= argv
[4]->arg
;
796 if (strcasecmp(proto
, "any") == 0)
799 i
= proto_name2num(proto
);
801 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
802 return CMD_WARNING_CONFIG_FAILED
;
804 if (nht_rm
[AFI_IP6
][i
])
805 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
806 nht_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
807 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
812 DEFUN (no_ipv6_protocol_nht_rmap
,
813 no_ipv6_protocol_nht_rmap_cmd
,
814 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
817 "Filter Next Hop tracking route resolution\n"
818 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
819 "Specify route map\n"
822 char *proto
= argv
[3]->text
;
823 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
826 if (strcasecmp(proto
, "any") == 0)
829 i
= proto_name2num(proto
);
831 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
832 return CMD_WARNING_CONFIG_FAILED
;
835 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
])) {
836 vty_out(vty
, "invalid route-map \"%s\"\n", rmap
);
837 return CMD_WARNING_CONFIG_FAILED
;
840 if (nht_rm
[AFI_IP6
][i
]) {
841 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
842 nht_rm
[AFI_IP6
][i
] = NULL
;
845 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
850 DEFUN (show_ipv6_protocol_nht
,
851 show_ipv6_protocol_nht_cmd
,
852 "show ipv6 nht route-map",
855 "Next Hop filtering status\n"
860 vty_out(vty
, "Protocol : route-map \n");
861 vty_out(vty
, "------------------------\n");
862 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
863 if (nht_rm
[AFI_IP6
][i
])
864 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
867 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
869 if (nht_rm
[AFI_IP
][i
])
870 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP6
][i
]);
872 vty_out(vty
, "%-10s : none\n", "any");
877 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
879 /* `match ip next-hop IP_ACCESS_LIST' */
881 /* Match function return 1 if match is success else return zero. */
882 static route_map_result_t
route_match_ip_next_hop(void *rule
,
883 const struct prefix
*prefix
,
884 route_map_object_t type
,
887 struct access_list
*alist
;
888 struct nh_rmap_obj
*nh_data
;
889 struct prefix_ipv4 p
;
891 if (type
== RMAP_ZEBRA
) {
894 return RMAP_DENYMATCH
;
896 switch (nh_data
->nexthop
->type
) {
897 case NEXTHOP_TYPE_IFINDEX
:
898 /* Interface routes can't match ip next-hop */
900 case NEXTHOP_TYPE_IPV4_IFINDEX
:
901 case NEXTHOP_TYPE_IPV4
:
903 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
904 p
.prefixlen
= IPV4_MAX_BITLEN
;
909 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
913 return (access_list_apply(alist
, &p
) == FILTER_DENY
920 /* Route map `ip next-hop' match statement. `arg' should be
922 static void *route_match_ip_next_hop_compile(const char *arg
)
924 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
927 /* Free route map's compiled `. */
928 static void route_match_ip_next_hop_free(void *rule
)
930 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
933 /* Route map commands for ip next-hop matching. */
934 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
935 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
936 route_match_ip_next_hop_free
};
938 /* `match ip next-hop prefix-list PREFIX_LIST' */
940 static route_map_result_t
941 route_match_ip_next_hop_prefix_list(void *rule
, const struct prefix
*prefix
,
942 route_map_object_t type
, void *object
)
944 struct prefix_list
*plist
;
945 struct nh_rmap_obj
*nh_data
;
946 struct prefix_ipv4 p
;
948 if (type
== RMAP_ZEBRA
) {
949 nh_data
= (struct nh_rmap_obj
*)object
;
951 return RMAP_DENYMATCH
;
953 switch (nh_data
->nexthop
->type
) {
954 case NEXTHOP_TYPE_IFINDEX
:
955 /* Interface routes can't match ip next-hop */
957 case NEXTHOP_TYPE_IPV4_IFINDEX
:
958 case NEXTHOP_TYPE_IPV4
:
960 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
961 p
.prefixlen
= IPV4_MAX_BITLEN
;
966 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
970 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
977 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
979 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
982 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
984 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
987 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
988 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
989 route_match_ip_next_hop_prefix_list_compile
,
990 route_match_ip_next_hop_prefix_list_free
};
992 /* `match ip address IP_ACCESS_LIST' */
994 /* Match function should return 1 if match is success else return
996 static route_map_result_t
route_match_ip_address(void *rule
,
997 const struct prefix
*prefix
,
998 route_map_object_t type
,
1001 struct access_list
*alist
;
1003 if (type
== RMAP_ZEBRA
) {
1004 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
1006 return RMAP_NOMATCH
;
1008 return (access_list_apply(alist
, prefix
) == FILTER_DENY
1012 return RMAP_NOMATCH
;
1015 /* Route map `ip address' match statement. `arg' should be
1016 access-list name. */
1017 static void *route_match_ip_address_compile(const char *arg
)
1019 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1022 /* Free route map's compiled `ip address' value. */
1023 static void route_match_ip_address_free(void *rule
)
1025 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1028 /* Route map commands for ip address matching. */
1029 static struct route_map_rule_cmd route_match_ip_address_cmd
= {
1030 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
1031 route_match_ip_address_free
};
1033 /* `match ip address prefix-list PREFIX_LIST' */
1035 static route_map_result_t
1036 route_match_address_prefix_list(void *rule
, const struct prefix
*prefix
,
1037 route_map_object_t type
, void *object
, afi_t afi
)
1039 struct prefix_list
*plist
;
1041 if (type
== RMAP_ZEBRA
) {
1042 plist
= prefix_list_lookup(afi
, (char *)rule
);
1044 return RMAP_NOMATCH
;
1046 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
1050 return RMAP_NOMATCH
;
1053 static route_map_result_t
1054 route_match_ip_address_prefix_list(void *rule
, const struct prefix
*prefix
,
1055 route_map_object_t type
, void *object
)
1057 return (route_match_address_prefix_list(rule
, prefix
, type
, object
,
1061 static void *route_match_address_prefix_list_compile(const char *arg
)
1063 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1066 static void route_match_address_prefix_list_free(void *rule
)
1068 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1071 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
1072 "ip address prefix-list", route_match_ip_address_prefix_list
,
1073 route_match_address_prefix_list_compile
,
1074 route_match_address_prefix_list_free
};
1076 static route_map_result_t
1077 route_match_ipv6_address_prefix_list(void *rule
, const struct prefix
*prefix
,
1078 route_map_object_t type
, void *object
)
1080 return (route_match_address_prefix_list(rule
, prefix
, type
, object
,
1084 static struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
= {
1085 "ipv6 address prefix-list", route_match_ipv6_address_prefix_list
,
1086 route_match_address_prefix_list_compile
,
1087 route_match_address_prefix_list_free
};
1089 /* `match ip address prefix-len PREFIXLEN' */
1091 static route_map_result_t
1092 route_match_address_prefix_len(void *rule
, const struct prefix
*prefix
,
1093 route_map_object_t type
, void *object
)
1095 uint32_t *prefixlen
= (uint32_t *)rule
;
1097 if (type
== RMAP_ZEBRA
) {
1098 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1101 return RMAP_NOMATCH
;
1104 static void *route_match_address_prefix_len_compile(const char *arg
)
1106 uint32_t *prefix_len
;
1107 char *endptr
= NULL
;
1108 unsigned long tmpval
;
1110 /* prefix len value shoud be integer. */
1111 if (!all_digit(arg
))
1115 tmpval
= strtoul(arg
, &endptr
, 10);
1116 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1119 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1121 *prefix_len
= tmpval
;
1125 static void route_match_address_prefix_len_free(void *rule
)
1127 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1130 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
= {
1131 "ip address prefix-len", route_match_address_prefix_len
,
1132 route_match_address_prefix_len_compile
,
1133 route_match_address_prefix_len_free
};
1135 static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd
= {
1136 "ipv6 address prefix-len", route_match_address_prefix_len
,
1137 route_match_address_prefix_len_compile
,
1138 route_match_address_prefix_len_free
};
1140 /* `match ip nexthop prefix-len PREFIXLEN' */
1142 static route_map_result_t
1143 route_match_ip_nexthop_prefix_len(void *rule
, const struct prefix
*prefix
,
1144 route_map_object_t type
, void *object
)
1146 uint32_t *prefixlen
= (uint32_t *)rule
;
1147 struct nh_rmap_obj
*nh_data
;
1148 struct prefix_ipv4 p
;
1150 if (type
== RMAP_ZEBRA
) {
1151 nh_data
= (struct nh_rmap_obj
*)object
;
1152 if (!nh_data
|| !nh_data
->nexthop
)
1153 return RMAP_DENYMATCH
;
1155 switch (nh_data
->nexthop
->type
) {
1156 case NEXTHOP_TYPE_IFINDEX
:
1157 /* Interface routes can't match ip next-hop */
1158 return RMAP_NOMATCH
;
1159 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1160 case NEXTHOP_TYPE_IPV4
:
1162 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1163 p
.prefixlen
= IPV4_MAX_BITLEN
;
1166 return RMAP_NOMATCH
;
1168 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1171 return RMAP_NOMATCH
;
1174 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
= {
1175 "ip next-hop prefix-len", route_match_ip_nexthop_prefix_len
,
1176 route_match_address_prefix_len_compile
, /* reuse */
1177 route_match_address_prefix_len_free
/* reuse */
1180 /* `match source-protocol PROTOCOL' */
1182 static route_map_result_t
route_match_source_protocol(void *rule
,
1183 const struct prefix
*p
,
1184 route_map_object_t type
,
1187 uint32_t *rib_type
= (uint32_t *)rule
;
1188 struct nh_rmap_obj
*nh_data
;
1190 if (type
== RMAP_ZEBRA
) {
1191 nh_data
= (struct nh_rmap_obj
*)object
;
1193 return RMAP_DENYMATCH
;
1195 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1198 return RMAP_NOMATCH
;
1201 static void *route_match_source_protocol_compile(const char *arg
)
1206 i
= proto_name2num(arg
);
1207 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1214 static void route_match_source_protocol_free(void *rule
)
1216 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1219 static struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1220 "source-protocol", route_match_source_protocol
,
1221 route_match_source_protocol_compile
, route_match_source_protocol_free
};
1223 /* `source-instance` */
1224 static route_map_result_t
route_match_source_instance(void *rule
,
1225 const struct prefix
*p
,
1226 route_map_object_t type
,
1229 uint8_t *instance
= (uint8_t *)rule
;
1230 struct nh_rmap_obj
*nh_data
;
1232 if (type
!= RMAP_ZEBRA
)
1233 return RMAP_NOMATCH
;
1235 nh_data
= (struct nh_rmap_obj
*)object
;
1237 return RMAP_DENYMATCH
;
1239 return (nh_data
->instance
== *instance
) ? RMAP_MATCH
: RMAP_NOMATCH
;
1242 static void *route_match_source_instance_compile(const char *arg
)
1248 instance
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1255 static void route_match_source_instance_free(void *rule
)
1257 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1260 static struct route_map_rule_cmd route_match_source_instance_cmd
= {
1261 "source-instance", route_match_source_instance
,
1262 route_match_source_instance_compile
, route_match_source_instance_free
};
1264 /* `set src A.B.C.D' */
1267 static route_map_result_t
route_set_src(void *rule
, const struct prefix
*prefix
,
1268 route_map_object_t type
, void *object
)
1270 struct nh_rmap_obj
*nh_data
;
1272 if (type
== RMAP_ZEBRA
) {
1273 nh_data
= (struct nh_rmap_obj
*)object
;
1274 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1279 /* set src compilation. */
1280 static void *route_set_src_compile(const char *arg
)
1282 union g_addr src
, *psrc
;
1284 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1285 || (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)) {
1286 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1293 /* Free route map's compiled `set src' value. */
1294 static void route_set_src_free(void *rule
)
1296 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1299 /* Set src rule structure. */
1300 static struct route_map_rule_cmd route_set_src_cmd
= {
1301 "src", route_set_src
, route_set_src_compile
, route_set_src_free
,
1304 /* The function checks if the changed routemap specified by parameter rmap
1305 * matches the configured protocol routemaps in proto_rm table. If there is
1306 * a match then rib_update_table() to process the routes.
1308 static void zebra_rib_table_rm_update(const char *rmap
)
1311 struct route_table
*table
;
1312 struct vrf
*vrf
= NULL
;
1313 struct zebra_vrf
*zvrf
= NULL
;
1318 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1322 for (i
= 0; i
<= ZEBRA_ROUTE_MAX
; i
++) {
1323 rmap_name
= PROTO_RM_NAME(zvrf
, AFI_IP
, i
);
1324 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1325 if (IS_ZEBRA_DEBUG_EVENT
)
1327 "%s : AFI_IP rmap %s, route type %s",
1329 zebra_route_string(i
));
1331 PROTO_RM_MAP(zvrf
, AFI_IP
, i
) =
1332 route_map_lookup_by_name(rmap_name
);
1333 /* There is single rib table for all protocols
1336 table
= zvrf
->table
[AFI_IP
]
1343 RIB_UPDATE_RMAP_CHANGE
);
1347 rmap_name
= PROTO_RM_NAME(zvrf
, AFI_IP6
, i
);
1348 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1349 if (IS_ZEBRA_DEBUG_EVENT
)
1351 "%s : AFI_IP6 rmap %s, route type %s",
1353 zebra_route_string(i
));
1355 PROTO_RM_MAP(zvrf
, AFI_IP6
, i
) =
1356 route_map_lookup_by_name(rmap_name
);
1357 /* There is single rib table for all protocols
1359 if (afi_ipv6
== 0) {
1360 table
= zvrf
->table
[AFI_IP6
]
1367 RIB_UPDATE_RMAP_CHANGE
);
1375 /* The function checks if the changed routemap specified by parameter rmap
1376 * matches the configured protocol routemaps in nht_rm table. If there is
1377 * a match then zebra_evaluate_rnh() to process the nexthops.
1379 static void zebra_nht_rm_update(const char *rmap
)
1382 struct route_table
*table
;
1383 struct vrf
*vrf
= NULL
;
1384 struct zebra_vrf
*zvrf
= NULL
;
1389 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1393 for (i
= 0; i
<= ZEBRA_ROUTE_MAX
; i
++) {
1394 rmap_name
= NHT_RM_NAME(zvrf
, AFI_IP
, i
);
1395 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1396 if (IS_ZEBRA_DEBUG_EVENT
)
1398 "%s : AFI_IP rmap %s, route type %s",
1400 zebra_route_string(i
));
1402 NHT_RM_MAP(zvrf
, AFI_IP
, i
) =
1403 route_map_lookup_by_name(rmap_name
);
1404 /* There is single rib table for all protocols
1407 table
= zvrf
->table
[AFI_IP
]
1416 RNH_NEXTHOP_TYPE
, NULL
);
1421 rmap_name
= NHT_RM_NAME(zvrf
, AFI_IP6
, i
);
1422 if (rmap_name
&& (strcmp(rmap_name
, rmap
) == 0)) {
1423 if (IS_ZEBRA_DEBUG_EVENT
)
1425 "%s : AFI_IP6 rmap %s, route type %s",
1427 zebra_route_string(i
));
1429 NHT_RM_MAP(zvrf
, AFI_IP6
, i
) =
1430 route_map_lookup_by_name(rmap_name
);
1431 /* There is single rib table for all protocols
1433 if (afi_ipv6
== 0) {
1434 table
= zvrf
->table
[AFI_IP6
]
1443 RNH_NEXTHOP_TYPE
, NULL
);
1451 static void zebra_route_map_process_update_cb(char *rmap_name
)
1453 if (IS_ZEBRA_DEBUG_EVENT
)
1454 zlog_debug("Event handler for route-map: %s",
1456 zebra_import_table_rm_update(rmap_name
);
1457 zebra_rib_table_rm_update(rmap_name
);
1458 zebra_nht_rm_update(rmap_name
);
1461 static int zebra_route_map_update_timer(struct thread
*thread
)
1463 zebra_t_rmap_update
= NULL
;
1465 if (IS_ZEBRA_DEBUG_EVENT
)
1466 zlog_debug("Event driven route-map update triggered");
1468 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1470 "%u: Routemap update-timer fired, scheduling RIB processing",
1473 route_map_walk_update_list(zebra_route_map_process_update_cb
);
1476 * This code needs to be updated to be:
1477 * 1) VRF Aware <sigh>
1478 * 2) Route-map aware
1483 static void zebra_route_map_set_delay_timer(uint32_t value
)
1485 zebra_rmap_update_timer
= value
;
1486 if (!value
&& zebra_t_rmap_update
) {
1487 /* Event driven route map updates is being disabled */
1488 /* But there's a pending timer. Fire it off now */
1489 thread_cancel(zebra_t_rmap_update
);
1490 zebra_route_map_update_timer(zebra_t_rmap_update
);
1494 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1496 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1497 vty_out(vty
, "zebra route-map delay-timer %d\n",
1498 zebra_rmap_update_timer
);
1503 zebra_route_map_check(int family
, int rib_type
, uint8_t instance
,
1504 const struct prefix
*p
, struct nexthop
*nexthop
,
1505 struct zebra_vrf
*zvrf
, route_tag_t tag
)
1507 struct route_map
*rmap
= NULL
;
1508 route_map_result_t ret
= RMAP_MATCH
;
1509 struct nh_rmap_obj nh_obj
;
1511 nh_obj
.nexthop
= nexthop
;
1512 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1513 nh_obj
.source_protocol
= rib_type
;
1514 nh_obj
.instance
= instance
;
1518 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1519 rmap
= PROTO_RM_MAP(zvrf
, family
, rib_type
);
1520 if (!rmap
&& PROTO_RM_NAME(zvrf
, family
, ZEBRA_ROUTE_MAX
))
1521 rmap
= PROTO_RM_MAP(zvrf
, family
, ZEBRA_ROUTE_MAX
);
1523 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1529 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1531 return zebra_import_table_routemap
[afi
][table
];
1534 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1537 zebra_import_table_routemap
[afi
][table
] =
1538 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1541 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1543 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1547 zebra_import_table_route_map_check(int family
, int re_type
, uint8_t instance
,
1548 const struct prefix
*p
,
1549 struct nexthop
*nexthop
,
1550 vrf_id_t vrf_id
, route_tag_t tag
,
1551 const char *rmap_name
)
1553 struct route_map
*rmap
= NULL
;
1554 route_map_result_t ret
= RMAP_DENYMATCH
;
1555 struct nh_rmap_obj nh_obj
;
1557 nh_obj
.nexthop
= nexthop
;
1558 nh_obj
.vrf_id
= vrf_id
;
1559 nh_obj
.source_protocol
= re_type
;
1560 nh_obj
.instance
= instance
;
1564 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1565 rmap
= route_map_lookup_by_name(rmap_name
);
1567 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1573 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1574 const struct prefix
*p
,
1575 struct zebra_vrf
*zvrf
,
1576 struct route_entry
*re
,
1577 struct nexthop
*nexthop
)
1579 struct route_map
*rmap
= NULL
;
1580 route_map_result_t ret
= RMAP_MATCH
;
1581 struct nh_rmap_obj nh_obj
;
1583 nh_obj
.nexthop
= nexthop
;
1584 nh_obj
.vrf_id
= nexthop
->vrf_id
;
1585 nh_obj
.source_protocol
= re
->type
;
1586 nh_obj
.instance
= re
->instance
;
1587 nh_obj
.metric
= re
->metric
;
1588 nh_obj
.tag
= re
->tag
;
1590 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1591 rmap
= NHT_RM_MAP(zvrf
, family
, client_proto
);
1592 if (!rmap
&& NHT_RM_MAP(zvrf
, family
, ZEBRA_ROUTE_MAX
))
1593 rmap
= NHT_RM_MAP(zvrf
, family
, ZEBRA_ROUTE_MAX
);
1595 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1600 static void zebra_route_map_mark_update(const char *rmap_name
)
1602 /* rmap_update_timer of 0 means don't do route updates */
1603 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1604 zebra_t_rmap_update
= NULL
;
1605 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1606 NULL
, zebra_rmap_update_timer
,
1607 &zebra_t_rmap_update
);
1611 static void zebra_route_map_add(const char *rmap_name
)
1613 if (route_map_mark_updated(rmap_name
) == 0)
1614 zebra_route_map_mark_update(rmap_name
);
1616 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1619 static void zebra_route_map_delete(const char *rmap_name
)
1621 if (route_map_mark_updated(rmap_name
) == 0)
1622 zebra_route_map_mark_update(rmap_name
);
1624 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1627 static void zebra_route_map_event(route_map_event_t event
,
1628 const char *rmap_name
)
1630 if (route_map_mark_updated(rmap_name
) == 0)
1631 zebra_route_map_mark_update(rmap_name
);
1633 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1636 /* ip protocol configuration write function */
1637 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1641 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1642 if (proto_rm
[AFI_IP
][i
])
1643 vty_out(vty
, "ip protocol %s route-map %s\n",
1644 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1646 if (proto_rm
[AFI_IP6
][i
])
1647 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1648 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1650 if (nht_rm
[AFI_IP
][i
])
1651 vty_out(vty
, "ip nht %s route-map %s\n",
1652 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1654 if (nht_rm
[AFI_IP6
][i
])
1655 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1656 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1659 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1660 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1661 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1663 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1664 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1665 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1667 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1668 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1669 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1671 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1672 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1673 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1675 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1676 vty_out(vty
, "zebra route-map delay-timer %d\n",
1677 zebra_rmap_update_timer
);
1680 void zebra_route_map_init()
1682 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1683 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1684 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1685 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1686 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1687 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1688 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1689 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1690 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1691 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1692 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1693 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1694 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1695 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1699 route_map_add_hook(zebra_route_map_add
);
1700 route_map_delete_hook(zebra_route_map_delete
);
1701 route_map_event_hook(zebra_route_map_event
);
1703 route_map_match_interface_hook(generic_match_add
);
1704 route_map_no_match_interface_hook(generic_match_delete
);
1706 route_map_match_ip_address_hook(generic_match_add
);
1707 route_map_no_match_ip_address_hook(generic_match_delete
);
1709 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1710 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1712 route_map_match_ip_next_hop_hook(generic_match_add
);
1713 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1715 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1716 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1718 route_map_match_tag_hook(generic_match_add
);
1719 route_map_no_match_tag_hook(generic_match_delete
);
1721 route_map_match_ipv6_address_hook(generic_match_add
);
1722 route_map_no_match_ipv6_address_hook(generic_match_delete
);
1724 route_map_match_ipv6_address_prefix_list_hook(generic_match_add
);
1725 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete
);
1727 route_map_install_match(&route_match_tag_cmd
);
1728 route_map_install_match(&route_match_interface_cmd
);
1729 route_map_install_match(&route_match_ip_next_hop_cmd
);
1730 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1731 route_map_install_match(&route_match_ip_address_cmd
);
1732 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1733 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd
);
1734 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1735 route_map_install_match(&route_match_ipv6_address_prefix_len_cmd
);
1736 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1737 route_map_install_match(&route_match_source_protocol_cmd
);
1738 route_map_install_match(&route_match_source_instance_cmd
);
1741 route_map_install_set(&route_set_src_cmd
);
1743 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1744 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1745 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1746 install_element(RMAP_NODE
, &match_ipv6_address_prefix_len_cmd
);
1747 install_element(RMAP_NODE
, &no_match_ipv6_address_prefix_len_cmd
);
1748 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1749 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1750 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1751 install_element(RMAP_NODE
, &match_source_instance_cmd
);
1752 install_element(RMAP_NODE
, &no_match_source_instance_cmd
);
1755 install_element(RMAP_NODE
, &set_src_cmd
);
1756 install_element(RMAP_NODE
, &no_set_src_cmd
);