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
];
50 struct nexthop
*nexthop
;
52 u_int32_t source_protocol
;
57 static void zebra_route_map_set_delay_timer(u_int32_t value
);
61 /* Add zebra route map rule */
63 zebra_route_match_add(struct vty
*vty
,
64 const char *command
, const char *arg
,
65 route_map_event_t type
)
67 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
70 ret
= route_map_add_match (index
, command
, arg
);
75 case RMAP_RULE_MISSING
:
76 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
78 case RMAP_COMPILE_ERROR
:
79 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
84 if (type
!= RMAP_EVENT_MATCH_ADDED
)
86 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
91 /* Delete zebra route map rule. */
93 zebra_route_match_delete (struct vty
*vty
,
94 const char *command
, const char *arg
,
95 route_map_event_t type
)
97 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
99 char *dep_name
= NULL
;
101 char *rmap_name
= NULL
;
103 if (type
!= RMAP_EVENT_MATCH_DELETED
)
105 /* ignore the mundane, the types without any dependency */
108 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
109 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
113 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
115 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
118 ret
= route_map_delete_match (index
, command
, arg
);
123 case RMAP_RULE_MISSING
:
124 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
126 case RMAP_COMPILE_ERROR
:
127 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
132 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
133 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
136 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
138 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
144 * Match function return 1 if match is success else return 0
146 static route_map_result_t
147 route_match_tag (void *rule
, struct prefix
*prefix
,
148 route_map_object_t type
, void *object
)
151 struct nh_rmap_obj
*nh_data
;
153 if (type
== RMAP_ZEBRA
)
158 if (nh_data
->tag
== *tag
)
164 /* Route map commands for tag matching */
165 static struct route_map_rule_cmd route_match_tag_cmd
=
169 route_map_rule_tag_compile
,
170 route_map_rule_tag_free
,
174 /* `match interface IFNAME' */
175 /* Match function return 1 if match is success else return zero. */
176 static route_map_result_t
177 route_match_interface (void *rule
, struct prefix
*prefix
,
178 route_map_object_t type
, void *object
)
180 struct nh_rmap_obj
*nh_data
;
184 if (type
== RMAP_ZEBRA
)
186 if (strcasecmp(ifname
, "any") == 0)
189 if (!nh_data
|| !nh_data
->nexthop
)
191 ifindex
= ifname2ifindex (ifname
, nh_data
->vrf_id
);
194 if (nh_data
->nexthop
->ifindex
== ifindex
)
200 /* Route map `match interface' match statement. `arg' is IFNAME value */
202 route_match_interface_compile (const char *arg
)
204 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
207 /* Free route map's compiled `match interface' value. */
209 route_match_interface_free (void *rule
)
211 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
214 /* Route map commands for interface matching */
215 struct route_map_rule_cmd route_match_interface_cmd
=
218 route_match_interface
,
219 route_match_interface_compile
,
220 route_match_interface_free
223 DEFUN (match_ip_address_prefix_len
,
224 match_ip_address_prefix_len_cmd
,
225 "match ip address prefix-len (0-32)",
228 "Match prefix length of ip address\n"
229 "Match prefix length of ip address\n"
232 return zebra_route_match_add (vty
, "ip address prefix-len",
233 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
236 DEFUN (no_match_ip_address_prefix_len
,
237 no_match_ip_address_prefix_len_cmd
,
238 "no match ip address prefix-len [(0-32)]",
242 "Match prefix length of ip address\n"
243 "Match prefix length of ip address\n"
246 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
247 return zebra_route_match_delete (vty
,
248 "ip address prefix-len", plen
,
249 RMAP_EVENT_MATCH_DELETED
);
253 DEFUN (match_ip_nexthop_prefix_len
,
254 match_ip_nexthop_prefix_len_cmd
,
255 "match ip next-hop prefix-len (0-32)",
258 "Match prefixlen of nexthop ip address\n"
259 "Match prefixlen of given nexthop\n"
262 return zebra_route_match_add (vty
, "ip next-hop prefix-len",
263 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
266 DEFUN (no_match_ip_nexthop_prefix_len
,
267 no_match_ip_nexthop_prefix_len_cmd
,
268 "no match ip next-hop prefix-len [(0-32)]",
272 "Match prefixlen of nexthop ip address\n"
273 "Match prefix length of nexthop\n"
276 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
277 return zebra_route_match_delete (vty
,
278 "ip next-hop prefix-len", plen
,
279 RMAP_EVENT_MATCH_DELETED
);
283 DEFUN (match_source_protocol
,
284 match_source_protocol_cmd
,
285 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>",
287 "Match protocol via which the route was learnt\n"
294 "Routes from directly connected peer\n"
295 "Routes from system configuration\n"
296 "Routes from kernel\n"
297 "Statically configured routes\n")
299 char *proto
= argv
[2]->text
;
302 i
= proto_name2num(proto
);
305 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
308 return zebra_route_match_add (vty
, "source-protocol", proto
, RMAP_EVENT_MATCH_ADDED
);
311 DEFUN (no_match_source_protocol
,
312 no_match_source_protocol_cmd
,
313 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>]",
316 "No match protocol via which the route was learnt\n"
323 "Routes from directly connected peer\n"
324 "Routes from system configuration\n"
325 "Routes from kernel\n"
326 "Statically configured routes\n")
328 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
329 return zebra_route_match_delete (vty
, "source-protocol", proto
, RMAP_EVENT_MATCH_DELETED
);
336 "set src <A.B.C.D|X:X::X:X>",
338 "src address for route\n"
340 "IPv6 src address\n")
344 struct interface
*pif
= NULL
;
349 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1)
351 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1)
353 vty_out (vty
, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE
);
357 p
.family
= family
= AF_INET6
;
358 p
.u
.prefix6
= src
.ipv6
;
359 p
.prefixlen
= IPV6_MAX_BITLEN
;
363 p
.family
= family
= AF_INET
;
364 p
.u
.prefix4
= src
.ipv4
;
365 p
.prefixlen
= IPV4_MAX_BITLEN
;
368 if (!zebra_check_addr(&p
))
370 vty_out (vty
, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE
);
374 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
)
376 if (family
== AF_INET
)
377 pif
= if_lookup_exact_address ((void *)&src
.ipv4
, AF_INET
,
379 else if (family
== AF_INET6
)
380 pif
= if_lookup_exact_address ((void *)&src
.ipv6
, AF_INET6
,
389 vty_out (vty
, "%% not a local address%s", VTY_NEWLINE
);
393 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
394 return generic_set_add (vty
, index
, "src", argv
[idx_ip
]->arg
);
399 "no set src [<A.B.C.D|X:X::X:X>]",
402 "Source address for route\n"
406 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
407 VTY_DECLVAR_CONTEXT (route_map_index
, index
);
408 return generic_set_delete (vty
, index
, "src", ip
);
411 DEFUN (zebra_route_map_timer
,
412 zebra_route_map_timer_cmd
,
413 "zebra route-map delay-timer (0-600)",
414 "Zebra information\n"
415 "Set route-map parameters\n"
416 "Time to wait before route-map updates are processed\n"
417 "0 means event-driven updates are disabled\n")
420 u_int32_t rmap_delay_timer
;
422 VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer
, argv
[idx_number
]->arg
, 0, 600);
423 zebra_route_map_set_delay_timer(rmap_delay_timer
);
425 return (CMD_SUCCESS
);
428 DEFUN (no_zebra_route_map_timer
,
429 no_zebra_route_map_timer_cmd
,
430 "no zebra route-map delay-timer [(0-600)]",
432 "Zebra information\n"
433 "Set route-map parameters\n"
434 "Reset delay-timer to default value, 30 secs\n"
435 "0 means event-driven updates are disabled\n")
437 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
439 return (CMD_SUCCESS
);
445 "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
447 "Filter routing info exchanged between zebra and protocol\n"
448 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
449 "Specify route-map\n"
452 char *proto
= argv
[2]->text
;
453 char *rmap
= argv
[4]->arg
;
456 if (strcasecmp(proto
, "any") == 0)
459 i
= proto_name2num(proto
);
462 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
465 if (proto_rm
[AFI_IP
][i
])
467 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
470 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
472 proto_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
474 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
475 zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
478 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
482 DEFUN (no_ip_protocol
,
484 "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
487 "Stop filtering routing info between zebra and protocol\n"
488 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
489 "Specify route map\n"
492 char *proto
= argv
[3]->text
;
493 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
496 if (strcasecmp(proto
, "any") == 0)
499 i
= proto_name2num(proto
);
503 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
507 if (!proto_rm
[AFI_IP
][i
])
510 if (!rmap
|| strcmp (rmap
, proto_rm
[AFI_IP
][i
]) == 0)
512 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
513 proto_rm
[AFI_IP
][i
] = NULL
;
515 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
516 zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
518 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
523 DEFUN (show_ip_protocol
,
524 show_ip_protocol_cmd
,
528 "IP protocol filtering status\n")
532 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
533 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
534 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
536 if (proto_rm
[AFI_IP
][i
])
537 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
541 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
543 if (proto_rm
[AFI_IP
][i
])
544 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP
][i
],
547 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
552 DEFUN (ipv6_protocol
,
554 "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
556 "Filter IPv6 routing info exchanged between zebra and protocol\n"
557 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
558 "Specify route map\n"
561 char *proto
= argv
[2]->text
;
562 char *rmap
= argv
[4]->arg
;
565 if (strcasecmp(proto
, "any") == 0)
568 i
= proto_name2num(proto
);
571 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
574 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
)
584 zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
587 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
591 DEFUN (no_ipv6_protocol
,
592 no_ipv6_protocol_cmd
,
593 "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
596 "Stop filtering IPv6 routing info between zebra and protocol\n"
597 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
598 "Specify route map\n"
601 const char *proto
= argv
[3]->text
;
602 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
605 if (strcasecmp(proto
, "any") == 0)
608 i
= proto_name2num(proto
);
611 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
614 if (!proto_rm
[AFI_IP6
][i
])
617 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0)
619 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
620 proto_rm
[AFI_IP6
][i
] = NULL
;
622 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
623 zlog_debug ("%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 %s", VTY_NEWLINE
);
641 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
642 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
644 if (proto_rm
[AFI_IP6
][i
])
645 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
646 proto_rm
[AFI_IP6
][i
],
649 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
651 if (proto_rm
[AFI_IP6
][i
])
652 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP6
][i
],
655 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
660 DEFUN (ip_protocol_nht_rmap
,
661 ip_protocol_nht_rmap_cmd
,
662 "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
664 "Filter Next Hop tracking route resolution\n"
665 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
666 "Specify route map\n"
669 char *proto
= argv
[2]->text
;
670 char *rmap
= argv
[4]->arg
;
673 if (strcasecmp(proto
, "any") == 0)
676 i
= proto_name2num(proto
);
679 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
682 if (nht_rm
[AFI_IP
][i
])
684 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
687 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
690 nht_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
691 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
696 DEFUN (no_ip_protocol_nht_rmap
,
697 no_ip_protocol_nht_rmap_cmd
,
698 "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
701 "Filter Next Hop tracking route resolution\n"
702 FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
703 "Specify route map\n"
707 char *proto
= argv
[3]->text
;
708 char *rmap
= argv_find (argv
, argc
, "ROUTE-MAP", &idx
) ? argv
[idx
]->arg
: NULL
;
710 int i
= strmatch(proto
, "any") ? ZEBRA_ROUTE_MAX
: proto_name2num(proto
);
714 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
718 if (!nht_rm
[AFI_IP
][i
])
721 if (!rmap
|| strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0)
723 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
724 nht_rm
[AFI_IP
][i
] = NULL
;
725 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
730 DEFUN (show_ip_protocol_nht
,
731 show_ip_protocol_nht_cmd
,
732 "show ip nht route-map",
735 "IP nexthop tracking table\n"
736 "IP Next Hop tracking filtering status\n")
740 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
741 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
742 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
744 if (nht_rm
[AFI_IP
][i
])
745 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
749 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
751 if (nht_rm
[AFI_IP
][i
])
752 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP
][i
],
755 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
760 DEFUN (ipv6_protocol_nht_rmap
,
761 ipv6_protocol_nht_rmap_cmd
,
762 "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" route-map ROUTE-MAP",
764 "Filter Next Hop tracking route resolution\n"
765 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
766 "Specify route map\n"
769 char *proto
= argv
[2]->text
;
770 char *rmap
= argv
[4]->arg
;
773 if (strcasecmp(proto
, "any") == 0)
776 i
= proto_name2num(proto
);
779 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
782 if (nht_rm
[AFI_IP6
][i
])
783 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
784 nht_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
785 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
790 DEFUN (no_ipv6_protocol_nht_rmap
,
791 no_ipv6_protocol_nht_rmap_cmd
,
792 "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
" [route-map ROUTE-MAP]",
795 "Filter Next Hop tracking route resolution\n"
796 FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
797 "Specify route map\n"
800 char *proto
= argv
[3]->text
;
801 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
804 if (strcasecmp(proto
, "any") == 0)
807 i
= proto_name2num(proto
);
810 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
814 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
]))
816 vty_out (vty
, "invalid route-map \"%s\"%s", rmap
, VTY_NEWLINE
);
820 if (nht_rm
[AFI_IP6
][i
])
822 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
823 nht_rm
[AFI_IP6
][i
] = NULL
;
826 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
831 DEFUN (show_ipv6_protocol_nht
,
832 show_ipv6_protocol_nht_cmd
,
833 "show ipv6 nht route-map",
836 "Next Hop filtering status\n"
841 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
842 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
843 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
845 if (nht_rm
[AFI_IP6
][i
])
846 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
850 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
852 if (nht_rm
[AFI_IP
][i
])
853 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP6
][i
],
856 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
861 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
863 /* `match ip next-hop IP_ACCESS_LIST' */
865 /* Match function return 1 if match is success else return zero. */
866 static route_map_result_t
867 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
868 route_map_object_t type
, void *object
)
870 struct access_list
*alist
;
871 struct nh_rmap_obj
*nh_data
;
872 struct prefix_ipv4 p
;
874 if (type
== RMAP_ZEBRA
)
878 return RMAP_DENYMATCH
;
880 switch (nh_data
->nexthop
->type
) {
881 case NEXTHOP_TYPE_IFINDEX
:
882 /* Interface routes can't match ip next-hop */
884 case NEXTHOP_TYPE_IPV4_IFINDEX
:
885 case NEXTHOP_TYPE_IPV4
:
887 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
888 p
.prefixlen
= IPV4_MAX_BITLEN
;
893 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
897 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
898 RMAP_NOMATCH
: RMAP_MATCH
);
903 /* Route map `ip next-hop' match statement. `arg' should be
906 route_match_ip_next_hop_compile (const char *arg
)
908 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
911 /* Free route map's compiled `. */
913 route_match_ip_next_hop_free (void *rule
)
915 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
918 /* Route map commands for ip next-hop matching. */
919 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
922 route_match_ip_next_hop
,
923 route_match_ip_next_hop_compile
,
924 route_match_ip_next_hop_free
927 /* `match ip next-hop prefix-list PREFIX_LIST' */
929 static route_map_result_t
930 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
931 route_map_object_t type
, void *object
)
933 struct prefix_list
*plist
;
934 struct nh_rmap_obj
*nh_data
;
935 struct prefix_ipv4 p
;
937 if (type
== RMAP_ZEBRA
)
939 nh_data
= (struct nh_rmap_obj
*)object
;
941 return RMAP_DENYMATCH
;
943 switch (nh_data
->nexthop
->type
) {
944 case NEXTHOP_TYPE_IFINDEX
:
945 /* Interface routes can't match ip next-hop */
947 case NEXTHOP_TYPE_IPV4_IFINDEX
:
948 case NEXTHOP_TYPE_IPV4
:
950 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
951 p
.prefixlen
= IPV4_MAX_BITLEN
;
956 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
960 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
961 RMAP_NOMATCH
: RMAP_MATCH
);
967 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
969 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
973 route_match_ip_next_hop_prefix_list_free (void *rule
)
975 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
978 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
980 "ip next-hop prefix-list",
981 route_match_ip_next_hop_prefix_list
,
982 route_match_ip_next_hop_prefix_list_compile
,
983 route_match_ip_next_hop_prefix_list_free
986 /* `match ip address IP_ACCESS_LIST' */
988 /* Match function should return 1 if match is success else return
990 static route_map_result_t
991 route_match_ip_address (void *rule
, struct prefix
*prefix
,
992 route_map_object_t type
, void *object
)
994 struct access_list
*alist
;
996 if (type
== RMAP_ZEBRA
)
998 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
1000 return RMAP_NOMATCH
;
1002 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
1003 RMAP_NOMATCH
: RMAP_MATCH
);
1005 return RMAP_NOMATCH
;
1008 /* Route map `ip address' match statement. `arg' should be
1009 access-list name. */
1011 route_match_ip_address_compile (const char *arg
)
1013 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1016 /* Free route map's compiled `ip address' value. */
1018 route_match_ip_address_free (void *rule
)
1020 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1023 /* Route map commands for ip address matching. */
1024 static struct route_map_rule_cmd route_match_ip_address_cmd
=
1027 route_match_ip_address
,
1028 route_match_ip_address_compile
,
1029 route_match_ip_address_free
1032 /* `match ip address prefix-list PREFIX_LIST' */
1034 static route_map_result_t
1035 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
1036 route_map_object_t type
, void *object
)
1038 struct prefix_list
*plist
;
1040 if (type
== RMAP_ZEBRA
)
1042 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
1044 return RMAP_NOMATCH
;
1046 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
1047 RMAP_NOMATCH
: RMAP_MATCH
);
1049 return RMAP_NOMATCH
;
1053 route_match_ip_address_prefix_list_compile (const char *arg
)
1055 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1059 route_match_ip_address_prefix_list_free (void *rule
)
1061 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1064 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
1066 "ip address prefix-list",
1067 route_match_ip_address_prefix_list
,
1068 route_match_ip_address_prefix_list_compile
,
1069 route_match_ip_address_prefix_list_free
1073 /* `match ip address prefix-len PREFIXLEN' */
1075 static route_map_result_t
1076 route_match_ip_address_prefix_len (void *rule
, struct prefix
*prefix
,
1077 route_map_object_t type
, void *object
)
1079 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1081 if (type
== RMAP_ZEBRA
)
1083 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1085 return RMAP_NOMATCH
;
1089 route_match_ip_address_prefix_len_compile (const char *arg
)
1091 u_int32_t
*prefix_len
;
1092 char *endptr
= NULL
;
1093 unsigned long tmpval
;
1095 /* prefix len value shoud be integer. */
1096 if (! all_digit (arg
))
1100 tmpval
= strtoul (arg
, &endptr
, 10);
1101 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1104 prefix_len
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1109 *prefix_len
= tmpval
;
1114 route_match_ip_address_prefix_len_free (void *rule
)
1116 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1119 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
=
1121 "ip address prefix-len",
1122 route_match_ip_address_prefix_len
,
1123 route_match_ip_address_prefix_len_compile
,
1124 route_match_ip_address_prefix_len_free
1128 /* `match ip nexthop prefix-len PREFIXLEN' */
1130 static route_map_result_t
1131 route_match_ip_nexthop_prefix_len (void *rule
, struct prefix
*prefix
,
1132 route_map_object_t type
, void *object
)
1134 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1135 struct nh_rmap_obj
*nh_data
;
1136 struct prefix_ipv4 p
;
1138 if (type
== RMAP_ZEBRA
)
1140 nh_data
= (struct nh_rmap_obj
*)object
;
1141 if (!nh_data
|| !nh_data
->nexthop
)
1142 return RMAP_DENYMATCH
;
1144 switch (nh_data
->nexthop
->type
) {
1145 case NEXTHOP_TYPE_IFINDEX
:
1146 /* Interface routes can't match ip next-hop */
1147 return RMAP_NOMATCH
;
1148 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1149 case NEXTHOP_TYPE_IPV4
:
1151 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1152 p
.prefixlen
= IPV4_MAX_BITLEN
;
1155 return RMAP_NOMATCH
;
1157 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1159 return RMAP_NOMATCH
;
1162 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
=
1164 "ip next-hop prefix-len",
1165 route_match_ip_nexthop_prefix_len
,
1166 route_match_ip_address_prefix_len_compile
, /* reuse */
1167 route_match_ip_address_prefix_len_free
/* reuse */
1170 /* `match source-protocol PROTOCOL' */
1172 static route_map_result_t
1173 route_match_source_protocol (void *rule
, struct prefix
*prefix
,
1174 route_map_object_t type
, void *object
)
1176 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1177 struct nh_rmap_obj
*nh_data
;
1179 if (type
== RMAP_ZEBRA
)
1181 nh_data
= (struct nh_rmap_obj
*)object
;
1183 return RMAP_DENYMATCH
;
1185 return ((nh_data
->source_protocol
== *rib_type
)
1186 ? RMAP_MATCH
: RMAP_NOMATCH
);
1188 return RMAP_NOMATCH
;
1192 route_match_source_protocol_compile (const char *arg
)
1194 u_int32_t
*rib_type
;
1197 i
= proto_name2num(arg
);
1198 rib_type
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1206 route_match_source_protocol_free (void *rule
)
1208 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1211 static struct route_map_rule_cmd route_match_source_protocol_cmd
=
1214 route_match_source_protocol
,
1215 route_match_source_protocol_compile
,
1216 route_match_source_protocol_free
1219 /* `set src A.B.C.D' */
1222 static route_map_result_t
1223 route_set_src (void *rule
, struct prefix
*prefix
,
1224 route_map_object_t type
, void *object
)
1226 struct nh_rmap_obj
*nh_data
;
1228 if (type
== RMAP_ZEBRA
)
1230 nh_data
= (struct nh_rmap_obj
*)object
;
1231 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1236 /* set src compilation. */
1238 route_set_src_compile (const char *arg
)
1240 union g_addr src
, *psrc
;
1242 if ((inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1) ||
1243 (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)))
1245 psrc
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union g_addr
));
1252 /* Free route map's compiled `set src' value. */
1254 route_set_src_free (void *rule
)
1256 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1259 /* Set src rule structure. */
1260 static struct route_map_rule_cmd route_set_src_cmd
=
1264 route_set_src_compile
,
1269 zebra_route_map_update_timer (struct thread
*thread
)
1271 zebra_t_rmap_update
= NULL
;
1273 if (IS_ZEBRA_DEBUG_EVENT
)
1274 zlog_debug("Event driven route-map update triggered");
1276 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1277 zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
1280 zebra_import_table_rm_update ();
1281 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1282 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1283 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1289 zebra_route_map_set_delay_timer(u_int32_t value
)
1291 zebra_rmap_update_timer
= value
;
1292 if (!value
&& zebra_t_rmap_update
)
1294 /* Event driven route map updates is being disabled */
1295 /* But there's a pending timer. Fire it off now */
1296 thread_cancel(zebra_t_rmap_update
);
1297 zebra_route_map_update_timer(zebra_t_rmap_update
);
1302 zebra_route_map_write_delay_timer (struct vty
*vty
)
1304 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1305 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1311 zebra_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1312 struct nexthop
*nexthop
, vrf_id_t vrf_id
, route_tag_t tag
)
1314 struct route_map
*rmap
= NULL
;
1315 route_map_result_t ret
= RMAP_MATCH
;
1316 struct nh_rmap_obj nh_obj
;
1318 nh_obj
.nexthop
= nexthop
;
1319 nh_obj
.vrf_id
= vrf_id
;
1320 nh_obj
.source_protocol
= rib_type
;
1324 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1325 rmap
= route_map_lookup_by_name (proto_rm
[family
][rib_type
]);
1326 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1327 rmap
= route_map_lookup_by_name (proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1329 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1336 zebra_get_import_table_route_map (afi_t afi
, uint32_t table
)
1338 return zebra_import_table_routemap
[afi
][table
];
1342 zebra_add_import_table_route_map (afi_t afi
, const char *rmap_name
, uint32_t table
)
1344 zebra_import_table_routemap
[afi
][table
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1348 zebra_del_import_table_route_map (afi_t afi
, uint32_t table
)
1350 XFREE (MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1354 zebra_import_table_route_map_check (int family
, int re_type
, struct prefix
*p
,
1355 struct nexthop
*nexthop
, vrf_id_t vrf_id
, route_tag_t tag
, const char *rmap_name
)
1357 struct route_map
*rmap
= NULL
;
1358 route_map_result_t ret
= RMAP_DENYMATCH
;
1359 struct nh_rmap_obj nh_obj
;
1361 nh_obj
.nexthop
= nexthop
;
1362 nh_obj
.vrf_id
= vrf_id
;
1363 nh_obj
.source_protocol
= re_type
;
1367 if (re_type
>= 0 && re_type
< ZEBRA_ROUTE_MAX
)
1368 rmap
= route_map_lookup_by_name (rmap_name
);
1370 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1377 zebra_nht_route_map_check (int family
, int client_proto
, struct prefix
*p
,
1378 struct route_entry
* re
, struct nexthop
*nexthop
)
1380 struct route_map
*rmap
= NULL
;
1381 route_map_result_t ret
= RMAP_MATCH
;
1382 struct nh_rmap_obj nh_obj
;
1384 nh_obj
.nexthop
= nexthop
;
1385 nh_obj
.vrf_id
= re
->vrf_id
;
1386 nh_obj
.source_protocol
= re
->type
;
1387 nh_obj
.metric
= re
->metric
;
1388 nh_obj
.tag
= re
->tag
;
1390 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1391 rmap
= route_map_lookup_by_name (nht_rm
[family
][client_proto
]);
1392 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1393 rmap
= route_map_lookup_by_name (nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1395 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1402 zebra_route_map_mark_update (const char *rmap_name
)
1404 /* rmap_update_timer of 0 means don't do route updates */
1405 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
) {
1406 zebra_t_rmap_update
= NULL
;
1407 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
, NULL
, zebra_rmap_update_timer
,
1408 &zebra_t_rmap_update
);
1413 zebra_route_map_add (const char *rmap_name
)
1415 zebra_route_map_mark_update(rmap_name
);
1416 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1420 zebra_route_map_delete (const char *rmap_name
)
1422 zebra_route_map_mark_update(rmap_name
);
1423 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1427 zebra_route_map_event (route_map_event_t event
, const char *rmap_name
)
1429 zebra_route_map_mark_update(rmap_name
);
1430 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1433 /* ip protocol configuration write function */
1435 zebra_routemap_config_write_protocol (struct vty
*vty
)
1439 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1441 if (proto_rm
[AFI_IP
][i
])
1442 vty_out (vty
, "ip protocol %s route-map %s%s", zebra_route_string(i
),
1443 proto_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1445 if (proto_rm
[AFI_IP6
][i
])
1446 vty_out (vty
, "ipv6 protocol %s route-map %s%s", zebra_route_string(i
),
1447 proto_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1449 if (nht_rm
[AFI_IP
][i
])
1450 vty_out (vty
, "ip nht %s route-map %s%s", zebra_route_string(i
),
1451 nht_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1453 if (nht_rm
[AFI_IP6
][i
])
1454 vty_out (vty
, "ipv6 nht %s route-map %s%s", zebra_route_string(i
),
1455 nht_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1458 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1459 vty_out (vty
, "ip protocol %s route-map %s%s", "any",
1460 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1462 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1463 vty_out (vty
, "ipv6 protocol %s route-map %s%s", "any",
1464 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1466 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1467 vty_out (vty
, "ip nht %s route-map %s%s", "any",
1468 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1470 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1471 vty_out (vty
, "ipv6 nht %s route-map %s%s", "any",
1472 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1474 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1475 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1480 zebra_route_map_init ()
1482 install_element (CONFIG_NODE
, &ip_protocol_cmd
);
1483 install_element (CONFIG_NODE
, &no_ip_protocol_cmd
);
1484 install_element (VIEW_NODE
, &show_ip_protocol_cmd
);
1485 install_element (CONFIG_NODE
, &ipv6_protocol_cmd
);
1486 install_element (CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1487 install_element (VIEW_NODE
, &show_ipv6_protocol_cmd
);
1488 install_element (CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1489 install_element (CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1490 install_element (VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1491 install_element (CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1492 install_element (CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1493 install_element (VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1494 install_element (CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1495 install_element (CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1499 route_map_add_hook (zebra_route_map_add
);
1500 route_map_delete_hook (zebra_route_map_delete
);
1501 route_map_event_hook (zebra_route_map_event
);
1503 route_map_match_interface_hook (generic_match_add
);
1504 route_map_no_match_interface_hook (generic_match_delete
);
1506 route_map_match_ip_address_hook (generic_match_add
);
1507 route_map_no_match_ip_address_hook (generic_match_delete
);
1509 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
1510 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
1512 route_map_match_ip_next_hop_hook (generic_match_add
);
1513 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
1515 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
1516 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
1518 route_map_match_tag_hook (generic_match_add
);
1519 route_map_no_match_tag_hook (generic_match_delete
);
1521 route_map_install_match (&route_match_tag_cmd
);
1522 route_map_install_match (&route_match_interface_cmd
);
1523 route_map_install_match (&route_match_ip_next_hop_cmd
);
1524 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
1525 route_map_install_match (&route_match_ip_address_cmd
);
1526 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
1527 route_map_install_match (&route_match_ip_address_prefix_len_cmd
);
1528 route_map_install_match (&route_match_ip_nexthop_prefix_len_cmd
);
1529 route_map_install_match (&route_match_source_protocol_cmd
);
1531 route_map_install_set (&route_set_src_cmd
);
1533 install_element (RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1534 install_element (RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1535 install_element (RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1536 install_element (RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1537 install_element (RMAP_NODE
, &match_source_protocol_cmd
);
1538 install_element (RMAP_NODE
, &no_match_source_protocol_cmd
);
1540 install_element (RMAP_NODE
, &set_src_cmd
);
1541 install_element (RMAP_NODE
, &no_set_src_cmd
);