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
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 #include "zebra_memory.h"
35 #include "zebra/zserv.h"
36 #include "zebra/redistribute.h"
37 #include "zebra/debug.h"
38 #include "zebra/zebra_rnh.h"
39 #include "zebra/zebra_routemap.h"
41 static u_int32_t zebra_rmap_update_timer
= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
;
42 static struct thread
*zebra_t_rmap_update
= NULL
;
43 char *proto_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+1]; /* "any" == ZEBRA_ROUTE_MAX */
44 /* NH Tracking route map */
45 char *nht_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+1]; /* "any" == ZEBRA_ROUTE_MAX */
46 char *zebra_import_table_routemap
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
50 struct nexthop
*nexthop
;
52 u_int32_t source_protocol
;
57 static void zebra_route_map_set_delay_timer(u_int32_t value
);
59 /* Add zebra route map rule */
61 zebra_route_match_add(struct vty
*vty
,
62 const char *command
, const char *arg
,
63 route_map_event_t type
)
65 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
68 ret
= route_map_add_match (index
, command
, arg
);
73 case RMAP_RULE_MISSING
:
74 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
76 case RMAP_COMPILE_ERROR
:
77 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
82 if (type
!= RMAP_EVENT_MATCH_ADDED
)
84 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
89 /* Delete zebra route map rule. */
91 zebra_route_match_delete (struct vty
*vty
,
92 const char *command
, const char *arg
,
93 route_map_event_t type
)
95 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
97 char *dep_name
= NULL
;
99 char *rmap_name
= NULL
;
101 if (type
!= RMAP_EVENT_MATCH_DELETED
)
103 /* ignore the mundane, the types without any dependency */
106 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
107 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
111 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
113 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
116 ret
= route_map_delete_match (index
, command
, arg
);
121 case RMAP_RULE_MISSING
:
122 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
124 case RMAP_COMPILE_ERROR
:
125 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
130 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
131 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
134 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
136 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
141 /* Add zebra route map rule. */
143 zebra_route_set_add (struct vty
*vty
,
144 const char *command
, const char *arg
)
146 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
149 ret
= route_map_add_set (index
, command
, arg
);
154 case RMAP_RULE_MISSING
:
155 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
157 case RMAP_COMPILE_ERROR
:
158 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
165 /* Delete zebra route map rule. */
167 zebra_route_set_delete (struct vty
*vty
,
168 const char *command
, const char *arg
)
170 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
173 ret
= route_map_delete_set (index
, command
, arg
);
178 case RMAP_RULE_MISSING
:
179 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
181 case RMAP_COMPILE_ERROR
:
182 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
190 * Match function return 1 if match is success else return 0
192 static route_map_result_t
193 route_match_tag (void *rule
, struct prefix
*prefix
,
194 route_map_object_t type
, void *object
)
197 struct nh_rmap_obj
*nh_data
;
199 if (type
== RMAP_ZEBRA
)
204 if (nh_data
->tag
== *tag
)
210 /* Route map commands for tag matching */
211 static struct route_map_rule_cmd route_match_tag_cmd
=
215 route_map_rule_tag_compile
,
216 route_map_rule_tag_free
,
220 /* `match interface IFNAME' */
221 /* Match function return 1 if match is success else return zero. */
222 static route_map_result_t
223 route_match_interface (void *rule
, struct prefix
*prefix
,
224 route_map_object_t type
, void *object
)
226 struct nh_rmap_obj
*nh_data
;
230 if (type
== RMAP_ZEBRA
)
232 if (strcasecmp(ifname
, "any") == 0)
235 if (!nh_data
|| !nh_data
->nexthop
)
237 ifindex
= ifname2ifindex_vrf (ifname
, nh_data
->vrf_id
);
240 if (nh_data
->nexthop
->ifindex
== ifindex
)
246 /* Route map `match interface' match statement. `arg' is IFNAME value */
248 route_match_interface_compile (const char *arg
)
250 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
253 /* Free route map's compiled `match interface' value. */
255 route_match_interface_free (void *rule
)
257 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
260 /* Route map commands for interface matching */
261 struct route_map_rule_cmd route_match_interface_cmd
=
264 route_match_interface
,
265 route_match_interface_compile
,
266 route_match_interface_free
269 DEFUN (match_interface
,
271 "match interface WORD",
273 "match first hop interface of route\n"
276 return zebra_route_match_add (vty
, "interface", argv
[0],
277 RMAP_EVENT_MATCH_ADDED
);
280 DEFUN (no_match_interface
,
281 no_match_interface_cmd
,
282 "no match interface",
285 "Match first hop interface of route\n")
288 return zebra_route_match_delete (vty
, "interface", NULL
, RMAP_EVENT_MATCH_DELETED
);
290 return zebra_route_match_delete (vty
, "interface", argv
[0], RMAP_EVENT_MATCH_DELETED
);
293 ALIAS (no_match_interface
,
294 no_match_interface_val_cmd
,
295 "no match interface WORD",
298 "Match first hop interface of route\n"
303 "match tag <1-4294967295>",
305 "Match tag of route\n"
308 return zebra_route_match_add (vty
, "tag", argv
[0],
309 RMAP_EVENT_MATCH_ADDED
);
317 "Match tag of route\n")
320 return zebra_route_match_delete (vty
, "tag", NULL
,
321 RMAP_EVENT_MATCH_DELETED
);
323 return zebra_route_match_delete (vty
, "tag", argv
[0],
324 RMAP_EVENT_MATCH_DELETED
);
328 no_match_tag_val_cmd
,
329 "no match tag <1-4294967295>",
332 "Match tag of route\n")
334 DEFUN (match_ip_next_hop
,
335 match_ip_next_hop_cmd
,
336 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
339 "Match next-hop address of route\n"
340 "IP access-list number\n"
341 "IP access-list number (expanded range)\n"
342 "IP Access-list name\n")
344 return zebra_route_match_add (vty
, "ip next-hop", argv
[0], RMAP_EVENT_FILTER_ADDED
);
347 DEFUN (no_match_ip_next_hop
,
348 no_match_ip_next_hop_cmd
,
349 "no match ip next-hop",
353 "Match next-hop address of route\n")
356 return zebra_route_match_delete (vty
, "ip next-hop", NULL
,
357 RMAP_EVENT_FILTER_DELETED
);
359 return zebra_route_match_delete (vty
, "ip next-hop", argv
[0],
360 RMAP_EVENT_FILTER_DELETED
);
363 ALIAS (no_match_ip_next_hop
,
364 no_match_ip_next_hop_val_cmd
,
365 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
369 "Match next-hop address of route\n"
370 "IP access-list number\n"
371 "IP access-list number (expanded range)\n"
372 "IP Access-list name\n")
374 DEFUN (match_ip_next_hop_prefix_list
,
375 match_ip_next_hop_prefix_list_cmd
,
376 "match ip next-hop prefix-list WORD",
379 "Match next-hop address of route\n"
380 "Match entries of prefix-lists\n"
381 "IP prefix-list name\n")
383 return zebra_route_match_add (vty
, "ip next-hop prefix-list",
384 argv
[0], RMAP_EVENT_PLIST_ADDED
);
387 DEFUN (no_match_ip_next_hop_prefix_list
,
388 no_match_ip_next_hop_prefix_list_cmd
,
389 "no match ip next-hop prefix-list",
393 "Match next-hop address of route\n"
394 "Match entries of prefix-lists\n")
397 return zebra_route_match_delete (vty
,
398 "ip next-hop prefix-list", NULL
,
399 RMAP_EVENT_PLIST_DELETED
);
401 return zebra_route_match_delete (vty
,
402 "ip next-hop prefix-list", argv
[0],
403 RMAP_EVENT_PLIST_DELETED
);
406 ALIAS (no_match_ip_next_hop_prefix_list
,
407 no_match_ip_next_hop_prefix_list_val_cmd
,
408 "no match ip next-hop prefix-list WORD",
412 "Match next-hop address of route\n"
413 "Match entries of prefix-lists\n"
414 "IP prefix-list name\n")
416 DEFUN (match_ip_address
,
417 match_ip_address_cmd
,
418 "match ip address (<1-199>|<1300-2699>|WORD)",
421 "Match address of route\n"
422 "IP access-list number\n"
423 "IP access-list number (expanded range)\n"
424 "IP Access-list name\n")
427 return zebra_route_match_add (vty
, "ip address", argv
[0],
428 RMAP_EVENT_FILTER_ADDED
);
431 DEFUN (no_match_ip_address
,
432 no_match_ip_address_cmd
,
433 "no match ip address",
437 "Match address of route\n")
440 return zebra_route_match_delete (vty
, "ip address", NULL
,
441 RMAP_EVENT_FILTER_DELETED
);
443 return zebra_route_match_delete (vty
, "ip address", argv
[0],
444 RMAP_EVENT_FILTER_DELETED
);
447 ALIAS (no_match_ip_address
,
448 no_match_ip_address_val_cmd
,
449 "no match ip address (<1-199>|<1300-2699>|WORD)",
453 "Match address of route\n"
454 "IP access-list number\n"
455 "IP access-list number (expanded range)\n"
456 "IP Access-list name\n")
458 DEFUN (match_ip_address_prefix_list
,
459 match_ip_address_prefix_list_cmd
,
460 "match ip address prefix-list WORD",
463 "Match address of route\n"
464 "Match entries of prefix-lists\n"
465 "IP prefix-list name\n")
467 return zebra_route_match_add (vty
, "ip address prefix-list",
468 argv
[0], RMAP_EVENT_PLIST_ADDED
);
471 DEFUN (no_match_ip_address_prefix_list
,
472 no_match_ip_address_prefix_list_cmd
,
473 "no match ip address prefix-list",
477 "Match address of route\n"
478 "Match entries of prefix-lists\n")
481 return zebra_route_match_delete (vty
,
482 "ip address prefix-list", NULL
,
483 RMAP_EVENT_PLIST_DELETED
);
485 return zebra_route_match_delete (vty
,
486 "ip address prefix-list", argv
[0],
487 RMAP_EVENT_PLIST_DELETED
);
490 ALIAS (no_match_ip_address_prefix_list
,
491 no_match_ip_address_prefix_list_val_cmd
,
492 "no match ip address prefix-list WORD",
496 "Match address of route\n"
497 "Match entries of prefix-lists\n"
498 "IP prefix-list name\n")
500 DEFUN (match_ip_address_prefix_len
,
501 match_ip_address_prefix_len_cmd
,
502 "match ip address prefix-len NUMBER",
505 "Match prefix length of ip address\n"
506 "Match prefix length of ip address\n"
509 return zebra_route_match_add (vty
, "ip address prefix-len",
510 argv
[0], RMAP_EVENT_MATCH_ADDED
);
513 DEFUN (no_match_ip_address_prefix_len
,
514 no_match_ip_address_prefix_len_cmd
,
515 "no match ip address prefix-len",
519 "Match prefixlen of ip address of route\n"
520 "prefix length of ip address\n")
523 return zebra_route_match_delete (vty
,
524 "ip address prefix-len", NULL
,
525 RMAP_EVENT_MATCH_DELETED
);
527 return zebra_route_match_delete (vty
,
528 "ip address prefix-len", argv
[0],
529 RMAP_EVENT_MATCH_DELETED
);
532 ALIAS (no_match_ip_address_prefix_len
,
533 no_match_ip_address_prefix_len_val_cmd
,
534 "no match ip address prefix-len NUMBER",
538 "Match prefixlen of ip address of route\n"
539 "prefix length of ip address\n")
541 DEFUN (match_ip_nexthop_prefix_len
,
542 match_ip_nexthop_prefix_len_cmd
,
543 "match ip next-hop prefix-len NUMBER",
546 "Match prefixlen of nexthop ip address\n"
547 "Match prefixlen of given nexthop\n"
550 return zebra_route_match_add (vty
, "ip next-hop prefix-len",
551 argv
[0], RMAP_EVENT_MATCH_ADDED
);
554 DEFUN (no_match_ip_nexthop_prefix_len
,
555 no_match_ip_nexthop_prefix_len_cmd
,
556 "no match ip next-hop prefix-len",
560 "Match prefixlen of nexthop ip address\n"
561 "Match prefix length of nexthop\n")
564 return zebra_route_match_delete (vty
,
565 "ip next-hop prefix-len", NULL
,
566 RMAP_EVENT_MATCH_DELETED
);
568 return zebra_route_match_delete (vty
,
569 "ip next-hop prefix-len", argv
[0],
570 RMAP_EVENT_MATCH_DELETED
);
573 ALIAS (no_match_ip_nexthop_prefix_len
,
574 no_match_ip_nexthop_prefix_len_val_cmd
,
575 "no match ip next-hop prefix-len NUMBER",
577 "Match prefixlen of ip address of route\n"
578 "prefix length of ip address\n")
580 DEFUN (match_source_protocol
,
581 match_source_protocol_cmd
,
582 "match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
584 "Match protocol via which the route was learnt\n")
588 i
= proto_name2num(argv
[0]);
591 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
595 return zebra_route_match_add (vty
, "source-protocol",
596 argv
[0], RMAP_EVENT_MATCH_ADDED
);
599 DEFUN (no_match_source_protocol
,
600 no_match_source_protocol_cmd
,
601 "no match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
604 "No match protocol via which the route was learnt\n")
610 i
= proto_name2num(argv
[0]);
613 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
618 return zebra_route_match_delete (vty
,
619 "source-protocol", argv
[0] ? argv
[0] : NULL
,
620 RMAP_EVENT_MATCH_DELETED
);
627 "set src (A.B.C.D|X:X::X:X)",
629 "src address for route\n"
633 struct interface
*pif
= NULL
;
638 if (inet_pton(AF_INET
, argv
[0], &src
.ipv4
) != 1)
640 if (inet_pton(AF_INET6
, argv
[0], &src
.ipv6
) != 1)
642 vty_out (vty
, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE
);
646 p
.family
= family
= AF_INET6
;
647 p
.u
.prefix6
= src
.ipv6
;
648 p
.prefixlen
= IPV6_MAX_BITLEN
;
652 p
.family
= family
= AF_INET
;
653 p
.u
.prefix4
= src
.ipv4
;
654 p
.prefixlen
= IPV4_MAX_BITLEN
;
657 if (!zebra_check_addr(&p
))
659 vty_out (vty
, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE
);
663 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
665 if (family
== AF_INET
)
666 pif
= if_lookup_exact_address_vrf ((void *)&src
.ipv4
, AF_INET
,
668 else if (family
== AF_INET6
)
669 pif
= if_lookup_exact_address_vrf ((void *)&src
.ipv6
, AF_INET6
,
678 vty_out (vty
, "%% not a local address%s", VTY_NEWLINE
);
681 return zebra_route_set_add (vty
, "src", argv
[0]);
686 "no set src {A.B.C.D|X:X::X:X}",
689 "Source address for route\n")
692 return zebra_route_set_delete (vty
, "src", NULL
);
694 return zebra_route_set_delete (vty
, "src", argv
[0]);
697 DEFUN (zebra_route_map_timer
,
698 zebra_route_map_timer_cmd
,
699 "zebra route-map delay-timer <0-600>",
700 "Time to wait before route-map updates are processed\n"
701 "0 means event-driven updates are disabled\n")
703 u_int32_t rmap_delay_timer
;
705 VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer
, argv
[0], 0, 600);
706 zebra_route_map_set_delay_timer(rmap_delay_timer
);
708 return (CMD_SUCCESS
);
711 DEFUN (no_zebra_route_map_timer
,
712 no_zebra_route_map_timer_cmd
,
713 "no zebra route-map delay-timer",
715 "Time to wait before route-map updates are processed\n"
716 "Reset delay-timer to default value, 30 secs\n")
718 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
720 return (CMD_SUCCESS
);
723 ALIAS (no_zebra_route_map_timer
,
724 no_zebra_route_map_timer_val_cmd
,
725 "no zebra route-map delay-timer <0-600>",
727 "Time to wait before route-map updates are processed\n"
728 "Reset delay-timer to default value, 30 secs\n"
729 "0 means event-driven updates are disabled\n")
733 "ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
735 "Filter routing info exchanged between zebra and protocol\n"
736 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
741 if (strcasecmp(argv
[0], "any") == 0)
744 i
= proto_name2num(argv
[0]);
747 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
751 if (proto_rm
[AFI_IP
][i
])
753 if (strcmp(proto_rm
[AFI_IP
][i
], argv
[1]) == 0)
756 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
758 proto_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
760 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
761 zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
762 VRF_DEFAULT
, argv
[0]);
764 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
768 DEFUN (no_ip_protocol
,
770 "no ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
,
773 "Stop filtering routing info between zebra and protocol\n"
774 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
775 "Protocol from which to stop filtering routes\n")
779 if (strcasecmp(argv
[0], "any") == 0)
782 i
= proto_name2num(argv
[0]);
785 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
789 if (!proto_rm
[AFI_IP
][i
])
792 if ((argc
== 2 && strcmp(argv
[1], proto_rm
[AFI_IP
][i
]) == 0) ||
795 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
796 proto_rm
[AFI_IP
][i
] = NULL
;
798 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
799 zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
800 VRF_DEFAULT
, argv
[0]);
801 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
806 ALIAS (no_ip_protocol
,
807 no_ip_protocol_val_cmd
,
808 "no ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
811 "Stop filtering routing info between zebra and protocol\n"
812 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
815 DEFUN (show_ip_protocol
,
816 show_ip_protocol_cmd
,
820 "IP protocol filtering status\n")
824 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
825 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
826 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
828 if (proto_rm
[AFI_IP
][i
])
829 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
833 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
835 if (proto_rm
[AFI_IP
][i
])
836 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP
][i
],
839 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
844 DEFUN (ipv6_protocol
,
846 "ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
848 "Filter IPv6 routing info exchanged between zebra and protocol\n"
849 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
854 if (strcasecmp(argv
[0], "any") == 0)
857 i
= proto_name2num(argv
[0]);
860 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
864 if (proto_rm
[AFI_IP6
][i
])
866 if (strcmp(proto_rm
[AFI_IP6
][i
], argv
[1]) == 0)
869 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
871 proto_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
873 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
874 zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
875 VRF_DEFAULT
, argv
[0]);
877 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
881 DEFUN (no_ipv6_protocol
,
882 no_ipv6_protocol_cmd
,
883 "no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
,
886 "Stop filtering IPv6 routing info between zebra and protocol\n"
887 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
888 "Protocol from which to stop filtering routes\n")
892 if (strcasecmp(argv
[0], "any") == 0)
895 i
= proto_name2num(argv
[0]);
898 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
902 if (!proto_rm
[AFI_IP6
][i
])
905 if ((argc
== 2 && strcmp(argv
[1], proto_rm
[AFI_IP6
][i
]) == 0) ||
908 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
909 proto_rm
[AFI_IP6
][i
] = NULL
;
911 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
912 zlog_debug ("%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
913 VRF_DEFAULT
, argv
[0]);
915 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
920 ALIAS (no_ipv6_protocol
,
921 no_ipv6_protocol_val_cmd
,
922 "no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
925 "Stop filtering IPv6 routing info between zebra and protocol\n"
926 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
929 DEFUN (show_ipv6_protocol
,
930 show_ipv6_protocol_cmd
,
931 "show ipv6 protocol",
934 "IPv6 protocol filtering status\n")
938 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
939 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
940 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
942 if (proto_rm
[AFI_IP6
][i
])
943 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
944 proto_rm
[AFI_IP6
][i
],
947 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
949 if (proto_rm
[AFI_IP6
][i
])
950 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP6
][i
],
953 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
958 DEFUN (ip_protocol_nht_rmap
,
959 ip_protocol_nht_rmap_cmd
,
960 "ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
962 "Filter Next Hop tracking route resolution\n"
963 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
968 if (strcasecmp(argv
[0], "any") == 0)
971 i
= proto_name2num(argv
[0]);
974 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
978 if (nht_rm
[AFI_IP
][i
])
980 if (strcmp(nht_rm
[AFI_IP
][i
], argv
[1]) == 0)
983 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
986 nht_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
987 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
992 DEFUN (no_ip_protocol_nht_rmap
,
993 no_ip_protocol_nht_rmap_cmd
,
994 "no ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
,
997 "Filter Next Hop tracking route resolution\n"
998 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
)
1002 if (strcasecmp(argv
[0], "any") == 0)
1003 i
= ZEBRA_ROUTE_MAX
;
1005 i
= proto_name2num(argv
[0]);
1008 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1012 if (!nht_rm
[AFI_IP
][i
])
1015 if ((argc
== 2 && strcmp(argv
[1], nht_rm
[AFI_IP
][i
]) == 0) ||
1018 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
1019 nht_rm
[AFI_IP
][i
] = NULL
;
1020 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1025 ALIAS (no_ip_protocol_nht_rmap
,
1026 no_ip_protocol_nht_rmap_val_cmd
,
1027 "no ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
1029 "Filter Next Hop tracking route resolution\n"
1030 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
1033 DEFUN (show_ip_protocol_nht
,
1034 show_ip_protocol_nht_cmd
,
1035 "show ip nht route-map",
1038 "IP Next Hop tracking filtering status\n")
1042 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
1043 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
1044 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1046 if (nht_rm
[AFI_IP
][i
])
1047 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
1051 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
1053 if (nht_rm
[AFI_IP
][i
])
1054 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP
][i
],
1057 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
1062 DEFUN (ipv6_protocol_nht_rmap
,
1063 ipv6_protocol_nht_rmap_cmd
,
1064 "ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
1066 "Filter Next Hop tracking route resolution\n"
1067 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
1072 if (strcasecmp(argv
[0], "any") == 0)
1073 i
= ZEBRA_ROUTE_MAX
;
1075 i
= proto_name2num(argv
[0]);
1078 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1082 if (nht_rm
[AFI_IP6
][i
])
1083 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
1084 nht_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
1085 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1090 DEFUN (no_ipv6_protocol_nht_rmap
,
1091 no_ipv6_protocol_nht_rmap_cmd
,
1092 "no ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
,
1095 "Filter Next Hop tracking route resolution\n"
1096 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
)
1100 if (strcasecmp(argv
[0], "any") == 0)
1101 i
= ZEBRA_ROUTE_MAX
;
1103 i
= proto_name2num(argv
[0]);
1106 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1111 if (nht_rm
[AFI_IP6
][i
] && argc
== 2 && strcmp(argv
[1], nht_rm
[AFI_IP6
][i
]))
1113 vty_out (vty
, "invalid route-map \"%s\"%s", argv
[1], VTY_NEWLINE
);
1117 if (nht_rm
[AFI_IP6
][i
])
1119 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
1120 nht_rm
[AFI_IP6
][i
] = NULL
;
1123 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1128 ALIAS (no_ipv6_protocol_nht_rmap
,
1129 no_ipv6_protocol_nht_rmap_val_cmd
,
1130 "no ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
1133 "Filter Next Hop tracking route resolution\n"
1134 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
1137 DEFUN (show_ipv6_protocol_nht
,
1138 show_ipv6_protocol_nht_cmd
,
1139 "show ipv6 nht route-map",
1142 "IPv6 protocol Next Hop filtering status\n")
1146 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
1147 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
1148 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1150 if (nht_rm
[AFI_IP6
][i
])
1151 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
1155 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
1157 if (nht_rm
[AFI_IP
][i
])
1158 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP6
][i
],
1161 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
1166 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
1168 /* `match ip next-hop IP_ACCESS_LIST' */
1170 /* Match function return 1 if match is success else return zero. */
1171 static route_map_result_t
1172 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
1173 route_map_object_t type
, void *object
)
1175 struct access_list
*alist
;
1176 struct nh_rmap_obj
*nh_data
;
1177 struct prefix_ipv4 p
;
1179 if (type
== RMAP_ZEBRA
)
1183 return RMAP_DENYMATCH
;
1185 switch (nh_data
->nexthop
->type
) {
1186 case NEXTHOP_TYPE_IFINDEX
:
1187 /* Interface routes can't match ip next-hop */
1188 return RMAP_NOMATCH
;
1189 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1190 case NEXTHOP_TYPE_IPV4
:
1192 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1193 p
.prefixlen
= IPV4_MAX_BITLEN
;
1196 return RMAP_NOMATCH
;
1198 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
1200 return RMAP_NOMATCH
;
1202 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
1203 RMAP_NOMATCH
: RMAP_MATCH
);
1205 return RMAP_NOMATCH
;
1208 /* Route map `ip next-hop' match statement. `arg' should be
1209 access-list name. */
1211 route_match_ip_next_hop_compile (const char *arg
)
1213 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1216 /* Free route map's compiled `. */
1218 route_match_ip_next_hop_free (void *rule
)
1220 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1223 /* Route map commands for ip next-hop matching. */
1224 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
1227 route_match_ip_next_hop
,
1228 route_match_ip_next_hop_compile
,
1229 route_match_ip_next_hop_free
1232 /* `match ip next-hop prefix-list PREFIX_LIST' */
1234 static route_map_result_t
1235 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
1236 route_map_object_t type
, void *object
)
1238 struct prefix_list
*plist
;
1239 struct nh_rmap_obj
*nh_data
;
1240 struct prefix_ipv4 p
;
1242 if (type
== RMAP_ZEBRA
)
1244 nh_data
= (struct nh_rmap_obj
*)object
;
1246 return RMAP_DENYMATCH
;
1248 switch (nh_data
->nexthop
->type
) {
1249 case NEXTHOP_TYPE_IFINDEX
:
1250 /* Interface routes can't match ip next-hop */
1251 return RMAP_NOMATCH
;
1252 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1253 case NEXTHOP_TYPE_IPV4
:
1255 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1256 p
.prefixlen
= IPV4_MAX_BITLEN
;
1259 return RMAP_NOMATCH
;
1261 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
1263 return RMAP_NOMATCH
;
1265 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
1266 RMAP_NOMATCH
: RMAP_MATCH
);
1268 return RMAP_NOMATCH
;
1272 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
1274 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1278 route_match_ip_next_hop_prefix_list_free (void *rule
)
1280 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1283 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
1285 "ip next-hop prefix-list",
1286 route_match_ip_next_hop_prefix_list
,
1287 route_match_ip_next_hop_prefix_list_compile
,
1288 route_match_ip_next_hop_prefix_list_free
1291 /* `match ip address IP_ACCESS_LIST' */
1293 /* Match function should return 1 if match is success else return
1295 static route_map_result_t
1296 route_match_ip_address (void *rule
, struct prefix
*prefix
,
1297 route_map_object_t type
, void *object
)
1299 struct access_list
*alist
;
1301 if (type
== RMAP_ZEBRA
)
1303 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
1305 return RMAP_NOMATCH
;
1307 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
1308 RMAP_NOMATCH
: RMAP_MATCH
);
1310 return RMAP_NOMATCH
;
1313 /* Route map `ip address' match statement. `arg' should be
1314 access-list name. */
1316 route_match_ip_address_compile (const char *arg
)
1318 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1321 /* Free route map's compiled `ip address' value. */
1323 route_match_ip_address_free (void *rule
)
1325 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1328 /* Route map commands for ip address matching. */
1329 static struct route_map_rule_cmd route_match_ip_address_cmd
=
1332 route_match_ip_address
,
1333 route_match_ip_address_compile
,
1334 route_match_ip_address_free
1337 /* `match ip address prefix-list PREFIX_LIST' */
1339 static route_map_result_t
1340 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
1341 route_map_object_t type
, void *object
)
1343 struct prefix_list
*plist
;
1345 if (type
== RMAP_ZEBRA
)
1347 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
1349 return RMAP_NOMATCH
;
1351 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
1352 RMAP_NOMATCH
: RMAP_MATCH
);
1354 return RMAP_NOMATCH
;
1358 route_match_ip_address_prefix_list_compile (const char *arg
)
1360 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1364 route_match_ip_address_prefix_list_free (void *rule
)
1366 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1369 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
1371 "ip address prefix-list",
1372 route_match_ip_address_prefix_list
,
1373 route_match_ip_address_prefix_list_compile
,
1374 route_match_ip_address_prefix_list_free
1378 /* `match ip address prefix-len PREFIXLEN' */
1380 static route_map_result_t
1381 route_match_ip_address_prefix_len (void *rule
, struct prefix
*prefix
,
1382 route_map_object_t type
, void *object
)
1384 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1386 if (type
== RMAP_ZEBRA
)
1388 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1390 return RMAP_NOMATCH
;
1394 route_match_ip_address_prefix_len_compile (const char *arg
)
1396 u_int32_t
*prefix_len
;
1397 char *endptr
= NULL
;
1398 unsigned long tmpval
;
1400 /* prefix len value shoud be integer. */
1401 if (! all_digit (arg
))
1405 tmpval
= strtoul (arg
, &endptr
, 10);
1406 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1409 prefix_len
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1414 *prefix_len
= tmpval
;
1419 route_match_ip_address_prefix_len_free (void *rule
)
1421 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1424 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
=
1426 "ip address prefix-len",
1427 route_match_ip_address_prefix_len
,
1428 route_match_ip_address_prefix_len_compile
,
1429 route_match_ip_address_prefix_len_free
1433 /* `match ip nexthop prefix-len PREFIXLEN' */
1435 static route_map_result_t
1436 route_match_ip_nexthop_prefix_len (void *rule
, struct prefix
*prefix
,
1437 route_map_object_t type
, void *object
)
1439 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1440 struct nh_rmap_obj
*nh_data
;
1441 struct prefix_ipv4 p
;
1443 if (type
== RMAP_ZEBRA
)
1445 nh_data
= (struct nh_rmap_obj
*)object
;
1446 if (!nh_data
|| !nh_data
->nexthop
)
1447 return RMAP_DENYMATCH
;
1449 switch (nh_data
->nexthop
->type
) {
1450 case NEXTHOP_TYPE_IFINDEX
:
1451 /* Interface routes can't match ip next-hop */
1452 return RMAP_NOMATCH
;
1453 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1454 case NEXTHOP_TYPE_IPV4
:
1456 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1457 p
.prefixlen
= IPV4_MAX_BITLEN
;
1460 return RMAP_NOMATCH
;
1462 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1464 return RMAP_NOMATCH
;
1467 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
=
1469 "ip next-hop prefix-len",
1470 route_match_ip_nexthop_prefix_len
,
1471 route_match_ip_address_prefix_len_compile
, /* reuse */
1472 route_match_ip_address_prefix_len_free
/* reuse */
1475 /* `match source-protocol PROTOCOL' */
1477 static route_map_result_t
1478 route_match_source_protocol (void *rule
, struct prefix
*prefix
,
1479 route_map_object_t type
, void *object
)
1481 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1482 struct nh_rmap_obj
*nh_data
;
1484 if (type
== RMAP_ZEBRA
)
1486 nh_data
= (struct nh_rmap_obj
*)object
;
1488 return RMAP_DENYMATCH
;
1490 return ((nh_data
->source_protocol
== *rib_type
)
1491 ? RMAP_MATCH
: RMAP_NOMATCH
);
1493 return RMAP_NOMATCH
;
1497 route_match_source_protocol_compile (const char *arg
)
1499 u_int32_t
*rib_type
;
1502 i
= proto_name2num(arg
);
1503 rib_type
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1511 route_match_source_protocol_free (void *rule
)
1513 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1516 static struct route_map_rule_cmd route_match_source_protocol_cmd
=
1519 route_match_source_protocol
,
1520 route_match_source_protocol_compile
,
1521 route_match_source_protocol_free
1524 /* `set src A.B.C.D' */
1527 static route_map_result_t
1528 route_set_src (void *rule
, struct prefix
*prefix
,
1529 route_map_object_t type
, void *object
)
1531 struct nh_rmap_obj
*nh_data
;
1533 if (type
== RMAP_ZEBRA
)
1535 nh_data
= (struct nh_rmap_obj
*)object
;
1536 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1541 /* set src compilation. */
1543 route_set_src_compile (const char *arg
)
1545 union g_addr src
, *psrc
;
1549 (inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1) ||
1550 #endif /* HAVE_IPV6 */
1551 (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)))
1553 psrc
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union g_addr
));
1560 /* Free route map's compiled `set src' value. */
1562 route_set_src_free (void *rule
)
1564 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1567 /* Set src rule structure. */
1568 static struct route_map_rule_cmd route_set_src_cmd
=
1572 route_set_src_compile
,
1577 zebra_route_map_update_timer (struct thread
*thread
)
1579 zebra_t_rmap_update
= NULL
;
1581 if (IS_ZEBRA_DEBUG_EVENT
)
1582 zlog_debug("Event driven route-map update triggered");
1584 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1585 zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
1588 zebra_import_table_rm_update ();
1589 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1590 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1591 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1597 zebra_route_map_set_delay_timer(u_int32_t value
)
1599 zebra_rmap_update_timer
= value
;
1600 if (!value
&& zebra_t_rmap_update
)
1602 /* Event driven route map updates is being disabled */
1603 /* But there's a pending timer. Fire it off now */
1604 thread_cancel(zebra_t_rmap_update
);
1605 zebra_route_map_update_timer(zebra_t_rmap_update
);
1610 zebra_route_map_write_delay_timer (struct vty
*vty
)
1612 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1613 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1619 zebra_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1620 struct nexthop
*nexthop
, vrf_id_t vrf_id
, route_tag_t tag
)
1622 struct route_map
*rmap
= NULL
;
1623 route_map_result_t ret
= RMAP_MATCH
;
1624 struct nh_rmap_obj nh_obj
;
1626 nh_obj
.nexthop
= nexthop
;
1627 nh_obj
.vrf_id
= vrf_id
;
1628 nh_obj
.source_protocol
= rib_type
;
1632 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1633 rmap
= route_map_lookup_by_name (proto_rm
[family
][rib_type
]);
1634 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1635 rmap
= route_map_lookup_by_name (proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1637 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1644 zebra_get_import_table_route_map (afi_t afi
, uint32_t table
)
1646 return zebra_import_table_routemap
[afi
][table
];
1650 zebra_add_import_table_route_map (afi_t afi
, const char *rmap_name
, uint32_t table
)
1652 zebra_import_table_routemap
[afi
][table
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1656 zebra_del_import_table_route_map (afi_t afi
, uint32_t table
)
1658 XFREE (MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1662 zebra_import_table_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1663 struct nexthop
*nexthop
, vrf_id_t vrf_id
, route_tag_t tag
, const char *rmap_name
)
1665 struct route_map
*rmap
= NULL
;
1666 route_map_result_t ret
= RMAP_DENYMATCH
;
1667 struct nh_rmap_obj nh_obj
;
1669 nh_obj
.nexthop
= nexthop
;
1670 nh_obj
.vrf_id
= vrf_id
;
1671 nh_obj
.source_protocol
= rib_type
;
1675 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1676 rmap
= route_map_lookup_by_name (rmap_name
);
1678 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1685 zebra_nht_route_map_check (int family
, int client_proto
, struct prefix
*p
,
1686 struct rib
* rib
, struct nexthop
*nexthop
)
1688 struct route_map
*rmap
= NULL
;
1689 route_map_result_t ret
= RMAP_MATCH
;
1690 struct nh_rmap_obj nh_obj
;
1692 nh_obj
.nexthop
= nexthop
;
1693 nh_obj
.vrf_id
= rib
->vrf_id
;
1694 nh_obj
.source_protocol
= rib
->type
;
1695 nh_obj
.metric
= rib
->metric
;
1696 nh_obj
.tag
= rib
->tag
;
1698 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1699 rmap
= route_map_lookup_by_name (nht_rm
[family
][client_proto
]);
1700 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1701 rmap
= route_map_lookup_by_name (nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1703 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1710 zebra_route_map_mark_update (const char *rmap_name
)
1712 /* rmap_update_timer of 0 means don't do route updates */
1713 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
)
1714 zebra_t_rmap_update
=
1715 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
, NULL
,
1716 zebra_rmap_update_timer
);
1720 zebra_route_map_add (const char *rmap_name
)
1722 zebra_route_map_mark_update(rmap_name
);
1723 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1727 zebra_route_map_delete (const char *rmap_name
)
1729 zebra_route_map_mark_update(rmap_name
);
1730 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1734 zebra_route_map_event (route_map_event_t event
, const char *rmap_name
)
1736 zebra_route_map_mark_update(rmap_name
);
1737 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1740 /* ip protocol configuration write function */
1742 zebra_routemap_config_write_protocol (struct vty
*vty
)
1746 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1748 if (proto_rm
[AFI_IP
][i
])
1749 vty_out (vty
, "ip protocol %s route-map %s%s", zebra_route_string(i
),
1750 proto_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1752 if (proto_rm
[AFI_IP6
][i
])
1753 vty_out (vty
, "ipv6 protocol %s route-map %s%s", zebra_route_string(i
),
1754 proto_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1756 if (nht_rm
[AFI_IP
][i
])
1757 vty_out (vty
, "ip nht %s route-map %s%s", zebra_route_string(i
),
1758 nht_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1760 if (nht_rm
[AFI_IP6
][i
])
1761 vty_out (vty
, "ipv6 nht %s route-map %s%s", zebra_route_string(i
),
1762 nht_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1765 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1766 vty_out (vty
, "ip protocol %s route-map %s%s", "any",
1767 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1769 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1770 vty_out (vty
, "ipv6 protocol %s route-map %s%s", "any",
1771 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1773 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1774 vty_out (vty
, "ip nht %s route-map %s%s", "any",
1775 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1777 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1778 vty_out (vty
, "ipv6 nht %s route-map %s%s", "any",
1779 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1781 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1782 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1787 zebra_route_map_init ()
1789 install_element (CONFIG_NODE
, &ip_protocol_cmd
);
1790 install_element (CONFIG_NODE
, &no_ip_protocol_cmd
);
1791 install_element (CONFIG_NODE
, &no_ip_protocol_val_cmd
);
1792 install_element (VIEW_NODE
, &show_ip_protocol_cmd
);
1793 install_element (CONFIG_NODE
, &ipv6_protocol_cmd
);
1794 install_element (CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1795 install_element (CONFIG_NODE
, &no_ipv6_protocol_val_cmd
);
1796 install_element (VIEW_NODE
, &show_ipv6_protocol_cmd
);
1797 install_element (CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1798 install_element (CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1799 install_element (CONFIG_NODE
, &no_ip_protocol_nht_rmap_val_cmd
);
1800 install_element (VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1801 install_element (CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1802 install_element (CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1803 install_element (CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_val_cmd
);
1804 install_element (VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1805 install_element (CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1806 install_element (CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1807 install_element (CONFIG_NODE
, &no_zebra_route_map_timer_val_cmd
);
1811 route_map_add_hook (zebra_route_map_add
);
1812 route_map_delete_hook (zebra_route_map_delete
);
1813 route_map_event_hook (zebra_route_map_event
);
1815 route_map_install_match (&route_match_tag_cmd
);
1816 route_map_install_match (&route_match_interface_cmd
);
1817 route_map_install_match (&route_match_ip_next_hop_cmd
);
1818 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
1819 route_map_install_match (&route_match_ip_address_cmd
);
1820 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
1821 route_map_install_match (&route_match_ip_address_prefix_len_cmd
);
1822 route_map_install_match (&route_match_ip_nexthop_prefix_len_cmd
);
1823 route_map_install_match (&route_match_source_protocol_cmd
);
1825 route_map_install_set (&route_set_src_cmd
);
1827 install_element (RMAP_NODE
, &match_tag_cmd
);
1828 install_element (RMAP_NODE
, &no_match_tag_cmd
);
1829 install_element (RMAP_NODE
, &no_match_tag_val_cmd
);
1830 install_element (RMAP_NODE
, &match_interface_cmd
);
1831 install_element (RMAP_NODE
, &no_match_interface_cmd
);
1832 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
1833 install_element (RMAP_NODE
, &match_ip_next_hop_cmd
);
1834 install_element (RMAP_NODE
, &no_match_ip_next_hop_cmd
);
1835 install_element (RMAP_NODE
, &no_match_ip_next_hop_val_cmd
);
1836 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
1837 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
1838 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_val_cmd
);
1839 install_element (RMAP_NODE
, &match_ip_address_cmd
);
1840 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
1841 install_element (RMAP_NODE
, &no_match_ip_address_val_cmd
);
1842 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
1843 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
1844 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_val_cmd
);
1845 install_element (RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1846 install_element (RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1847 install_element (RMAP_NODE
, &no_match_ip_nexthop_prefix_len_val_cmd
);
1848 install_element (RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1849 install_element (RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1850 install_element (RMAP_NODE
, &no_match_ip_address_prefix_len_val_cmd
);
1851 install_element (RMAP_NODE
, &match_source_protocol_cmd
);
1852 install_element (RMAP_NODE
, &no_match_source_protocol_cmd
);
1854 install_element (RMAP_NODE
, &set_src_cmd
);
1855 install_element (RMAP_NODE
, &no_set_src_cmd
);