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
34 #include "zebra/zserv.h"
35 #include "zebra/redistribute.h"
36 #include "zebra/debug.h"
37 #include "zebra/zebra_rnh.h"
38 #include "zebra/zebra_routemap.h"
40 static u_int32_t zebra_rmap_update_timer
= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
;
41 static struct thread
*zebra_t_rmap_update
= NULL
;
42 char *proto_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+1]; /* "any" == ZEBRA_ROUTE_MAX */
43 /* NH Tracking route map */
44 char *nht_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+1]; /* "any" == ZEBRA_ROUTE_MAX */
45 char *zebra_import_table_routemap
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
49 struct nexthop
*nexthop
;
51 u_int32_t source_protocol
;
56 static void zebra_route_map_set_delay_timer(u_int32_t value
);
58 /* Add zebra route map rule */
60 zebra_route_match_add(struct vty
*vty
, struct route_map_index
*index
,
61 const char *command
, const char *arg
,
62 route_map_event_t type
)
66 ret
= route_map_add_match (index
, command
, arg
);
71 case RMAP_RULE_MISSING
:
72 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
74 case RMAP_COMPILE_ERROR
:
75 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
80 if (type
!= RMAP_EVENT_MATCH_ADDED
)
82 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
87 /* Delete zebra route map rule. */
89 zebra_route_match_delete (struct vty
*vty
, struct route_map_index
*index
,
90 const char *command
, const char *arg
,
91 route_map_event_t type
)
94 char *dep_name
= NULL
;
96 char *rmap_name
= NULL
;
98 if (type
!= RMAP_EVENT_MATCH_DELETED
)
100 /* ignore the mundane, the types without any dependency */
103 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
104 dep_name
= 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
);
118 case RMAP_RULE_MISSING
:
119 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
121 case RMAP_COMPILE_ERROR
:
122 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
127 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
128 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
131 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
133 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
138 /* Add zebra route map rule. */
140 zebra_route_set_add (struct vty
*vty
, struct route_map_index
*index
,
141 const char *command
, const char *arg
)
145 ret
= route_map_add_set (index
, command
, arg
);
150 case RMAP_RULE_MISSING
:
151 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
153 case RMAP_COMPILE_ERROR
:
154 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
161 /* Delete zebra route map rule. */
163 zebra_route_set_delete (struct vty
*vty
, struct route_map_index
*index
,
164 const char *command
, const char *arg
)
168 ret
= route_map_delete_set (index
, command
, arg
);
173 case RMAP_RULE_MISSING
:
174 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
176 case RMAP_COMPILE_ERROR
:
177 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
185 * Match function return 1 if match is success else return 0
187 static route_map_result_t
188 route_match_tag (void *rule
, struct prefix
*prefix
,
189 route_map_object_t type
, void *object
)
192 struct nh_rmap_obj
*nh_data
;
194 if (type
== RMAP_ZEBRA
)
199 if (nh_data
->tag
== *tag
)
205 /* Route map 'match tag' match statement. 'arg' is TAG value */
207 route_match_tag_compile (const char *arg
)
212 /* tag value shoud be integer. */
213 if (! all_digit (arg
))
220 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
230 /* Free route map's compiled 'match tag' value. */
232 route_match_tag_free (void *rule
)
234 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
237 /* Route map commands for tag matching */
238 struct route_map_rule_cmd route_match_tag_cmd
=
242 route_match_tag_compile
,
247 /* `match interface IFNAME' */
248 /* Match function return 1 if match is success else return zero. */
249 static route_map_result_t
250 route_match_interface (void *rule
, struct prefix
*prefix
,
251 route_map_object_t type
, void *object
)
253 struct nh_rmap_obj
*nh_data
;
257 if (type
== RMAP_ZEBRA
)
259 if (strcasecmp(ifname
, "any") == 0)
262 if (!nh_data
|| !nh_data
->nexthop
)
264 ifindex
= ifname2ifindex_vrf (ifname
, nh_data
->vrf_id
);
267 if (nh_data
->nexthop
->ifindex
== ifindex
)
273 /* Route map `match interface' match statement. `arg' is IFNAME value */
275 route_match_interface_compile (const char *arg
)
277 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
280 /* Free route map's compiled `match interface' value. */
282 route_match_interface_free (void *rule
)
284 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
287 /* Route map commands for interface matching */
288 struct route_map_rule_cmd route_match_interface_cmd
=
291 route_match_interface
,
292 route_match_interface_compile
,
293 route_match_interface_free
296 DEFUN (match_interface
,
298 "match interface WORD",
300 "match first hop interface of route\n"
303 return zebra_route_match_add (vty
, vty
->index
, "interface", argv
[0],
304 RMAP_EVENT_MATCH_ADDED
);
307 DEFUN (no_match_interface
,
308 no_match_interface_cmd
,
309 "no match interface",
312 "Match first hop interface of route\n")
315 return zebra_route_match_delete (vty
, vty
->index
, "interface", NULL
, RMAP_EVENT_MATCH_DELETED
);
317 return zebra_route_match_delete (vty
, vty
->index
, "interface", argv
[0], RMAP_EVENT_MATCH_DELETED
);
320 ALIAS (no_match_interface
,
321 no_match_interface_val_cmd
,
322 "no match interface WORD",
325 "Match first hop interface of route\n"
330 "match tag <1-65535>",
332 "Match tag of route\n"
335 return zebra_route_match_add (vty
, vty
->index
, "tag", argv
[0],
336 RMAP_EVENT_MATCH_ADDED
);
344 "Match tag of route\n")
347 return zebra_route_match_delete (vty
, vty
->index
, "tag", NULL
,
348 RMAP_EVENT_MATCH_DELETED
);
350 return zebra_route_match_delete (vty
, vty
->index
, "tag", argv
[0],
351 RMAP_EVENT_MATCH_DELETED
);
355 no_match_tag_val_cmd
,
356 "no match tag <1-65535>",
359 "Match tag of route\n")
361 DEFUN (match_ip_next_hop
,
362 match_ip_next_hop_cmd
,
363 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
366 "Match next-hop address of route\n"
367 "IP access-list number\n"
368 "IP access-list number (expanded range)\n"
369 "IP Access-list name\n")
371 return zebra_route_match_add (vty
, vty
->index
, "ip next-hop", argv
[0], RMAP_EVENT_FILTER_ADDED
);
374 DEFUN (no_match_ip_next_hop
,
375 no_match_ip_next_hop_cmd
,
376 "no match ip next-hop",
380 "Match next-hop address of route\n")
383 return zebra_route_match_delete (vty
, vty
->index
, "ip next-hop", NULL
,
384 RMAP_EVENT_FILTER_DELETED
);
386 return zebra_route_match_delete (vty
, vty
->index
, "ip next-hop", argv
[0],
387 RMAP_EVENT_FILTER_DELETED
);
390 ALIAS (no_match_ip_next_hop
,
391 no_match_ip_next_hop_val_cmd
,
392 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
396 "Match next-hop address of route\n"
397 "IP access-list number\n"
398 "IP access-list number (expanded range)\n"
399 "IP Access-list name\n")
401 DEFUN (match_ip_next_hop_prefix_list
,
402 match_ip_next_hop_prefix_list_cmd
,
403 "match ip next-hop prefix-list WORD",
406 "Match next-hop address of route\n"
407 "Match entries of prefix-lists\n"
408 "IP prefix-list name\n")
410 return zebra_route_match_add (vty
, vty
->index
, "ip next-hop prefix-list",
411 argv
[0], RMAP_EVENT_PLIST_ADDED
);
414 DEFUN (no_match_ip_next_hop_prefix_list
,
415 no_match_ip_next_hop_prefix_list_cmd
,
416 "no match ip next-hop prefix-list",
420 "Match next-hop address of route\n"
421 "Match entries of prefix-lists\n")
424 return zebra_route_match_delete (vty
, vty
->index
,
425 "ip next-hop prefix-list", NULL
,
426 RMAP_EVENT_PLIST_DELETED
);
428 return zebra_route_match_delete (vty
, vty
->index
,
429 "ip next-hop prefix-list", argv
[0],
430 RMAP_EVENT_PLIST_DELETED
);
433 ALIAS (no_match_ip_next_hop_prefix_list
,
434 no_match_ip_next_hop_prefix_list_val_cmd
,
435 "no match ip next-hop prefix-list WORD",
439 "Match next-hop address of route\n"
440 "Match entries of prefix-lists\n"
441 "IP prefix-list name\n")
443 DEFUN (match_ip_address
,
444 match_ip_address_cmd
,
445 "match ip address (<1-199>|<1300-2699>|WORD)",
448 "Match address of route\n"
449 "IP access-list number\n"
450 "IP access-list number (expanded range)\n"
451 "IP Access-list name\n")
454 return zebra_route_match_add (vty
, vty
->index
, "ip address", argv
[0],
455 RMAP_EVENT_FILTER_ADDED
);
458 DEFUN (no_match_ip_address
,
459 no_match_ip_address_cmd
,
460 "no match ip address",
464 "Match address of route\n")
467 return zebra_route_match_delete (vty
, vty
->index
, "ip address", NULL
,
468 RMAP_EVENT_FILTER_DELETED
);
470 return zebra_route_match_delete (vty
, vty
->index
, "ip address", argv
[0],
471 RMAP_EVENT_FILTER_DELETED
);
474 ALIAS (no_match_ip_address
,
475 no_match_ip_address_val_cmd
,
476 "no match ip address (<1-199>|<1300-2699>|WORD)",
480 "Match address of route\n"
481 "IP access-list number\n"
482 "IP access-list number (expanded range)\n"
483 "IP Access-list name\n")
485 DEFUN (match_ip_address_prefix_list
,
486 match_ip_address_prefix_list_cmd
,
487 "match ip address prefix-list WORD",
490 "Match address of route\n"
491 "Match entries of prefix-lists\n"
492 "IP prefix-list name\n")
494 return zebra_route_match_add (vty
, vty
->index
, "ip address prefix-list",
495 argv
[0], RMAP_EVENT_PLIST_ADDED
);
498 DEFUN (no_match_ip_address_prefix_list
,
499 no_match_ip_address_prefix_list_cmd
,
500 "no match ip address prefix-list",
504 "Match address of route\n"
505 "Match entries of prefix-lists\n")
508 return zebra_route_match_delete (vty
, vty
->index
,
509 "ip address prefix-list", NULL
,
510 RMAP_EVENT_PLIST_DELETED
);
512 return zebra_route_match_delete (vty
, vty
->index
,
513 "ip address prefix-list", argv
[0],
514 RMAP_EVENT_PLIST_DELETED
);
517 ALIAS (no_match_ip_address_prefix_list
,
518 no_match_ip_address_prefix_list_val_cmd
,
519 "no match ip address prefix-list WORD",
523 "Match address of route\n"
524 "Match entries of prefix-lists\n"
525 "IP prefix-list name\n")
527 DEFUN (match_ip_address_prefix_len
,
528 match_ip_address_prefix_len_cmd
,
529 "match ip address prefix-len NUMBER",
532 "Match prefix length of ip address\n"
533 "Match prefix length of ip address\n"
536 return zebra_route_match_add (vty
, vty
->index
, "ip address prefix-len",
537 argv
[0], RMAP_EVENT_MATCH_ADDED
);
540 DEFUN (no_match_ip_address_prefix_len
,
541 no_match_ip_address_prefix_len_cmd
,
542 "no match ip address prefix-len",
546 "Match prefixlen of ip address of route\n"
547 "prefix length of ip address\n")
550 return zebra_route_match_delete (vty
, vty
->index
,
551 "ip address prefix-len", NULL
,
552 RMAP_EVENT_MATCH_DELETED
);
554 return zebra_route_match_delete (vty
, vty
->index
,
555 "ip address prefix-len", argv
[0],
556 RMAP_EVENT_MATCH_DELETED
);
559 ALIAS (no_match_ip_address_prefix_len
,
560 no_match_ip_address_prefix_len_val_cmd
,
561 "no match ip address prefix-len NUMBER",
565 "Match prefixlen of ip address of route\n"
566 "prefix length of ip address\n")
568 DEFUN (match_ip_nexthop_prefix_len
,
569 match_ip_nexthop_prefix_len_cmd
,
570 "match ip next-hop prefix-len NUMBER",
573 "Match prefixlen of nexthop ip address\n"
574 "Match prefixlen of given nexthop\n"
577 return zebra_route_match_add (vty
, vty
->index
, "ip next-hop prefix-len",
578 argv
[0], RMAP_EVENT_MATCH_ADDED
);
581 DEFUN (no_match_ip_nexthop_prefix_len
,
582 no_match_ip_nexthop_prefix_len_cmd
,
583 "no match ip next-hop prefix-len",
587 "Match prefixlen of nexthop ip address\n"
588 "Match prefix length of nexthop\n")
591 return zebra_route_match_delete (vty
, vty
->index
,
592 "ip next-hop prefix-len", NULL
,
593 RMAP_EVENT_MATCH_DELETED
);
595 return zebra_route_match_delete (vty
, vty
->index
,
596 "ip next-hop prefix-len", argv
[0],
597 RMAP_EVENT_MATCH_DELETED
);
600 ALIAS (no_match_ip_nexthop_prefix_len
,
601 no_match_ip_nexthop_prefix_len_val_cmd
,
602 "no match ip next-hop prefix-len NUMBER",
604 "Match prefixlen of ip address of route\n"
605 "prefix length of ip address\n")
607 DEFUN (match_source_protocol
,
608 match_source_protocol_cmd
,
609 "match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
611 "Match protocol via which the route was learnt\n")
615 i
= proto_name2num(argv
[0]);
618 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
622 return zebra_route_match_add (vty
, vty
->index
, "source-protocol",
623 argv
[0], RMAP_EVENT_MATCH_ADDED
);
626 DEFUN (no_match_source_protocol
,
627 no_match_source_protocol_cmd
,
628 "no match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
631 "No match protocol via which the route was learnt\n")
637 i
= proto_name2num(argv
[0]);
640 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
645 return zebra_route_match_delete (vty
, vty
->index
,
646 "source-protocol", argv
[0] ? argv
[0] : NULL
,
647 RMAP_EVENT_MATCH_DELETED
);
654 "set src (A.B.C.D|X:X::X:X)",
656 "src address for route\n"
660 struct interface
*pif
= NULL
;
665 if (inet_pton(AF_INET
, argv
[0], &src
.ipv4
) != 1)
667 if (inet_pton(AF_INET6
, argv
[0], &src
.ipv6
) != 1)
669 vty_out (vty
, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE
);
673 p
.family
= family
= AF_INET6
;
674 p
.u
.prefix6
= src
.ipv6
;
675 p
.prefixlen
= IPV6_MAX_BITLEN
;
679 p
.family
= family
= AF_INET
;
680 p
.u
.prefix4
= src
.ipv4
;
681 p
.prefixlen
= IPV4_MAX_BITLEN
;
684 if (!zebra_check_addr(&p
))
686 vty_out (vty
, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE
);
690 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
692 if (family
== AF_INET
)
693 pif
= if_lookup_exact_address_vrf ((void *)&src
.ipv4
, AF_INET
,
695 else if (family
== AF_INET6
)
696 pif
= if_lookup_exact_address_vrf ((void *)&src
.ipv6
, AF_INET6
,
705 vty_out (vty
, "%% not a local address%s", VTY_NEWLINE
);
708 return zebra_route_set_add (vty
, vty
->index
, "src", argv
[0]);
713 "no set src {A.B.C.D|X:X::X:X}",
716 "Source address for route\n")
719 return zebra_route_set_delete (vty
, vty
->index
, "src", NULL
);
721 return zebra_route_set_delete (vty
, vty
->index
, "src", argv
[0]);
724 DEFUN (zebra_route_map_timer
,
725 zebra_route_map_timer_cmd
,
726 "zebra route-map delay-timer <0-600>",
727 "Time to wait before route-map updates are processed\n"
728 "0 means event-driven updates are disabled\n")
730 u_int32_t rmap_delay_timer
;
732 VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer
, argv
[0], 0, 600);
733 zebra_route_map_set_delay_timer(rmap_delay_timer
);
735 return (CMD_SUCCESS
);
738 DEFUN (no_zebra_route_map_timer
,
739 no_zebra_route_map_timer_cmd
,
740 "no zebra route-map delay-timer",
742 "Time to wait before route-map updates are processed\n"
743 "Reset delay-timer to default value, 30 secs\n")
745 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
747 return (CMD_SUCCESS
);
750 ALIAS (no_zebra_route_map_timer
,
751 no_zebra_route_map_timer_val_cmd
,
752 "no zebra route-map delay-timer <0-600>",
754 "Time to wait before route-map updates are processed\n"
755 "Reset delay-timer to default value, 30 secs\n"
756 "0 means event-driven updates are disabled\n")
760 "ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
762 "Filter routing info exchanged between zebra and protocol\n"
763 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
768 if (strcasecmp(argv
[0], "any") == 0)
771 i
= proto_name2num(argv
[0]);
774 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
778 if (proto_rm
[AFI_IP
][i
])
780 if (strcmp(proto_rm
[AFI_IP
][i
], argv
[1]) == 0)
783 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
785 proto_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
787 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
788 zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
789 VRF_DEFAULT
, argv
[0]);
791 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
795 DEFUN (no_ip_protocol
,
797 "no ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
,
800 "Stop filtering routing info between zebra and protocol\n"
801 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
802 "Protocol from which to stop filtering routes\n")
806 if (strcasecmp(argv
[0], "any") == 0)
809 i
= proto_name2num(argv
[0]);
812 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
816 if (!proto_rm
[AFI_IP
][i
])
819 if ((argc
== 2 && strcmp(argv
[1], proto_rm
[AFI_IP
][i
]) == 0) ||
822 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
823 proto_rm
[AFI_IP
][i
] = NULL
;
825 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
826 zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
827 VRF_DEFAULT
, argv
[0]);
828 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
833 ALIAS (no_ip_protocol
,
834 no_ip_protocol_val_cmd
,
835 "no ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
838 "Stop filtering routing info between zebra and protocol\n"
839 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
842 DEFUN (show_ip_protocol
,
843 show_ip_protocol_cmd
,
847 "IP protocol filtering status\n")
851 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
852 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
853 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
855 if (proto_rm
[AFI_IP
][i
])
856 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
860 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
862 if (proto_rm
[AFI_IP
][i
])
863 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP
][i
],
866 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
871 DEFUN (ipv6_protocol
,
873 "ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
875 "Filter IPv6 routing info exchanged between zebra and protocol\n"
876 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
881 if (strcasecmp(argv
[0], "any") == 0)
884 i
= proto_name2num(argv
[0]);
887 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
891 if (proto_rm
[AFI_IP6
][i
])
893 if (strcmp(proto_rm
[AFI_IP6
][i
], argv
[1]) == 0)
896 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
898 proto_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
900 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
901 zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
902 VRF_DEFAULT
, argv
[0]);
904 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
908 DEFUN (no_ipv6_protocol
,
909 no_ipv6_protocol_cmd
,
910 "no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
,
913 "Stop filtering IPv6 routing info between zebra and protocol\n"
914 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
915 "Protocol from which to stop filtering routes\n")
919 if (strcasecmp(argv
[0], "any") == 0)
922 i
= proto_name2num(argv
[0]);
925 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
929 if (!proto_rm
[AFI_IP6
][i
])
932 if ((argc
== 2 && strcmp(argv
[1], proto_rm
[AFI_IP6
][i
]) == 0) ||
935 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
936 proto_rm
[AFI_IP6
][i
] = NULL
;
938 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
939 zlog_debug ("%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
940 VRF_DEFAULT
, argv
[0]);
942 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
947 ALIAS (no_ipv6_protocol
,
948 no_ipv6_protocol_val_cmd
,
949 "no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
952 "Stop filtering IPv6 routing info between zebra and protocol\n"
953 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
956 DEFUN (show_ipv6_protocol
,
957 show_ipv6_protocol_cmd
,
958 "show ipv6 protocol",
961 "IPv6 protocol filtering status\n")
965 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
966 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
967 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
969 if (proto_rm
[AFI_IP6
][i
])
970 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
971 proto_rm
[AFI_IP6
][i
],
974 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
976 if (proto_rm
[AFI_IP6
][i
])
977 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP6
][i
],
980 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
985 DEFUN (ip_protocol_nht_rmap
,
986 ip_protocol_nht_rmap_cmd
,
987 "ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
989 "Filter Next Hop tracking route resolution\n"
990 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
995 if (strcasecmp(argv
[0], "any") == 0)
998 i
= proto_name2num(argv
[0]);
1001 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1005 if (nht_rm
[AFI_IP
][i
])
1007 if (strcmp(nht_rm
[AFI_IP
][i
], argv
[1]) == 0)
1010 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
1013 nht_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
1014 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1019 DEFUN (no_ip_protocol_nht_rmap
,
1020 no_ip_protocol_nht_rmap_cmd
,
1021 "no ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
,
1024 "Filter Next Hop tracking route resolution\n"
1025 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
)
1029 if (strcasecmp(argv
[0], "any") == 0)
1030 i
= ZEBRA_ROUTE_MAX
;
1032 i
= proto_name2num(argv
[0]);
1035 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1039 if (!nht_rm
[AFI_IP
][i
])
1042 if ((argc
== 2 && strcmp(argv
[1], nht_rm
[AFI_IP
][i
]) == 0) ||
1045 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
1046 nht_rm
[AFI_IP
][i
] = NULL
;
1047 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1052 ALIAS (no_ip_protocol_nht_rmap
,
1053 no_ip_protocol_nht_rmap_val_cmd
,
1054 "no ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
1056 "Filter Next Hop tracking route resolution\n"
1057 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
1060 DEFUN (show_ip_protocol_nht
,
1061 show_ip_protocol_nht_cmd
,
1062 "show ip nht route-map",
1065 "IP Next Hop tracking filtering status\n")
1069 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
1070 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
1071 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1073 if (nht_rm
[AFI_IP
][i
])
1074 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
1078 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
1080 if (nht_rm
[AFI_IP
][i
])
1081 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP
][i
],
1084 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
1089 DEFUN (ipv6_protocol_nht_rmap
,
1090 ipv6_protocol_nht_rmap_cmd
,
1091 "ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
1093 "Filter Next Hop tracking route resolution\n"
1094 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
1099 if (strcasecmp(argv
[0], "any") == 0)
1100 i
= ZEBRA_ROUTE_MAX
;
1102 i
= proto_name2num(argv
[0]);
1105 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1109 if (nht_rm
[AFI_IP6
][i
])
1110 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
1111 nht_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, argv
[1]);
1112 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1117 DEFUN (no_ipv6_protocol_nht_rmap
,
1118 no_ipv6_protocol_nht_rmap_cmd
,
1119 "no ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
,
1122 "Filter Next Hop tracking route resolution\n"
1123 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
)
1127 if (strcasecmp(argv
[0], "any") == 0)
1128 i
= ZEBRA_ROUTE_MAX
;
1130 i
= proto_name2num(argv
[0]);
1133 vty_out (vty
, "invalid protocol name \"%s\"%s", argv
[0] ? argv
[0] : "",
1138 if (nht_rm
[AFI_IP6
][i
] && argc
== 2 && strcmp(argv
[1], nht_rm
[AFI_IP6
][i
]))
1140 vty_out (vty
, "invalid route-map \"%s\"%s", argv
[1], VTY_NEWLINE
);
1144 if (nht_rm
[AFI_IP6
][i
])
1146 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
1147 nht_rm
[AFI_IP6
][i
] = NULL
;
1150 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1155 ALIAS (no_ipv6_protocol_nht_rmap
,
1156 no_ipv6_protocol_nht_rmap_val_cmd
,
1157 "no ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
1160 "Filter Next Hop tracking route resolution\n"
1161 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
1164 DEFUN (show_ipv6_protocol_nht
,
1165 show_ipv6_protocol_nht_cmd
,
1166 "show ipv6 nht route-map",
1169 "IPv6 protocol Next Hop filtering status\n")
1173 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
1174 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
1175 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1177 if (nht_rm
[AFI_IP6
][i
])
1178 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
1182 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
1184 if (nht_rm
[AFI_IP
][i
])
1185 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP6
][i
],
1188 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
1193 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
1195 /* `match ip next-hop IP_ACCESS_LIST' */
1197 /* Match function return 1 if match is success else return zero. */
1198 static route_map_result_t
1199 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
1200 route_map_object_t type
, void *object
)
1202 struct access_list
*alist
;
1203 struct nh_rmap_obj
*nh_data
;
1204 struct prefix_ipv4 p
;
1206 if (type
== RMAP_ZEBRA
)
1210 return RMAP_DENYMATCH
;
1212 switch (nh_data
->nexthop
->type
) {
1213 case NEXTHOP_TYPE_IFINDEX
:
1214 /* Interface routes can't match ip next-hop */
1215 return RMAP_NOMATCH
;
1216 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1217 case NEXTHOP_TYPE_IPV4
:
1219 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1220 p
.prefixlen
= IPV4_MAX_BITLEN
;
1223 return RMAP_NOMATCH
;
1225 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
1227 return RMAP_NOMATCH
;
1229 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
1230 RMAP_NOMATCH
: RMAP_MATCH
);
1232 return RMAP_NOMATCH
;
1235 /* Route map `ip next-hop' match statement. `arg' should be
1236 access-list name. */
1238 route_match_ip_next_hop_compile (const char *arg
)
1240 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1243 /* Free route map's compiled `. */
1245 route_match_ip_next_hop_free (void *rule
)
1247 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1250 /* Route map commands for ip next-hop matching. */
1251 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
1254 route_match_ip_next_hop
,
1255 route_match_ip_next_hop_compile
,
1256 route_match_ip_next_hop_free
1259 /* `match ip next-hop prefix-list PREFIX_LIST' */
1261 static route_map_result_t
1262 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
1263 route_map_object_t type
, void *object
)
1265 struct prefix_list
*plist
;
1266 struct nh_rmap_obj
*nh_data
;
1267 struct prefix_ipv4 p
;
1269 if (type
== RMAP_ZEBRA
)
1271 nh_data
= (struct nh_rmap_obj
*)object
;
1273 return RMAP_DENYMATCH
;
1275 switch (nh_data
->nexthop
->type
) {
1276 case NEXTHOP_TYPE_IFINDEX
:
1277 /* Interface routes can't match ip next-hop */
1278 return RMAP_NOMATCH
;
1279 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1280 case NEXTHOP_TYPE_IPV4
:
1282 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1283 p
.prefixlen
= IPV4_MAX_BITLEN
;
1286 return RMAP_NOMATCH
;
1288 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
1290 return RMAP_NOMATCH
;
1292 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
1293 RMAP_NOMATCH
: RMAP_MATCH
);
1295 return RMAP_NOMATCH
;
1299 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
1301 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1305 route_match_ip_next_hop_prefix_list_free (void *rule
)
1307 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1310 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
1312 "ip next-hop prefix-list",
1313 route_match_ip_next_hop_prefix_list
,
1314 route_match_ip_next_hop_prefix_list_compile
,
1315 route_match_ip_next_hop_prefix_list_free
1318 /* `match ip address IP_ACCESS_LIST' */
1320 /* Match function should return 1 if match is success else return
1322 static route_map_result_t
1323 route_match_ip_address (void *rule
, struct prefix
*prefix
,
1324 route_map_object_t type
, void *object
)
1326 struct access_list
*alist
;
1328 if (type
== RMAP_ZEBRA
)
1330 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
1332 return RMAP_NOMATCH
;
1334 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
1335 RMAP_NOMATCH
: RMAP_MATCH
);
1337 return RMAP_NOMATCH
;
1340 /* Route map `ip address' match statement. `arg' should be
1341 access-list name. */
1343 route_match_ip_address_compile (const char *arg
)
1345 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1348 /* Free route map's compiled `ip address' value. */
1350 route_match_ip_address_free (void *rule
)
1352 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1355 /* Route map commands for ip address matching. */
1356 static struct route_map_rule_cmd route_match_ip_address_cmd
=
1359 route_match_ip_address
,
1360 route_match_ip_address_compile
,
1361 route_match_ip_address_free
1364 /* `match ip address prefix-list PREFIX_LIST' */
1366 static route_map_result_t
1367 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
1368 route_map_object_t type
, void *object
)
1370 struct prefix_list
*plist
;
1372 if (type
== RMAP_ZEBRA
)
1374 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
1376 return RMAP_NOMATCH
;
1378 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
1379 RMAP_NOMATCH
: RMAP_MATCH
);
1381 return RMAP_NOMATCH
;
1385 route_match_ip_address_prefix_list_compile (const char *arg
)
1387 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1391 route_match_ip_address_prefix_list_free (void *rule
)
1393 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1396 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
1398 "ip address prefix-list",
1399 route_match_ip_address_prefix_list
,
1400 route_match_ip_address_prefix_list_compile
,
1401 route_match_ip_address_prefix_list_free
1405 /* `match ip address prefix-len PREFIXLEN' */
1407 static route_map_result_t
1408 route_match_ip_address_prefix_len (void *rule
, struct prefix
*prefix
,
1409 route_map_object_t type
, void *object
)
1411 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1413 if (type
== RMAP_ZEBRA
)
1415 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1417 return RMAP_NOMATCH
;
1421 route_match_ip_address_prefix_len_compile (const char *arg
)
1423 u_int32_t
*prefix_len
;
1424 char *endptr
= NULL
;
1425 unsigned long tmpval
;
1427 /* prefix len value shoud be integer. */
1428 if (! all_digit (arg
))
1432 tmpval
= strtoul (arg
, &endptr
, 10);
1433 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1436 prefix_len
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1441 *prefix_len
= tmpval
;
1446 route_match_ip_address_prefix_len_free (void *rule
)
1448 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1451 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
=
1453 "ip address prefix-len",
1454 route_match_ip_address_prefix_len
,
1455 route_match_ip_address_prefix_len_compile
,
1456 route_match_ip_address_prefix_len_free
1460 /* `match ip nexthop prefix-len PREFIXLEN' */
1462 static route_map_result_t
1463 route_match_ip_nexthop_prefix_len (void *rule
, struct prefix
*prefix
,
1464 route_map_object_t type
, void *object
)
1466 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1467 struct nh_rmap_obj
*nh_data
;
1468 struct prefix_ipv4 p
;
1470 if (type
== RMAP_ZEBRA
)
1472 nh_data
= (struct nh_rmap_obj
*)object
;
1473 if (!nh_data
|| !nh_data
->nexthop
)
1474 return RMAP_DENYMATCH
;
1476 switch (nh_data
->nexthop
->type
) {
1477 case NEXTHOP_TYPE_IFINDEX
:
1478 /* Interface routes can't match ip next-hop */
1479 return RMAP_NOMATCH
;
1480 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1481 case NEXTHOP_TYPE_IPV4
:
1483 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1484 p
.prefixlen
= IPV4_MAX_BITLEN
;
1487 return RMAP_NOMATCH
;
1489 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1491 return RMAP_NOMATCH
;
1494 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
=
1496 "ip next-hop prefix-len",
1497 route_match_ip_nexthop_prefix_len
,
1498 route_match_ip_address_prefix_len_compile
, /* reuse */
1499 route_match_ip_address_prefix_len_free
/* reuse */
1502 /* `match source-protocol PROTOCOL' */
1504 static route_map_result_t
1505 route_match_source_protocol (void *rule
, struct prefix
*prefix
,
1506 route_map_object_t type
, void *object
)
1508 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1509 struct nh_rmap_obj
*nh_data
;
1511 if (type
== RMAP_ZEBRA
)
1513 nh_data
= (struct nh_rmap_obj
*)object
;
1515 return RMAP_DENYMATCH
;
1517 return ((nh_data
->source_protocol
== *rib_type
)
1518 ? RMAP_MATCH
: RMAP_NOMATCH
);
1520 return RMAP_NOMATCH
;
1524 route_match_source_protocol_compile (const char *arg
)
1526 u_int32_t
*rib_type
;
1529 i
= proto_name2num(arg
);
1530 rib_type
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1538 route_match_source_protocol_free (void *rule
)
1540 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1543 static struct route_map_rule_cmd route_match_source_protocol_cmd
=
1546 route_match_source_protocol
,
1547 route_match_source_protocol_compile
,
1548 route_match_source_protocol_free
1551 /* `set src A.B.C.D' */
1554 static route_map_result_t
1555 route_set_src (void *rule
, struct prefix
*prefix
,
1556 route_map_object_t type
, void *object
)
1558 struct nh_rmap_obj
*nh_data
;
1560 if (type
== RMAP_ZEBRA
)
1562 nh_data
= (struct nh_rmap_obj
*)object
;
1563 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1568 /* set src compilation. */
1570 route_set_src_compile (const char *arg
)
1572 union g_addr src
, *psrc
;
1576 (inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1) ||
1577 #endif /* HAVE_IPV6 */
1578 (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)))
1580 psrc
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union g_addr
));
1587 /* Free route map's compiled `set src' value. */
1589 route_set_src_free (void *rule
)
1591 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1594 /* Set src rule structure. */
1595 static struct route_map_rule_cmd route_set_src_cmd
=
1599 route_set_src_compile
,
1604 zebra_route_map_update_timer (struct thread
*thread
)
1606 zebra_t_rmap_update
= NULL
;
1608 if (IS_ZEBRA_DEBUG_EVENT
)
1609 zlog_debug("Event driven route-map update triggered");
1611 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1612 zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
1615 zebra_import_table_rm_update ();
1616 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1617 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1618 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1624 zebra_route_map_set_delay_timer(u_int32_t value
)
1626 zebra_rmap_update_timer
= value
;
1627 if (!value
&& zebra_t_rmap_update
)
1629 /* Event driven route map updates is being disabled */
1630 /* But there's a pending timer. Fire it off now */
1631 thread_cancel(zebra_t_rmap_update
);
1632 zebra_route_map_update_timer(zebra_t_rmap_update
);
1637 zebra_route_map_write_delay_timer (struct vty
*vty
)
1639 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1640 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1646 zebra_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1647 struct nexthop
*nexthop
, vrf_id_t vrf_id
, u_short tag
)
1649 struct route_map
*rmap
= NULL
;
1650 route_map_result_t ret
= RMAP_MATCH
;
1651 struct nh_rmap_obj nh_obj
;
1653 nh_obj
.nexthop
= nexthop
;
1654 nh_obj
.vrf_id
= vrf_id
;
1655 nh_obj
.source_protocol
= rib_type
;
1659 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1660 rmap
= route_map_lookup_by_name (proto_rm
[family
][rib_type
]);
1661 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1662 rmap
= route_map_lookup_by_name (proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1664 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1671 zebra_get_import_table_route_map (afi_t afi
, uint32_t table
)
1673 return zebra_import_table_routemap
[afi
][table
];
1677 zebra_add_import_table_route_map (afi_t afi
, const char *rmap_name
, uint32_t table
)
1679 zebra_import_table_routemap
[afi
][table
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1683 zebra_del_import_table_route_map (afi_t afi
, uint32_t table
)
1685 XFREE (MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1689 zebra_import_table_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1690 struct nexthop
*nexthop
, vrf_id_t vrf_id
, u_short tag
, const char *rmap_name
)
1692 struct route_map
*rmap
= NULL
;
1693 route_map_result_t ret
= RMAP_DENYMATCH
;
1694 struct nh_rmap_obj nh_obj
;
1696 nh_obj
.nexthop
= nexthop
;
1697 nh_obj
.vrf_id
= vrf_id
;
1698 nh_obj
.source_protocol
= rib_type
;
1702 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1703 rmap
= route_map_lookup_by_name (rmap_name
);
1705 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1712 zebra_nht_route_map_check (int family
, int client_proto
, struct prefix
*p
,
1713 struct rib
* rib
, struct nexthop
*nexthop
)
1715 struct route_map
*rmap
= NULL
;
1716 route_map_result_t ret
= RMAP_MATCH
;
1717 struct nh_rmap_obj nh_obj
;
1719 nh_obj
.nexthop
= nexthop
;
1720 nh_obj
.vrf_id
= rib
->vrf_id
;
1721 nh_obj
.source_protocol
= rib
->type
;
1722 nh_obj
.metric
= rib
->metric
;
1723 nh_obj
.tag
= rib
->tag
;
1725 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1726 rmap
= route_map_lookup_by_name (nht_rm
[family
][client_proto
]);
1727 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1728 rmap
= route_map_lookup_by_name (nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1730 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1737 zebra_route_map_mark_update (const char *rmap_name
)
1739 /* rmap_update_timer of 0 means don't do route updates */
1740 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
)
1741 zebra_t_rmap_update
=
1742 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
, NULL
,
1743 zebra_rmap_update_timer
);
1747 zebra_route_map_add (const char *rmap_name
)
1749 zebra_route_map_mark_update(rmap_name
);
1750 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1754 zebra_route_map_delete (const char *rmap_name
)
1756 zebra_route_map_mark_update(rmap_name
);
1757 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1761 zebra_route_map_event (route_map_event_t event
, const char *rmap_name
)
1763 zebra_route_map_mark_update(rmap_name
);
1764 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1767 /* ip protocol configuration write function */
1769 zebra_routemap_config_write_protocol (struct vty
*vty
)
1773 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1775 if (proto_rm
[AFI_IP
][i
])
1776 vty_out (vty
, "ip protocol %s route-map %s%s", zebra_route_string(i
),
1777 proto_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1779 if (proto_rm
[AFI_IP6
][i
])
1780 vty_out (vty
, "ipv6 protocol %s route-map %s%s", zebra_route_string(i
),
1781 proto_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1783 if (nht_rm
[AFI_IP
][i
])
1784 vty_out (vty
, "ip nht %s route-map %s%s", zebra_route_string(i
),
1785 nht_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1787 if (nht_rm
[AFI_IP6
][i
])
1788 vty_out (vty
, "ipv6 nht %s route-map %s%s", zebra_route_string(i
),
1789 nht_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1792 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1793 vty_out (vty
, "ip protocol %s route-map %s%s", "any",
1794 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1796 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1797 vty_out (vty
, "ipv6 protocol %s route-map %s%s", "any",
1798 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1800 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1801 vty_out (vty
, "ip nht %s route-map %s%s", "any",
1802 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1804 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1805 vty_out (vty
, "ipv6 nht %s route-map %s%s", "any",
1806 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1808 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1809 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1814 zebra_route_map_init ()
1816 install_element (CONFIG_NODE
, &ip_protocol_cmd
);
1817 install_element (CONFIG_NODE
, &no_ip_protocol_cmd
);
1818 install_element (CONFIG_NODE
, &no_ip_protocol_val_cmd
);
1819 install_element (VIEW_NODE
, &show_ip_protocol_cmd
);
1820 install_element (ENABLE_NODE
, &show_ip_protocol_cmd
);
1821 install_element (CONFIG_NODE
, &ipv6_protocol_cmd
);
1822 install_element (CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1823 install_element (CONFIG_NODE
, &no_ipv6_protocol_val_cmd
);
1824 install_element (VIEW_NODE
, &show_ipv6_protocol_cmd
);
1825 install_element (ENABLE_NODE
, &show_ipv6_protocol_cmd
);
1826 install_element (CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1827 install_element (CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1828 install_element (CONFIG_NODE
, &no_ip_protocol_nht_rmap_val_cmd
);
1829 install_element (VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1830 install_element (ENABLE_NODE
, &show_ip_protocol_nht_cmd
);
1831 install_element (CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1832 install_element (CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1833 install_element (CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_val_cmd
);
1834 install_element (VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1835 install_element (ENABLE_NODE
, &show_ipv6_protocol_nht_cmd
);
1836 install_element (CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1837 install_element (CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1838 install_element (CONFIG_NODE
, &no_zebra_route_map_timer_val_cmd
);
1841 route_map_init_vty ();
1843 route_map_add_hook (zebra_route_map_add
);
1844 route_map_delete_hook (zebra_route_map_delete
);
1845 route_map_event_hook (zebra_route_map_event
);
1847 route_map_install_match (&route_match_tag_cmd
);
1848 route_map_install_match (&route_match_interface_cmd
);
1849 route_map_install_match (&route_match_ip_next_hop_cmd
);
1850 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
1851 route_map_install_match (&route_match_ip_address_cmd
);
1852 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
1853 route_map_install_match (&route_match_ip_address_prefix_len_cmd
);
1854 route_map_install_match (&route_match_ip_nexthop_prefix_len_cmd
);
1855 route_map_install_match (&route_match_source_protocol_cmd
);
1857 route_map_install_set (&route_set_src_cmd
);
1859 install_element (RMAP_NODE
, &match_tag_cmd
);
1860 install_element (RMAP_NODE
, &no_match_tag_cmd
);
1861 install_element (RMAP_NODE
, &no_match_tag_val_cmd
);
1862 install_element (RMAP_NODE
, &match_interface_cmd
);
1863 install_element (RMAP_NODE
, &no_match_interface_cmd
);
1864 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
1865 install_element (RMAP_NODE
, &match_ip_next_hop_cmd
);
1866 install_element (RMAP_NODE
, &no_match_ip_next_hop_cmd
);
1867 install_element (RMAP_NODE
, &no_match_ip_next_hop_val_cmd
);
1868 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
1869 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
1870 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_val_cmd
);
1871 install_element (RMAP_NODE
, &match_ip_address_cmd
);
1872 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
1873 install_element (RMAP_NODE
, &no_match_ip_address_val_cmd
);
1874 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
1875 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
1876 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_val_cmd
);
1877 install_element (RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1878 install_element (RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1879 install_element (RMAP_NODE
, &no_match_ip_nexthop_prefix_len_val_cmd
);
1880 install_element (RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1881 install_element (RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1882 install_element (RMAP_NODE
, &no_match_ip_address_prefix_len_val_cmd
);
1883 install_element (RMAP_NODE
, &match_source_protocol_cmd
);
1884 install_element (RMAP_NODE
, &no_match_source_protocol_cmd
);
1886 install_element (RMAP_NODE
, &set_src_cmd
);
1887 install_element (RMAP_NODE
, &no_set_src_cmd
);