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"
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
];
49 struct nexthop
*nexthop
;
51 u_int32_t source_protocol
;
56 static void zebra_route_map_set_delay_timer(u_int32_t value
);
59 /* Add zebra route map rule */
60 static int zebra_route_match_add(struct vty
*vty
, const char *command
,
61 const char *arg
, route_map_event_t type
)
63 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
65 int retval
= CMD_SUCCESS
;
67 ret
= route_map_add_match(index
, command
, arg
);
69 case RMAP_RULE_MISSING
:
70 vty_out(vty
, "%% Zebra Can't find rule.\n");
71 retval
= CMD_WARNING_CONFIG_FAILED
;
73 case RMAP_COMPILE_ERROR
:
74 vty_out(vty
, "%% Zebra Argument is malformed.\n");
75 retval
= CMD_WARNING_CONFIG_FAILED
;
77 case RMAP_COMPILE_SUCCESS
:
78 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
79 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
87 /* Delete zebra route map rule. */
88 static int zebra_route_match_delete(struct vty
*vty
, const char *command
,
89 const char *arg
, route_map_event_t type
)
91 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
93 int retval
= CMD_SUCCESS
;
94 char *dep_name
= NULL
;
96 char *rmap_name
= NULL
;
98 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
99 /* ignore the mundane, the types without any dependency */
101 if ((tmpstr
= route_map_get_match_arg(index
, command
))
104 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
106 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
108 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
111 ret
= route_map_delete_match(index
, command
, arg
);
113 case RMAP_RULE_MISSING
:
114 vty_out(vty
, "%% Zebra Can't find rule.\n");
115 retval
= CMD_WARNING_CONFIG_FAILED
;
117 case RMAP_COMPILE_ERROR
:
118 vty_out(vty
, "%% Zebra Argument is malformed.\n");
119 retval
= CMD_WARNING_CONFIG_FAILED
;
121 case RMAP_COMPILE_SUCCESS
:
122 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
123 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
128 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
130 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
136 * Match function return 1 if match is success else return 0
138 static route_map_result_t
route_match_tag(void *rule
, struct prefix
*prefix
,
139 route_map_object_t type
, void *object
)
142 struct nh_rmap_obj
*nh_data
;
144 if (type
== RMAP_ZEBRA
) {
148 if (nh_data
->tag
== *tag
)
154 /* Route map commands for tag matching */
155 static struct route_map_rule_cmd route_match_tag_cmd
= {
156 "tag", route_match_tag
, route_map_rule_tag_compile
,
157 route_map_rule_tag_free
,
161 /* `match interface IFNAME' */
162 /* Match function return 1 if match is success else return zero. */
163 static route_map_result_t
route_match_interface(void *rule
,
164 struct prefix
*prefix
,
165 route_map_object_t type
,
168 struct nh_rmap_obj
*nh_data
;
172 if (type
== RMAP_ZEBRA
) {
173 if (strcasecmp(ifname
, "any") == 0)
176 if (!nh_data
|| !nh_data
->nexthop
)
178 ifindex
= ifname2ifindex(ifname
, nh_data
->vrf_id
);
181 if (nh_data
->nexthop
->ifindex
== ifindex
)
187 /* Route map `match interface' match statement. `arg' is IFNAME value */
188 static void *route_match_interface_compile(const char *arg
)
190 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
193 /* Free route map's compiled `match interface' value. */
194 static void route_match_interface_free(void *rule
)
196 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
199 /* Route map commands for interface matching */
200 struct route_map_rule_cmd route_match_interface_cmd
= {
201 "interface", route_match_interface
, route_match_interface_compile
,
202 route_match_interface_free
};
204 DEFUN (match_ip_address_prefix_len
,
205 match_ip_address_prefix_len_cmd
,
206 "match ip address prefix-len (0-32)",
209 "Match prefix length of ip address\n"
210 "Match prefix length of ip address\n"
213 return zebra_route_match_add(vty
, "ip address prefix-len", argv
[4]->arg
,
214 RMAP_EVENT_MATCH_ADDED
);
217 DEFUN (no_match_ip_address_prefix_len
,
218 no_match_ip_address_prefix_len_cmd
,
219 "no match ip address prefix-len [(0-32)]",
223 "Match prefix length of ip address\n"
224 "Match prefix length of ip address\n"
227 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
228 return zebra_route_match_delete(vty
, "ip address prefix-len", plen
,
229 RMAP_EVENT_MATCH_DELETED
);
232 DEFUN (match_ipv6_address_prefix_len
,
233 match_ipv6_address_prefix_len_cmd
,
234 "match ipv6 address prefix-len (0-128)",
237 "Match prefix length of ipv6 address\n"
238 "Match prefix length of ipv6 address\n"
241 return zebra_route_match_add(vty
, "ipv6 address prefix-len", argv
[4]->arg
,
242 RMAP_EVENT_MATCH_ADDED
);
245 DEFUN (no_match_ipv6_address_prefix_len
,
246 no_match_ipv6_address_prefix_len_cmd
,
247 "no match ipv6 address prefix-len [(0-128)]",
251 "Match prefix length of ip address\n"
252 "Match prefix length of ip address\n"
255 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
256 return zebra_route_match_delete(vty
, "ipv6 address prefix-len", plen
,
257 RMAP_EVENT_MATCH_DELETED
);
260 DEFUN (match_ip_nexthop_prefix_len
,
261 match_ip_nexthop_prefix_len_cmd
,
262 "match ip next-hop prefix-len (0-32)",
265 "Match prefixlen of nexthop ip address\n"
266 "Match prefixlen of given nexthop\n"
269 return zebra_route_match_add(vty
, "ip next-hop prefix-len",
270 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
273 DEFUN (no_match_ip_nexthop_prefix_len
,
274 no_match_ip_nexthop_prefix_len_cmd
,
275 "no match ip next-hop prefix-len [(0-32)]",
279 "Match prefixlen of nexthop ip address\n"
280 "Match prefix length of nexthop\n"
283 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
284 return zebra_route_match_delete(vty
, "ip next-hop prefix-len", plen
,
285 RMAP_EVENT_MATCH_DELETED
);
288 DEFUN (match_source_protocol
,
289 match_source_protocol_cmd
,
290 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static>",
292 "Match protocol via which the route was learnt\n"
303 "Routes from directly connected peer\n"
304 "Routes from system configuration\n"
305 "Routes from kernel\n"
306 "Statically configured routes\n")
308 char *proto
= argv
[2]->text
;
311 i
= proto_name2num(proto
);
313 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
314 return CMD_WARNING_CONFIG_FAILED
;
316 return zebra_route_match_add(vty
, "source-protocol", proto
,
317 RMAP_EVENT_MATCH_ADDED
);
320 DEFUN (no_match_source_protocol
,
321 no_match_source_protocol_cmd
,
322 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static>]",
325 "No match protocol via which the route was learnt\n"
336 "Routes from directly connected peer\n"
337 "Routes from system configuration\n"
338 "Routes from kernel\n"
339 "Statically configured routes\n")
341 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
342 return zebra_route_match_delete(vty
, "source-protocol", proto
,
343 RMAP_EVENT_MATCH_DELETED
);
350 "set src <A.B.C.D|X:X::X:X>",
352 "src address for route\n"
354 "IPv6 src address\n")
358 struct interface
*pif
= NULL
;
363 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1) {
364 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1) {
365 vty_out(vty
, "%% not a valid IPv4/v6 address\n");
366 return CMD_WARNING_CONFIG_FAILED
;
369 p
.family
= family
= AF_INET6
;
370 p
.u
.prefix6
= src
.ipv6
;
371 p
.prefixlen
= IPV6_MAX_BITLEN
;
373 p
.family
= family
= AF_INET
;
374 p
.u
.prefix4
= src
.ipv4
;
375 p
.prefixlen
= IPV4_MAX_BITLEN
;
378 if (!zebra_check_addr(&p
)) {
379 vty_out(vty
, "%% not a valid source IPv4/v6 address\n");
380 return CMD_WARNING_CONFIG_FAILED
;
383 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
) {
384 if (family
== AF_INET
)
385 pif
= if_lookup_exact_address((void *)&src
.ipv4
,
386 AF_INET
, vrf
->vrf_id
);
387 else if (family
== AF_INET6
)
388 pif
= if_lookup_exact_address((void *)&src
.ipv6
,
389 AF_INET6
, vrf
->vrf_id
);
396 vty_out(vty
, "%% not a local address\n");
397 return CMD_WARNING_CONFIG_FAILED
;
400 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
401 return generic_set_add(vty
, index
, "src", argv
[idx_ip
]->arg
);
406 "no set src [<A.B.C.D|X:X::X:X>]",
409 "Source address for route\n"
413 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
414 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
415 return generic_set_delete(vty
, index
, "src", ip
);
418 DEFUN (zebra_route_map_timer
,
419 zebra_route_map_timer_cmd
,
420 "zebra route-map delay-timer (0-600)",
422 "Set route-map parameters\n"
423 "Time to wait before route-map updates are processed\n"
424 "0 means event-driven updates are disabled\n")
427 u_int32_t rmap_delay_timer
;
429 rmap_delay_timer
= strtoul(argv
[idx_number
]->arg
, NULL
, 10);
430 zebra_route_map_set_delay_timer(rmap_delay_timer
);
432 return (CMD_SUCCESS
);
435 DEFUN (no_zebra_route_map_timer
,
436 no_zebra_route_map_timer_cmd
,
437 "no zebra route-map delay-timer [(0-600)]",
440 "Set route-map parameters\n"
441 "Reset delay-timer to default value, 30 secs\n"
442 "0 means event-driven updates are disabled\n")
444 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
446 return (CMD_SUCCESS
);
452 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
454 "Filter routing info exchanged between zebra and protocol\n"
455 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
456 "Specify route-map\n"
459 char *proto
= argv
[2]->text
;
460 char *rmap
= argv
[4]->arg
;
463 if (strcasecmp(proto
, "any") == 0)
466 i
= proto_name2num(proto
);
468 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
469 return CMD_WARNING_CONFIG_FAILED
;
471 if (proto_rm
[AFI_IP
][i
]) {
472 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
475 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
477 proto_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
479 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
481 "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
484 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
488 DEFUN (no_ip_protocol
,
490 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
493 "Stop filtering routing info between zebra and protocol\n"
494 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
495 "Specify route map\n"
498 char *proto
= argv
[3]->text
;
499 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
502 if (strcasecmp(proto
, "any") == 0)
505 i
= proto_name2num(proto
);
508 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
509 return CMD_WARNING_CONFIG_FAILED
;
512 if (!proto_rm
[AFI_IP
][i
])
515 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP
][i
]) == 0) {
516 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
517 proto_rm
[AFI_IP
][i
] = NULL
;
519 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
521 "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
523 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
528 DEFUN (show_ip_protocol
,
529 show_ip_protocol_cmd
,
533 "IP protocol filtering status\n")
537 vty_out(vty
, "Protocol : route-map \n");
538 vty_out(vty
, "------------------------\n");
539 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
540 if (proto_rm
[AFI_IP
][i
])
541 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
542 proto_rm
[AFI_IP
][i
]);
544 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
546 if (proto_rm
[AFI_IP
][i
])
547 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP
][i
]);
549 vty_out(vty
, "%-10s : none\n", "any");
554 DEFUN (ipv6_protocol
,
556 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
558 "Filter IPv6 routing info exchanged between zebra and protocol\n"
559 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
560 "Specify route map\n"
563 char *proto
= argv
[2]->text
;
564 char *rmap
= argv
[4]->arg
;
567 if (strcasecmp(proto
, "any") == 0)
570 i
= proto_name2num(proto
);
572 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
573 return CMD_WARNING_CONFIG_FAILED
;
575 if (proto_rm
[AFI_IP6
][i
]) {
576 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
579 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
581 proto_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
583 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
585 "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
588 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
592 DEFUN (no_ipv6_protocol
,
593 no_ipv6_protocol_cmd
,
594 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
597 "Stop filtering IPv6 routing info between zebra and protocol\n"
598 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
599 "Specify route map\n"
602 const char *proto
= argv
[3]->text
;
603 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
606 if (strcasecmp(proto
, "any") == 0)
609 i
= proto_name2num(proto
);
611 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
612 return CMD_WARNING_CONFIG_FAILED
;
614 if (!proto_rm
[AFI_IP6
][i
])
617 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0) {
618 XFREE(MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
619 proto_rm
[AFI_IP6
][i
] = NULL
;
621 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
623 "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
626 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
631 DEFUN (show_ipv6_protocol
,
632 show_ipv6_protocol_cmd
,
633 "show ipv6 protocol",
636 "IPv6 protocol filtering status\n")
640 vty_out(vty
, "Protocol : route-map \n");
641 vty_out(vty
, "------------------------\n");
642 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
643 if (proto_rm
[AFI_IP6
][i
])
644 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
645 proto_rm
[AFI_IP6
][i
]);
647 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
649 if (proto_rm
[AFI_IP6
][i
])
650 vty_out(vty
, "%-10s : %-10s\n", "any", proto_rm
[AFI_IP6
][i
]);
652 vty_out(vty
, "%-10s : none\n", "any");
657 DEFUN (ip_protocol_nht_rmap
,
658 ip_protocol_nht_rmap_cmd
,
659 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
661 "Filter Next Hop tracking route resolution\n"
662 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
663 "Specify route map\n"
666 char *proto
= argv
[2]->text
;
667 char *rmap
= argv
[4]->arg
;
670 if (strcasecmp(proto
, "any") == 0)
673 i
= proto_name2num(proto
);
675 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
676 return CMD_WARNING_CONFIG_FAILED
;
678 if (nht_rm
[AFI_IP
][i
]) {
679 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
682 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
685 nht_rm
[AFI_IP
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
686 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
691 DEFUN (no_ip_protocol_nht_rmap
,
692 no_ip_protocol_nht_rmap_cmd
,
693 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
696 "Filter Next Hop tracking route resolution\n"
697 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
698 "Specify route map\n"
702 char *proto
= argv
[3]->text
;
703 char *rmap
= argv_find(argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
706 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
707 : proto_name2num(proto
);
710 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
711 return CMD_WARNING_CONFIG_FAILED
;
714 if (!nht_rm
[AFI_IP
][i
])
717 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0) {
718 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
719 nht_rm
[AFI_IP
][i
] = NULL
;
720 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
725 DEFUN (show_ip_protocol_nht
,
726 show_ip_protocol_nht_cmd
,
727 "show ip nht route-map",
730 "IP nexthop tracking table\n"
731 "IP Next Hop tracking filtering status\n")
735 vty_out(vty
, "Protocol : route-map \n");
736 vty_out(vty
, "------------------------\n");
737 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
738 if (nht_rm
[AFI_IP
][i
])
739 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
742 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
744 if (nht_rm
[AFI_IP
][i
])
745 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP
][i
]);
747 vty_out(vty
, "%-10s : none\n", "any");
752 DEFUN (ipv6_protocol_nht_rmap
,
753 ipv6_protocol_nht_rmap_cmd
,
754 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
756 "Filter Next Hop tracking route resolution\n"
757 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
758 "Specify route map\n"
761 char *proto
= argv
[2]->text
;
762 char *rmap
= argv
[4]->arg
;
765 if (strcasecmp(proto
, "any") == 0)
768 i
= proto_name2num(proto
);
770 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
771 return CMD_WARNING_CONFIG_FAILED
;
773 if (nht_rm
[AFI_IP6
][i
])
774 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
775 nht_rm
[AFI_IP6
][i
] = XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
776 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
781 DEFUN (no_ipv6_protocol_nht_rmap
,
782 no_ipv6_protocol_nht_rmap_cmd
,
783 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
786 "Filter Next Hop tracking route resolution\n"
787 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
788 "Specify route map\n"
791 char *proto
= argv
[3]->text
;
792 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
795 if (strcasecmp(proto
, "any") == 0)
798 i
= proto_name2num(proto
);
800 vty_out(vty
, "invalid protocol name \"%s\"\n", proto
);
801 return CMD_WARNING_CONFIG_FAILED
;
804 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
])) {
805 vty_out(vty
, "invalid route-map \"%s\"\n", rmap
);
806 return CMD_WARNING_CONFIG_FAILED
;
809 if (nht_rm
[AFI_IP6
][i
]) {
810 XFREE(MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
811 nht_rm
[AFI_IP6
][i
] = NULL
;
814 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
819 DEFUN (show_ipv6_protocol_nht
,
820 show_ipv6_protocol_nht_cmd
,
821 "show ipv6 nht route-map",
824 "Next Hop filtering status\n"
829 vty_out(vty
, "Protocol : route-map \n");
830 vty_out(vty
, "------------------------\n");
831 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
832 if (nht_rm
[AFI_IP6
][i
])
833 vty_out(vty
, "%-10s : %-10s\n", zebra_route_string(i
),
836 vty_out(vty
, "%-10s : none\n", zebra_route_string(i
));
838 if (nht_rm
[AFI_IP
][i
])
839 vty_out(vty
, "%-10s : %-10s\n", "any", nht_rm
[AFI_IP6
][i
]);
841 vty_out(vty
, "%-10s : none\n", "any");
846 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
848 /* `match ip next-hop IP_ACCESS_LIST' */
850 /* Match function return 1 if match is success else return zero. */
851 static route_map_result_t
route_match_ip_next_hop(void *rule
,
852 struct prefix
*prefix
,
853 route_map_object_t type
,
856 struct access_list
*alist
;
857 struct nh_rmap_obj
*nh_data
;
858 struct prefix_ipv4 p
;
860 if (type
== RMAP_ZEBRA
) {
863 return RMAP_DENYMATCH
;
865 switch (nh_data
->nexthop
->type
) {
866 case NEXTHOP_TYPE_IFINDEX
:
867 /* Interface routes can't match ip next-hop */
869 case NEXTHOP_TYPE_IPV4_IFINDEX
:
870 case NEXTHOP_TYPE_IPV4
:
872 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
873 p
.prefixlen
= IPV4_MAX_BITLEN
;
878 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
882 return (access_list_apply(alist
, &p
) == FILTER_DENY
889 /* Route map `ip next-hop' match statement. `arg' should be
891 static void *route_match_ip_next_hop_compile(const char *arg
)
893 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
896 /* Free route map's compiled `. */
897 static void route_match_ip_next_hop_free(void *rule
)
899 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
902 /* Route map commands for ip next-hop matching. */
903 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
904 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
905 route_match_ip_next_hop_free
};
907 /* `match ip next-hop prefix-list PREFIX_LIST' */
909 static route_map_result_t
910 route_match_ip_next_hop_prefix_list(void *rule
, struct prefix
*prefix
,
911 route_map_object_t type
, void *object
)
913 struct prefix_list
*plist
;
914 struct nh_rmap_obj
*nh_data
;
915 struct prefix_ipv4 p
;
917 if (type
== RMAP_ZEBRA
) {
918 nh_data
= (struct nh_rmap_obj
*)object
;
920 return RMAP_DENYMATCH
;
922 switch (nh_data
->nexthop
->type
) {
923 case NEXTHOP_TYPE_IFINDEX
:
924 /* Interface routes can't match ip next-hop */
926 case NEXTHOP_TYPE_IPV4_IFINDEX
:
927 case NEXTHOP_TYPE_IPV4
:
929 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
930 p
.prefixlen
= IPV4_MAX_BITLEN
;
935 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
939 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
946 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
948 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
951 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
953 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
956 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
957 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
958 route_match_ip_next_hop_prefix_list_compile
,
959 route_match_ip_next_hop_prefix_list_free
};
961 /* `match ip address IP_ACCESS_LIST' */
963 /* Match function should return 1 if match is success else return
965 static route_map_result_t
route_match_ip_address(void *rule
,
966 struct prefix
*prefix
,
967 route_map_object_t type
,
970 struct access_list
*alist
;
972 if (type
== RMAP_ZEBRA
) {
973 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
977 return (access_list_apply(alist
, prefix
) == FILTER_DENY
984 /* Route map `ip address' match statement. `arg' should be
986 static void *route_match_ip_address_compile(const char *arg
)
988 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
991 /* Free route map's compiled `ip address' value. */
992 static void route_match_ip_address_free(void *rule
)
994 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
997 /* Route map commands for ip address matching. */
998 static struct route_map_rule_cmd route_match_ip_address_cmd
= {
999 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
1000 route_match_ip_address_free
};
1002 /* `match ip address prefix-list PREFIX_LIST' */
1004 static route_map_result_t
1005 route_match_ip_address_prefix_list(void *rule
, struct prefix
*prefix
,
1006 route_map_object_t type
, void *object
)
1008 struct prefix_list
*plist
;
1010 if (type
== RMAP_ZEBRA
) {
1011 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
1013 return RMAP_NOMATCH
;
1015 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
1019 return RMAP_NOMATCH
;
1022 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
1024 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1027 static void route_match_ip_address_prefix_list_free(void *rule
)
1029 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1032 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
1033 "ip address prefix-list", route_match_ip_address_prefix_list
,
1034 route_match_ip_address_prefix_list_compile
,
1035 route_match_ip_address_prefix_list_free
};
1038 /* `match ip address prefix-len PREFIXLEN' */
1040 static route_map_result_t
1041 route_match_address_prefix_len(void *rule
, struct prefix
*prefix
,
1042 route_map_object_t type
, void *object
)
1044 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1046 if (type
== RMAP_ZEBRA
) {
1047 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
1050 return RMAP_NOMATCH
;
1053 static void *route_match_address_prefix_len_compile(const char *arg
)
1055 u_int32_t
*prefix_len
;
1056 char *endptr
= NULL
;
1057 unsigned long tmpval
;
1059 /* prefix len value shoud be integer. */
1060 if (!all_digit(arg
))
1064 tmpval
= strtoul(arg
, &endptr
, 10);
1065 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1068 prefix_len
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(u_int32_t
));
1073 *prefix_len
= tmpval
;
1077 static void route_match_address_prefix_len_free(void *rule
)
1079 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1082 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
= {
1083 "ip address prefix-len", route_match_address_prefix_len
,
1084 route_match_address_prefix_len_compile
,
1085 route_match_address_prefix_len_free
};
1087 static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd
= {
1088 "ipv6 address prefix-len", route_match_address_prefix_len
,
1089 route_match_address_prefix_len_compile
,
1090 route_match_address_prefix_len_free
};
1092 /* `match ip nexthop prefix-len PREFIXLEN' */
1094 static route_map_result_t
1095 route_match_ip_nexthop_prefix_len(void *rule
, struct prefix
*prefix
,
1096 route_map_object_t type
, void *object
)
1098 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1099 struct nh_rmap_obj
*nh_data
;
1100 struct prefix_ipv4 p
;
1102 if (type
== RMAP_ZEBRA
) {
1103 nh_data
= (struct nh_rmap_obj
*)object
;
1104 if (!nh_data
|| !nh_data
->nexthop
)
1105 return RMAP_DENYMATCH
;
1107 switch (nh_data
->nexthop
->type
) {
1108 case NEXTHOP_TYPE_IFINDEX
:
1109 /* Interface routes can't match ip next-hop */
1110 return RMAP_NOMATCH
;
1111 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1112 case NEXTHOP_TYPE_IPV4
:
1114 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1115 p
.prefixlen
= IPV4_MAX_BITLEN
;
1118 return RMAP_NOMATCH
;
1120 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
1123 return RMAP_NOMATCH
;
1126 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
= {
1127 "ip next-hop prefix-len", route_match_ip_nexthop_prefix_len
,
1128 route_match_address_prefix_len_compile
, /* reuse */
1129 route_match_address_prefix_len_free
/* reuse */
1132 /* `match source-protocol PROTOCOL' */
1134 static route_map_result_t
route_match_source_protocol(void *rule
,
1135 struct prefix
*prefix
,
1136 route_map_object_t type
,
1139 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1140 struct nh_rmap_obj
*nh_data
;
1142 if (type
== RMAP_ZEBRA
) {
1143 nh_data
= (struct nh_rmap_obj
*)object
;
1145 return RMAP_DENYMATCH
;
1147 return ((nh_data
->source_protocol
== *rib_type
) ? RMAP_MATCH
1150 return RMAP_NOMATCH
;
1153 static void *route_match_source_protocol_compile(const char *arg
)
1155 u_int32_t
*rib_type
;
1158 i
= proto_name2num(arg
);
1159 rib_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(u_int32_t
));
1166 static void route_match_source_protocol_free(void *rule
)
1168 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1171 static struct route_map_rule_cmd route_match_source_protocol_cmd
= {
1172 "source-protocol", route_match_source_protocol
,
1173 route_match_source_protocol_compile
, route_match_source_protocol_free
};
1175 /* `set src A.B.C.D' */
1178 static route_map_result_t
route_set_src(void *rule
, struct prefix
*prefix
,
1179 route_map_object_t type
, void *object
)
1181 struct nh_rmap_obj
*nh_data
;
1183 if (type
== RMAP_ZEBRA
) {
1184 nh_data
= (struct nh_rmap_obj
*)object
;
1185 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1190 /* set src compilation. */
1191 static void *route_set_src_compile(const char *arg
)
1193 union g_addr src
, *psrc
;
1195 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1)
1196 || (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1))) {
1197 psrc
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(union g_addr
));
1204 /* Free route map's compiled `set src' value. */
1205 static void route_set_src_free(void *rule
)
1207 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1210 /* Set src rule structure. */
1211 static struct route_map_rule_cmd route_set_src_cmd
= {
1212 "src", route_set_src
, route_set_src_compile
, route_set_src_free
,
1215 static int zebra_route_map_update_timer(struct thread
*thread
)
1217 zebra_t_rmap_update
= NULL
;
1219 if (IS_ZEBRA_DEBUG_EVENT
)
1220 zlog_debug("Event driven route-map update triggered");
1222 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1224 "%u: Routemap update-timer fired, scheduling RIB processing",
1227 zebra_import_table_rm_update();
1228 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1229 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1230 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1235 static void zebra_route_map_set_delay_timer(u_int32_t value
)
1237 zebra_rmap_update_timer
= value
;
1238 if (!value
&& zebra_t_rmap_update
) {
1239 /* Event driven route map updates is being disabled */
1240 /* But there's a pending timer. Fire it off now */
1241 thread_cancel(zebra_t_rmap_update
);
1242 zebra_route_map_update_timer(zebra_t_rmap_update
);
1246 void zebra_route_map_write_delay_timer(struct vty
*vty
)
1248 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1249 vty_out(vty
, "zebra route-map delay-timer %d\n",
1250 zebra_rmap_update_timer
);
1254 route_map_result_t
zebra_route_map_check(int family
, int rib_type
,
1256 struct nexthop
*nexthop
,
1257 vrf_id_t vrf_id
, route_tag_t tag
)
1259 struct route_map
*rmap
= NULL
;
1260 route_map_result_t ret
= RMAP_MATCH
;
1261 struct nh_rmap_obj nh_obj
;
1263 nh_obj
.nexthop
= nexthop
;
1264 nh_obj
.vrf_id
= vrf_id
;
1265 nh_obj
.source_protocol
= rib_type
;
1269 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1270 rmap
= route_map_lookup_by_name(proto_rm
[family
][rib_type
]);
1271 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1272 rmap
= route_map_lookup_by_name(
1273 proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1275 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1281 char *zebra_get_import_table_route_map(afi_t afi
, uint32_t table
)
1283 return zebra_import_table_routemap
[afi
][table
];
1286 void zebra_add_import_table_route_map(afi_t afi
, const char *rmap_name
,
1289 zebra_import_table_routemap
[afi
][table
] =
1290 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1293 void zebra_del_import_table_route_map(afi_t afi
, uint32_t table
)
1295 XFREE(MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1299 zebra_import_table_route_map_check(int family
, int re_type
, struct prefix
*p
,
1300 struct nexthop
*nexthop
, vrf_id_t vrf_id
,
1301 route_tag_t tag
, const char *rmap_name
)
1303 struct route_map
*rmap
= NULL
;
1304 route_map_result_t ret
= RMAP_DENYMATCH
;
1305 struct nh_rmap_obj nh_obj
;
1307 nh_obj
.nexthop
= nexthop
;
1308 nh_obj
.vrf_id
= vrf_id
;
1309 nh_obj
.source_protocol
= re_type
;
1313 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1314 rmap
= route_map_lookup_by_name(rmap_name
);
1316 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1322 route_map_result_t
zebra_nht_route_map_check(int family
, int client_proto
,
1324 struct route_entry
*re
,
1325 struct nexthop
*nexthop
)
1327 struct route_map
*rmap
= NULL
;
1328 route_map_result_t ret
= RMAP_MATCH
;
1329 struct nh_rmap_obj nh_obj
;
1331 nh_obj
.nexthop
= nexthop
;
1332 nh_obj
.vrf_id
= re
->vrf_id
;
1333 nh_obj
.source_protocol
= re
->type
;
1334 nh_obj
.metric
= re
->metric
;
1335 nh_obj
.tag
= re
->tag
;
1337 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1338 rmap
= route_map_lookup_by_name(nht_rm
[family
][client_proto
]);
1339 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1340 rmap
= route_map_lookup_by_name(
1341 nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1343 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1349 static void zebra_route_map_mark_update(const char *rmap_name
)
1351 /* rmap_update_timer of 0 means don't do route updates */
1352 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1353 zebra_t_rmap_update
= NULL
;
1354 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
,
1355 NULL
, zebra_rmap_update_timer
,
1356 &zebra_t_rmap_update
);
1360 static void zebra_route_map_add(const char *rmap_name
)
1362 zebra_route_map_mark_update(rmap_name
);
1363 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1366 static void zebra_route_map_delete(const char *rmap_name
)
1368 zebra_route_map_mark_update(rmap_name
);
1369 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1372 static void zebra_route_map_event(route_map_event_t event
,
1373 const char *rmap_name
)
1375 zebra_route_map_mark_update(rmap_name
);
1376 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1379 /* ip protocol configuration write function */
1380 void zebra_routemap_config_write_protocol(struct vty
*vty
)
1384 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1385 if (proto_rm
[AFI_IP
][i
])
1386 vty_out(vty
, "ip protocol %s route-map %s\n",
1387 zebra_route_string(i
), proto_rm
[AFI_IP
][i
]);
1389 if (proto_rm
[AFI_IP6
][i
])
1390 vty_out(vty
, "ipv6 protocol %s route-map %s\n",
1391 zebra_route_string(i
), proto_rm
[AFI_IP6
][i
]);
1393 if (nht_rm
[AFI_IP
][i
])
1394 vty_out(vty
, "ip nht %s route-map %s\n",
1395 zebra_route_string(i
), nht_rm
[AFI_IP
][i
]);
1397 if (nht_rm
[AFI_IP6
][i
])
1398 vty_out(vty
, "ipv6 nht %s route-map %s\n",
1399 zebra_route_string(i
), nht_rm
[AFI_IP6
][i
]);
1402 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1403 vty_out(vty
, "ip protocol %s route-map %s\n", "any",
1404 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1406 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1407 vty_out(vty
, "ipv6 protocol %s route-map %s\n", "any",
1408 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1410 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1411 vty_out(vty
, "ip nht %s route-map %s\n", "any",
1412 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
]);
1414 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1415 vty_out(vty
, "ipv6 nht %s route-map %s\n", "any",
1416 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
]);
1418 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1419 vty_out(vty
, "zebra route-map delay-timer %d\n",
1420 zebra_rmap_update_timer
);
1423 void zebra_route_map_init()
1425 install_element(CONFIG_NODE
, &ip_protocol_cmd
);
1426 install_element(CONFIG_NODE
, &no_ip_protocol_cmd
);
1427 install_element(VIEW_NODE
, &show_ip_protocol_cmd
);
1428 install_element(CONFIG_NODE
, &ipv6_protocol_cmd
);
1429 install_element(CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1430 install_element(VIEW_NODE
, &show_ipv6_protocol_cmd
);
1431 install_element(CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1432 install_element(CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1433 install_element(VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1434 install_element(CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1435 install_element(CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1436 install_element(VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1437 install_element(CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1438 install_element(CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1442 route_map_add_hook(zebra_route_map_add
);
1443 route_map_delete_hook(zebra_route_map_delete
);
1444 route_map_event_hook(zebra_route_map_event
);
1446 route_map_match_interface_hook(generic_match_add
);
1447 route_map_no_match_interface_hook(generic_match_delete
);
1449 route_map_match_ip_address_hook(generic_match_add
);
1450 route_map_no_match_ip_address_hook(generic_match_delete
);
1452 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
1453 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
1455 route_map_match_ip_next_hop_hook(generic_match_add
);
1456 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
1458 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
1459 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
1461 route_map_match_tag_hook(generic_match_add
);
1462 route_map_no_match_tag_hook(generic_match_delete
);
1464 route_map_install_match(&route_match_tag_cmd
);
1465 route_map_install_match(&route_match_interface_cmd
);
1466 route_map_install_match(&route_match_ip_next_hop_cmd
);
1467 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
1468 route_map_install_match(&route_match_ip_address_cmd
);
1469 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
1470 route_map_install_match(&route_match_ip_address_prefix_len_cmd
);
1471 route_map_install_match(&route_match_ipv6_address_prefix_len_cmd
);
1472 route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd
);
1473 route_map_install_match(&route_match_source_protocol_cmd
);
1475 route_map_install_set(&route_set_src_cmd
);
1477 install_element(RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1478 install_element(RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1479 install_element(RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1480 install_element(RMAP_NODE
, &match_ipv6_address_prefix_len_cmd
);
1481 install_element(RMAP_NODE
, &no_match_ipv6_address_prefix_len_cmd
);
1482 install_element(RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1483 install_element(RMAP_NODE
, &match_source_protocol_cmd
);
1484 install_element(RMAP_NODE
, &no_match_source_protocol_cmd
);
1486 install_element(RMAP_NODE
, &set_src_cmd
);
1487 install_element(RMAP_NODE
, &no_set_src_cmd
);