2 * Copyright (C) 2006 IBM Corporation
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 #include "zebra_memory.h"
36 #include "zebra/zserv.h"
37 #include "zebra/redistribute.h"
38 #include "zebra/debug.h"
39 #include "zebra/zebra_rnh.h"
40 #include "zebra/zebra_routemap.h"
42 static u_int32_t zebra_rmap_update_timer
= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
;
43 static struct thread
*zebra_t_rmap_update
= NULL
;
44 char *proto_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+1]; /* "any" == ZEBRA_ROUTE_MAX */
45 /* NH Tracking route map */
46 char *nht_rm
[AFI_MAX
][ZEBRA_ROUTE_MAX
+1]; /* "any" == ZEBRA_ROUTE_MAX */
47 char *zebra_import_table_routemap
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
51 struct nexthop
*nexthop
;
53 u_int32_t source_protocol
;
58 static void zebra_route_map_set_delay_timer(u_int32_t value
);
62 /* Add zebra route map rule */
64 zebra_route_match_add(struct vty
*vty
, struct route_map_index
*index
,
65 const char *command
, const char *arg
,
66 route_map_event_t type
)
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
, struct route_map_index
*index
,
94 const char *command
, const char *arg
,
95 route_map_event_t type
)
98 char *dep_name
= NULL
;
100 char *rmap_name
= NULL
;
102 if (type
!= RMAP_EVENT_MATCH_DELETED
)
104 /* ignore the mundane, the types without any dependency */
107 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
108 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
112 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
114 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
117 ret
= route_map_delete_match (index
, command
, arg
);
122 case RMAP_RULE_MISSING
:
123 vty_out (vty
, "%% Zebra Can't find rule.%s", VTY_NEWLINE
);
125 case RMAP_COMPILE_ERROR
:
126 vty_out (vty
, "%% Zebra Argument is malformed.%s", VTY_NEWLINE
);
131 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
132 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
135 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
137 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
143 * Match function return 1 if match is success else return 0
145 static route_map_result_t
146 route_match_tag (void *rule
, struct prefix
*prefix
,
147 route_map_object_t type
, void *object
)
150 struct nh_rmap_obj
*nh_data
;
152 if (type
== RMAP_ZEBRA
)
157 if (nh_data
->tag
== *tag
)
163 /* Route map 'match tag' match statement. 'arg' is TAG value */
165 route_match_tag_compile (const char *arg
)
170 /* tag value shoud be integer. */
171 if (! all_digit (arg
))
178 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
188 /* Free route map's compiled 'match tag' value. */
190 route_match_tag_free (void *rule
)
192 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
195 /* Route map commands for tag matching */
196 struct route_map_rule_cmd route_match_tag_cmd
=
200 route_match_tag_compile
,
205 /* `match interface IFNAME' */
206 /* Match function return 1 if match is success else return zero. */
207 static route_map_result_t
208 route_match_interface (void *rule
, struct prefix
*prefix
,
209 route_map_object_t type
, void *object
)
211 struct nh_rmap_obj
*nh_data
;
215 if (type
== RMAP_ZEBRA
)
217 if (strcasecmp(ifname
, "any") == 0)
220 if (!nh_data
|| !nh_data
->nexthop
)
222 ifindex
= ifname2ifindex_vrf (ifname
, nh_data
->vrf_id
);
225 if (nh_data
->nexthop
->ifindex
== ifindex
)
231 /* Route map `match interface' match statement. `arg' is IFNAME value */
233 route_match_interface_compile (const char *arg
)
235 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
238 /* Free route map's compiled `match interface' value. */
240 route_match_interface_free (void *rule
)
242 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
245 /* Route map commands for interface matching */
246 struct route_map_rule_cmd route_match_interface_cmd
=
249 route_match_interface
,
250 route_match_interface_compile
,
251 route_match_interface_free
254 DEFUN (match_ip_address_prefix_len
,
255 match_ip_address_prefix_len_cmd
,
256 "match ip address prefix-len (0-32)",
259 "Match prefix length of ip address\n"
260 "Match prefix length of ip address\n"
263 return zebra_route_match_add (vty
, vty
->index
, "ip address prefix-len",
264 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
267 DEFUN (no_match_ip_address_prefix_len
,
268 no_match_ip_address_prefix_len_cmd
,
269 "no match ip address prefix-len [(0-32)]",
273 "Match prefixlen of ip address of route\n"
276 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
277 return zebra_route_match_delete (vty
, vty
->index
,
278 "ip address prefix-len", plen
,
279 RMAP_EVENT_MATCH_DELETED
);
283 DEFUN (match_ip_nexthop_prefix_len
,
284 match_ip_nexthop_prefix_len_cmd
,
285 "match ip next-hop prefix-len (0-32)",
288 "Match prefixlen of nexthop ip address\n"
289 "Match prefixlen of given nexthop\n"
292 return zebra_route_match_add (vty
, vty
->index
, "ip next-hop prefix-len",
293 argv
[4]->arg
, RMAP_EVENT_MATCH_ADDED
);
296 DEFUN (no_match_ip_nexthop_prefix_len
,
297 no_match_ip_nexthop_prefix_len_cmd
,
298 "no match ip next-hop prefix-len [(0-32)]",
302 "Match prefixlen of nexthop ip address\n"
303 "Match prefix length of nexthop\n"
306 char *plen
= (argc
== 6) ? argv
[5]->arg
: NULL
;
307 return zebra_route_match_delete (vty
, vty
->index
,
308 "ip next-hop prefix-len", plen
,
309 RMAP_EVENT_MATCH_DELETED
);
313 DEFUN (match_source_protocol
,
314 match_source_protocol_cmd
,
315 "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>",
317 "Match protocol via which the route was learnt\n")
319 char *proto
= argv
[2]->text
;
322 i
= proto_name2num(proto
);
325 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
328 return zebra_route_match_add (vty
, vty
->index
, "source-protocol", proto
, RMAP_EVENT_MATCH_ADDED
);
331 DEFUN (no_match_source_protocol
,
332 no_match_source_protocol_cmd
,
333 "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static>]",
336 "No match protocol via which the route was learnt\n"
339 char *proto
= (argc
== 4) ? argv
[3]->text
: NULL
;
340 return zebra_route_match_delete (vty
, vty
->index
, "source-protocol", proto
, RMAP_EVENT_MATCH_DELETED
);
347 "set src <A.B.C.D|X:X::X:X>",
349 "src address for route\n"
354 struct interface
*pif
= NULL
;
359 if (inet_pton(AF_INET
, argv
[idx_ip
]->arg
, &src
.ipv4
) != 1)
361 if (inet_pton(AF_INET6
, argv
[idx_ip
]->arg
, &src
.ipv6
) != 1)
363 vty_out (vty
, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE
);
367 p
.family
= family
= AF_INET6
;
368 p
.u
.prefix6
= src
.ipv6
;
369 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
))
380 vty_out (vty
, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE
);
384 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
386 if (family
== AF_INET
)
387 pif
= if_lookup_exact_address_vrf ((void *)&src
.ipv4
, AF_INET
,
389 else if (family
== AF_INET6
)
390 pif
= if_lookup_exact_address_vrf ((void *)&src
.ipv6
, AF_INET6
,
399 vty_out (vty
, "%% not a local address%s", VTY_NEWLINE
);
402 return generic_set_add (vty
, vty
->index
, "src", argv
[idx_ip
]->arg
);
407 "no set src [<A.B.C.D|X:X::X:X>]",
410 "Source address for route\n")
412 char *ip
= (argc
== 4) ? argv
[3]->arg
: NULL
;
413 return generic_set_delete (vty
, vty
->index
, "src", ip
);
416 DEFUN (zebra_route_map_timer
,
417 zebra_route_map_timer_cmd
,
418 "zebra route-map delay-timer (0-600)",
419 "Time to wait before route-map updates are processed\n"
420 "0 means event-driven updates are disabled\n")
423 u_int32_t rmap_delay_timer
;
425 VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer
, argv
[idx_number
]->arg
, 0, 600);
426 zebra_route_map_set_delay_timer(rmap_delay_timer
);
428 return (CMD_SUCCESS
);
431 DEFUN (no_zebra_route_map_timer
,
432 no_zebra_route_map_timer_cmd
,
433 "no zebra route-map delay-timer [(0-600)]",
435 "Time to wait before route-map updates are processed\n"
436 "Reset delay-timer to default value, 30 secs\n"
437 "0 means event-driven updates are disabled\n")
440 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
);
442 return (CMD_SUCCESS
);
448 "ip protocol <kernel|connected|static|rip|ospf|isis|bgp|pim|table|any> route-map ROUTE-MAP",
450 "Filter routing info exchanged between zebra and protocol\n"
451 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
452 "Specify route-map\n"
455 char *proto
= argv
[2]->text
;
456 char *rmap
= argv
[4]->arg
;
459 if (strcasecmp(proto
, "any") == 0)
462 i
= proto_name2num(proto
);
465 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
468 if (proto_rm
[AFI_IP
][i
])
470 if (strcmp(proto_rm
[AFI_IP
][i
], rmap
) == 0)
473 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
475 proto_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
477 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
478 zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
481 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
485 DEFUN (no_ip_protocol
,
487 "no ip protocol <kernel|connected|static|rip|ospf|isis|bgp|pim|table|any> [route-map ROUTE-MAP]",
490 "Stop filtering routing info between zebra and protocol\n"
491 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
492 "Specify route map\n"
495 char *proto
= argv
[3]->text
;
496 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
499 if (strcasecmp(proto
, "any") == 0)
502 i
= proto_name2num(proto
);
506 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
510 if (!proto_rm
[AFI_IP
][i
])
513 if (!rmap
|| strcmp (rmap
, proto_rm
[AFI_IP
][i
]) == 0)
515 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP
][i
]);
516 proto_rm
[AFI_IP
][i
] = NULL
;
518 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
519 zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
521 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
527 DEFUN (show_ip_protocol
,
528 show_ip_protocol_cmd
,
532 "IP protocol filtering status\n")
536 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
537 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
538 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
540 if (proto_rm
[AFI_IP
][i
])
541 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
545 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
547 if (proto_rm
[AFI_IP
][i
])
548 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP
][i
],
551 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
556 DEFUN (ipv6_protocol
,
558 "ipv6 protocol <kernel|connected|static|ripng|ospf6|isis|bgp|table|any> route-map ROUTE-MAP",
560 "Filter IPv6 routing info exchanged between zebra and protocol\n"
561 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
562 "Specify route map\n"
565 char *proto
= argv
[2]->text
;
566 char *rmap
= argv
[4]->arg
;
569 if (strcasecmp(proto
, "any") == 0)
572 i
= proto_name2num(proto
);
575 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
578 if (proto_rm
[AFI_IP6
][i
])
580 if (strcmp(proto_rm
[AFI_IP6
][i
], rmap
) == 0)
583 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
585 proto_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
587 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
588 zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
591 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
595 DEFUN (no_ipv6_protocol
,
596 no_ipv6_protocol_cmd
,
597 "no ipv6 protocol <kernel|connected|static|ripng|ospf6|isis|bgp|table|any> [route-map ROUTE-MAP]",
600 "Stop filtering IPv6 routing info between zebra and protocol\n"
601 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
602 "Specify route map\n"
605 const char *proto
= argv
[3]->text
;
606 const char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
609 if (strcasecmp(proto
, "any") == 0)
612 i
= proto_name2num(proto
);
615 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
618 if (!proto_rm
[AFI_IP6
][i
])
621 if (!rmap
|| strcmp(rmap
, proto_rm
[AFI_IP6
][i
]) == 0)
623 XFREE (MTYPE_ROUTE_MAP_NAME
, proto_rm
[AFI_IP6
][i
]);
624 proto_rm
[AFI_IP6
][i
] = NULL
;
626 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
627 zlog_debug ("%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
630 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
636 DEFUN (show_ipv6_protocol
,
637 show_ipv6_protocol_cmd
,
638 "show ipv6 protocol",
641 "IPv6 protocol filtering status\n")
645 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
646 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
647 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
649 if (proto_rm
[AFI_IP6
][i
])
650 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
651 proto_rm
[AFI_IP6
][i
],
654 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
656 if (proto_rm
[AFI_IP6
][i
])
657 vty_out (vty
, "%-10s : %-10s%s", "any", proto_rm
[AFI_IP6
][i
],
660 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
665 DEFUN (ip_protocol_nht_rmap
,
666 ip_protocol_nht_rmap_cmd
,
667 "ip nht <kernel|connected|static|rip|ospf|isis|bgp|pim|table|any> route-map ROUTE-MAP",
669 "Filter Next Hop tracking route resolution\n"
670 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
671 "Specify route map\n"
674 char *proto
= argv
[2]->text
;
675 char *rmap
= argv
[4]->arg
;
678 if (strcasecmp(proto
, "any") == 0)
681 i
= proto_name2num(proto
);
684 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
687 if (nht_rm
[AFI_IP
][i
])
689 if (strcmp(nht_rm
[AFI_IP
][i
], rmap
) == 0)
692 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
695 nht_rm
[AFI_IP
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
696 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
701 DEFUN (no_ip_protocol_nht_rmap
,
702 no_ip_protocol_nht_rmap_cmd
,
703 "no ip nht <kernel|connected|static|rip|ospf|isis|bgp|pim|table|any> [route-map ROUTE-MAP]",
706 "Filter Next Hop tracking route resolution\n"
707 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
708 "Specify route map\n"
711 char *proto
= argv
[3]->text
;
712 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
715 if (strcasecmp(proto
, "any") == 0)
718 i
= proto_name2num(proto
);
721 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
724 if (!nht_rm
[AFI_IP
][i
])
727 if (!rmap
&& strcmp(rmap
, nht_rm
[AFI_IP
][i
]) == 0)
729 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP
][i
]);
730 nht_rm
[AFI_IP
][i
] = NULL
;
731 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
737 DEFUN (show_ip_protocol_nht
,
738 show_ip_protocol_nht_cmd
,
739 "show ip nht route-map",
742 "IP Next Hop tracking filtering status\n")
746 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
747 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
748 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
750 if (nht_rm
[AFI_IP
][i
])
751 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
755 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
757 if (nht_rm
[AFI_IP
][i
])
758 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP
][i
],
761 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
766 DEFUN (ipv6_protocol_nht_rmap
,
767 ipv6_protocol_nht_rmap_cmd
,
768 "ipv6 nht <kernel|connected|static|ripng|ospf6|isis|bgp|table|any> route-map ROUTE-MAP",
770 "Filter Next Hop tracking route resolution\n"
771 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
772 "Specify route map\n"
775 char *proto
= argv
[2]->text
;
776 char *rmap
= argv
[4]->arg
;
779 if (strcasecmp(proto
, "any") == 0)
782 i
= proto_name2num(proto
);
785 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
788 if (nht_rm
[AFI_IP6
][i
])
789 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
790 nht_rm
[AFI_IP6
][i
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap
);
791 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
796 DEFUN (no_ipv6_protocol_nht_rmap
,
797 no_ipv6_protocol_nht_rmap_cmd
,
798 "no ipv6 nht <kernel|connected|static|ripng|ospf6|isis|bgp|table|any> [route-map ROUTE-MAP]",
801 "Filter Next Hop tracking route resolution\n"
802 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
803 "Specify route map\n"
806 char *proto
= argv
[3]->text
;
807 char *rmap
= (argc
== 6) ? argv
[5]->arg
: NULL
;
810 if (strcasecmp(proto
, "any") == 0)
813 i
= proto_name2num(proto
);
816 vty_out (vty
, "invalid protocol name \"%s\"%s", proto
, VTY_NEWLINE
);
820 if (nht_rm
[AFI_IP6
][i
] && rmap
&& strcmp(rmap
, nht_rm
[AFI_IP6
][i
]))
822 vty_out (vty
, "invalid route-map \"%s\"%s", rmap
, VTY_NEWLINE
);
826 if (nht_rm
[AFI_IP6
][i
])
828 XFREE (MTYPE_ROUTE_MAP_NAME
, nht_rm
[AFI_IP6
][i
]);
829 nht_rm
[AFI_IP6
][i
] = NULL
;
832 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
838 DEFUN (show_ipv6_protocol_nht
,
839 show_ipv6_protocol_nht_cmd
,
840 "show ipv6 nht route-map",
843 "IPv6 protocol Next Hop filtering status\n")
847 vty_out(vty
, "Protocol : route-map %s", VTY_NEWLINE
);
848 vty_out(vty
, "------------------------%s", VTY_NEWLINE
);
849 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
851 if (nht_rm
[AFI_IP6
][i
])
852 vty_out (vty
, "%-10s : %-10s%s", zebra_route_string(i
),
856 vty_out (vty
, "%-10s : none%s", zebra_route_string(i
), VTY_NEWLINE
);
858 if (nht_rm
[AFI_IP
][i
])
859 vty_out (vty
, "%-10s : %-10s%s", "any", nht_rm
[AFI_IP6
][i
],
862 vty_out (vty
, "%-10s : none%s", "any", VTY_NEWLINE
);
867 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
869 /* `match ip next-hop IP_ACCESS_LIST' */
871 /* Match function return 1 if match is success else return zero. */
872 static route_map_result_t
873 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
874 route_map_object_t type
, void *object
)
876 struct access_list
*alist
;
877 struct nh_rmap_obj
*nh_data
;
878 struct prefix_ipv4 p
;
880 if (type
== RMAP_ZEBRA
)
884 return RMAP_DENYMATCH
;
886 switch (nh_data
->nexthop
->type
) {
887 case NEXTHOP_TYPE_IFINDEX
:
888 /* Interface routes can't match ip next-hop */
890 case NEXTHOP_TYPE_IPV4_IFINDEX
:
891 case NEXTHOP_TYPE_IPV4
:
893 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
894 p
.prefixlen
= IPV4_MAX_BITLEN
;
899 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
903 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
904 RMAP_NOMATCH
: RMAP_MATCH
);
909 /* Route map `ip next-hop' match statement. `arg' should be
912 route_match_ip_next_hop_compile (const char *arg
)
914 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
917 /* Free route map's compiled `. */
919 route_match_ip_next_hop_free (void *rule
)
921 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
924 /* Route map commands for ip next-hop matching. */
925 static struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
928 route_match_ip_next_hop
,
929 route_match_ip_next_hop_compile
,
930 route_match_ip_next_hop_free
933 /* `match ip next-hop prefix-list PREFIX_LIST' */
935 static route_map_result_t
936 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
937 route_map_object_t type
, void *object
)
939 struct prefix_list
*plist
;
940 struct nh_rmap_obj
*nh_data
;
941 struct prefix_ipv4 p
;
943 if (type
== RMAP_ZEBRA
)
945 nh_data
= (struct nh_rmap_obj
*)object
;
947 return RMAP_DENYMATCH
;
949 switch (nh_data
->nexthop
->type
) {
950 case NEXTHOP_TYPE_IFINDEX
:
951 /* Interface routes can't match ip next-hop */
953 case NEXTHOP_TYPE_IPV4_IFINDEX
:
954 case NEXTHOP_TYPE_IPV4
:
956 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
957 p
.prefixlen
= IPV4_MAX_BITLEN
;
962 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
966 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
967 RMAP_NOMATCH
: RMAP_MATCH
);
973 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
975 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
979 route_match_ip_next_hop_prefix_list_free (void *rule
)
981 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
984 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
986 "ip next-hop prefix-list",
987 route_match_ip_next_hop_prefix_list
,
988 route_match_ip_next_hop_prefix_list_compile
,
989 route_match_ip_next_hop_prefix_list_free
992 /* `match ip address IP_ACCESS_LIST' */
994 /* Match function should return 1 if match is success else return
996 static route_map_result_t
997 route_match_ip_address (void *rule
, struct prefix
*prefix
,
998 route_map_object_t type
, void *object
)
1000 struct access_list
*alist
;
1002 if (type
== RMAP_ZEBRA
)
1004 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
1006 return RMAP_NOMATCH
;
1008 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
1009 RMAP_NOMATCH
: RMAP_MATCH
);
1011 return RMAP_NOMATCH
;
1014 /* Route map `ip address' match statement. `arg' should be
1015 access-list name. */
1017 route_match_ip_address_compile (const char *arg
)
1019 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1022 /* Free route map's compiled `ip address' value. */
1024 route_match_ip_address_free (void *rule
)
1026 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1029 /* Route map commands for ip address matching. */
1030 static struct route_map_rule_cmd route_match_ip_address_cmd
=
1033 route_match_ip_address
,
1034 route_match_ip_address_compile
,
1035 route_match_ip_address_free
1038 /* `match ip address prefix-list PREFIX_LIST' */
1040 static route_map_result_t
1041 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
1042 route_map_object_t type
, void *object
)
1044 struct prefix_list
*plist
;
1046 if (type
== RMAP_ZEBRA
)
1048 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
1050 return RMAP_NOMATCH
;
1052 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
1053 RMAP_NOMATCH
: RMAP_MATCH
);
1055 return RMAP_NOMATCH
;
1059 route_match_ip_address_prefix_list_compile (const char *arg
)
1061 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1065 route_match_ip_address_prefix_list_free (void *rule
)
1067 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1070 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
1072 "ip address prefix-list",
1073 route_match_ip_address_prefix_list
,
1074 route_match_ip_address_prefix_list_compile
,
1075 route_match_ip_address_prefix_list_free
1079 /* `match ip address prefix-len PREFIXLEN' */
1081 static route_map_result_t
1082 route_match_ip_address_prefix_len (void *rule
, struct prefix
*prefix
,
1083 route_map_object_t type
, void *object
)
1085 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1087 if (type
== RMAP_ZEBRA
)
1089 return ((prefix
->prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1091 return RMAP_NOMATCH
;
1095 route_match_ip_address_prefix_len_compile (const char *arg
)
1097 u_int32_t
*prefix_len
;
1098 char *endptr
= NULL
;
1099 unsigned long tmpval
;
1101 /* prefix len value shoud be integer. */
1102 if (! all_digit (arg
))
1106 tmpval
= strtoul (arg
, &endptr
, 10);
1107 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1110 prefix_len
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1115 *prefix_len
= tmpval
;
1120 route_match_ip_address_prefix_len_free (void *rule
)
1122 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1125 static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd
=
1127 "ip address prefix-len",
1128 route_match_ip_address_prefix_len
,
1129 route_match_ip_address_prefix_len_compile
,
1130 route_match_ip_address_prefix_len_free
1134 /* `match ip nexthop prefix-len PREFIXLEN' */
1136 static route_map_result_t
1137 route_match_ip_nexthop_prefix_len (void *rule
, struct prefix
*prefix
,
1138 route_map_object_t type
, void *object
)
1140 u_int32_t
*prefixlen
= (u_int32_t
*)rule
;
1141 struct nh_rmap_obj
*nh_data
;
1142 struct prefix_ipv4 p
;
1144 if (type
== RMAP_ZEBRA
)
1146 nh_data
= (struct nh_rmap_obj
*)object
;
1147 if (!nh_data
|| !nh_data
->nexthop
)
1148 return RMAP_DENYMATCH
;
1150 switch (nh_data
->nexthop
->type
) {
1151 case NEXTHOP_TYPE_IFINDEX
:
1152 /* Interface routes can't match ip next-hop */
1153 return RMAP_NOMATCH
;
1154 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1155 case NEXTHOP_TYPE_IPV4
:
1157 p
.prefix
= nh_data
->nexthop
->gate
.ipv4
;
1158 p
.prefixlen
= IPV4_MAX_BITLEN
;
1161 return RMAP_NOMATCH
;
1163 return ((p
.prefixlen
== *prefixlen
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1165 return RMAP_NOMATCH
;
1168 static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd
=
1170 "ip next-hop prefix-len",
1171 route_match_ip_nexthop_prefix_len
,
1172 route_match_ip_address_prefix_len_compile
, /* reuse */
1173 route_match_ip_address_prefix_len_free
/* reuse */
1176 /* `match source-protocol PROTOCOL' */
1178 static route_map_result_t
1179 route_match_source_protocol (void *rule
, struct prefix
*prefix
,
1180 route_map_object_t type
, void *object
)
1182 u_int32_t
*rib_type
= (u_int32_t
*)rule
;
1183 struct nh_rmap_obj
*nh_data
;
1185 if (type
== RMAP_ZEBRA
)
1187 nh_data
= (struct nh_rmap_obj
*)object
;
1189 return RMAP_DENYMATCH
;
1191 return ((nh_data
->source_protocol
== *rib_type
)
1192 ? RMAP_MATCH
: RMAP_NOMATCH
);
1194 return RMAP_NOMATCH
;
1198 route_match_source_protocol_compile (const char *arg
)
1200 u_int32_t
*rib_type
;
1203 i
= proto_name2num(arg
);
1204 rib_type
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
1212 route_match_source_protocol_free (void *rule
)
1214 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1217 static struct route_map_rule_cmd route_match_source_protocol_cmd
=
1220 route_match_source_protocol
,
1221 route_match_source_protocol_compile
,
1222 route_match_source_protocol_free
1225 /* `set src A.B.C.D' */
1228 static route_map_result_t
1229 route_set_src (void *rule
, struct prefix
*prefix
,
1230 route_map_object_t type
, void *object
)
1232 struct nh_rmap_obj
*nh_data
;
1234 if (type
== RMAP_ZEBRA
)
1236 nh_data
= (struct nh_rmap_obj
*)object
;
1237 nh_data
->nexthop
->rmap_src
= *(union g_addr
*)rule
;
1242 /* set src compilation. */
1244 route_set_src_compile (const char *arg
)
1246 union g_addr src
, *psrc
;
1250 (inet_pton(AF_INET6
, arg
, &src
.ipv6
) == 1) ||
1251 #endif /* HAVE_IPV6 */
1252 (src
.ipv4
.s_addr
&& (inet_pton(AF_INET
, arg
, &src
.ipv4
) == 1)))
1254 psrc
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union g_addr
));
1261 /* Free route map's compiled `set src' value. */
1263 route_set_src_free (void *rule
)
1265 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1268 /* Set src rule structure. */
1269 static struct route_map_rule_cmd route_set_src_cmd
=
1273 route_set_src_compile
,
1278 zebra_route_map_update_timer (struct thread
*thread
)
1280 zebra_t_rmap_update
= NULL
;
1282 if (IS_ZEBRA_DEBUG_EVENT
)
1283 zlog_debug("Event driven route-map update triggered");
1285 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
1286 zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
1289 zebra_import_table_rm_update ();
1290 rib_update(VRF_DEFAULT
, RIB_UPDATE_RMAP_CHANGE
);
1291 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1292 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1298 zebra_route_map_set_delay_timer(u_int32_t value
)
1300 zebra_rmap_update_timer
= value
;
1301 if (!value
&& zebra_t_rmap_update
)
1303 /* Event driven route map updates is being disabled */
1304 /* But there's a pending timer. Fire it off now */
1305 thread_cancel(zebra_t_rmap_update
);
1306 zebra_route_map_update_timer(zebra_t_rmap_update
);
1311 zebra_route_map_write_delay_timer (struct vty
*vty
)
1313 if (vty
&& (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
))
1314 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1320 zebra_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1321 struct nexthop
*nexthop
, vrf_id_t vrf_id
, u_short tag
)
1323 struct route_map
*rmap
= NULL
;
1324 route_map_result_t ret
= RMAP_MATCH
;
1325 struct nh_rmap_obj nh_obj
;
1327 nh_obj
.nexthop
= nexthop
;
1328 nh_obj
.vrf_id
= vrf_id
;
1329 nh_obj
.source_protocol
= rib_type
;
1333 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1334 rmap
= route_map_lookup_by_name (proto_rm
[family
][rib_type
]);
1335 if (!rmap
&& proto_rm
[family
][ZEBRA_ROUTE_MAX
])
1336 rmap
= route_map_lookup_by_name (proto_rm
[family
][ZEBRA_ROUTE_MAX
]);
1338 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1345 zebra_get_import_table_route_map (afi_t afi
, uint32_t table
)
1347 return zebra_import_table_routemap
[afi
][table
];
1351 zebra_add_import_table_route_map (afi_t afi
, const char *rmap_name
, uint32_t table
)
1353 zebra_import_table_routemap
[afi
][table
] = XSTRDUP (MTYPE_ROUTE_MAP_NAME
, rmap_name
);
1357 zebra_del_import_table_route_map (afi_t afi
, uint32_t table
)
1359 XFREE (MTYPE_ROUTE_MAP_NAME
, zebra_import_table_routemap
[afi
][table
]);
1363 zebra_import_table_route_map_check (int family
, int rib_type
, struct prefix
*p
,
1364 struct nexthop
*nexthop
, vrf_id_t vrf_id
, u_short tag
, const char *rmap_name
)
1366 struct route_map
*rmap
= NULL
;
1367 route_map_result_t ret
= RMAP_DENYMATCH
;
1368 struct nh_rmap_obj nh_obj
;
1370 nh_obj
.nexthop
= nexthop
;
1371 nh_obj
.vrf_id
= vrf_id
;
1372 nh_obj
.source_protocol
= rib_type
;
1376 if (rib_type
>= 0 && rib_type
< ZEBRA_ROUTE_MAX
)
1377 rmap
= route_map_lookup_by_name (rmap_name
);
1379 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1386 zebra_nht_route_map_check (int family
, int client_proto
, struct prefix
*p
,
1387 struct rib
* rib
, struct nexthop
*nexthop
)
1389 struct route_map
*rmap
= NULL
;
1390 route_map_result_t ret
= RMAP_MATCH
;
1391 struct nh_rmap_obj nh_obj
;
1393 nh_obj
.nexthop
= nexthop
;
1394 nh_obj
.vrf_id
= rib
->vrf_id
;
1395 nh_obj
.source_protocol
= rib
->type
;
1396 nh_obj
.metric
= rib
->metric
;
1397 nh_obj
.tag
= rib
->tag
;
1399 if (client_proto
>= 0 && client_proto
< ZEBRA_ROUTE_MAX
)
1400 rmap
= route_map_lookup_by_name (nht_rm
[family
][client_proto
]);
1401 if (!rmap
&& nht_rm
[family
][ZEBRA_ROUTE_MAX
])
1402 rmap
= route_map_lookup_by_name (nht_rm
[family
][ZEBRA_ROUTE_MAX
]);
1404 ret
= route_map_apply(rmap
, p
, RMAP_ZEBRA
, &nh_obj
);
1411 zebra_route_map_mark_update (const char *rmap_name
)
1413 /* rmap_update_timer of 0 means don't do route updates */
1414 if (zebra_rmap_update_timer
&& !zebra_t_rmap_update
)
1415 zebra_t_rmap_update
=
1416 thread_add_timer(zebrad
.master
, zebra_route_map_update_timer
, NULL
,
1417 zebra_rmap_update_timer
);
1421 zebra_route_map_add (const char *rmap_name
)
1423 zebra_route_map_mark_update(rmap_name
);
1424 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1428 zebra_route_map_delete (const char *rmap_name
)
1430 zebra_route_map_mark_update(rmap_name
);
1431 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
1435 zebra_route_map_event (route_map_event_t event
, const char *rmap_name
)
1437 zebra_route_map_mark_update(rmap_name
);
1438 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
1441 /* ip protocol configuration write function */
1443 zebra_routemap_config_write_protocol (struct vty
*vty
)
1447 for (i
=0;i
<ZEBRA_ROUTE_MAX
;i
++)
1449 if (proto_rm
[AFI_IP
][i
])
1450 vty_out (vty
, "ip protocol %s route-map %s%s", zebra_route_string(i
),
1451 proto_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1453 if (proto_rm
[AFI_IP6
][i
])
1454 vty_out (vty
, "ipv6 protocol %s route-map %s%s", zebra_route_string(i
),
1455 proto_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1457 if (nht_rm
[AFI_IP
][i
])
1458 vty_out (vty
, "ip nht %s route-map %s%s", zebra_route_string(i
),
1459 nht_rm
[AFI_IP
][i
], VTY_NEWLINE
);
1461 if (nht_rm
[AFI_IP6
][i
])
1462 vty_out (vty
, "ipv6 nht %s route-map %s%s", zebra_route_string(i
),
1463 nht_rm
[AFI_IP6
][i
], VTY_NEWLINE
);
1466 if (proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1467 vty_out (vty
, "ip protocol %s route-map %s%s", "any",
1468 proto_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1470 if (proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1471 vty_out (vty
, "ipv6 protocol %s route-map %s%s", "any",
1472 proto_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1474 if (nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
])
1475 vty_out (vty
, "ip nht %s route-map %s%s", "any",
1476 nht_rm
[AFI_IP
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1478 if (nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
])
1479 vty_out (vty
, "ipv6 nht %s route-map %s%s", "any",
1480 nht_rm
[AFI_IP6
][ZEBRA_ROUTE_MAX
], VTY_NEWLINE
);
1482 if (zebra_rmap_update_timer
!= ZEBRA_RMAP_DEFAULT_UPDATE_TIMER
)
1483 vty_out (vty
, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer
,
1488 zebra_route_map_init ()
1490 install_element (CONFIG_NODE
, &ip_protocol_cmd
);
1491 install_element (CONFIG_NODE
, &no_ip_protocol_cmd
);
1492 install_element (VIEW_NODE
, &show_ip_protocol_cmd
);
1493 install_element (ENABLE_NODE
, &show_ip_protocol_cmd
);
1494 install_element (CONFIG_NODE
, &ipv6_protocol_cmd
);
1495 install_element (CONFIG_NODE
, &no_ipv6_protocol_cmd
);
1496 install_element (VIEW_NODE
, &show_ipv6_protocol_cmd
);
1497 install_element (ENABLE_NODE
, &show_ipv6_protocol_cmd
);
1498 install_element (CONFIG_NODE
, &ip_protocol_nht_rmap_cmd
);
1499 install_element (CONFIG_NODE
, &no_ip_protocol_nht_rmap_cmd
);
1500 install_element (VIEW_NODE
, &show_ip_protocol_nht_cmd
);
1501 install_element (ENABLE_NODE
, &show_ip_protocol_nht_cmd
);
1502 install_element (CONFIG_NODE
, &ipv6_protocol_nht_rmap_cmd
);
1503 install_element (CONFIG_NODE
, &no_ipv6_protocol_nht_rmap_cmd
);
1504 install_element (VIEW_NODE
, &show_ipv6_protocol_nht_cmd
);
1505 install_element (ENABLE_NODE
, &show_ipv6_protocol_nht_cmd
);
1506 install_element (CONFIG_NODE
, &zebra_route_map_timer_cmd
);
1507 install_element (CONFIG_NODE
, &no_zebra_route_map_timer_cmd
);
1510 route_map_init_vty ();
1512 route_map_add_hook (zebra_route_map_add
);
1513 route_map_delete_hook (zebra_route_map_delete
);
1514 route_map_event_hook (zebra_route_map_event
);
1516 route_map_match_interface_hook (generic_match_add
);
1517 route_map_no_match_interface_hook (generic_match_delete
);
1519 route_map_match_ip_address_hook (generic_match_add
);
1520 route_map_no_match_ip_address_hook (generic_match_delete
);
1522 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
1523 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
1525 route_map_match_ip_next_hop_hook (generic_match_add
);
1526 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
1528 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
1529 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
1531 route_map_match_tag_hook (generic_match_add
);
1532 route_map_no_match_tag_hook (generic_match_delete
);
1534 route_map_install_match (&route_match_tag_cmd
);
1535 route_map_install_match (&route_match_interface_cmd
);
1536 route_map_install_match (&route_match_ip_next_hop_cmd
);
1537 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
1538 route_map_install_match (&route_match_ip_address_cmd
);
1539 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
1540 route_map_install_match (&route_match_ip_address_prefix_len_cmd
);
1541 route_map_install_match (&route_match_ip_nexthop_prefix_len_cmd
);
1542 route_map_install_match (&route_match_source_protocol_cmd
);
1544 route_map_install_set (&route_set_src_cmd
);
1546 install_element (RMAP_NODE
, &match_ip_nexthop_prefix_len_cmd
);
1547 install_element (RMAP_NODE
, &no_match_ip_nexthop_prefix_len_cmd
);
1548 install_element (RMAP_NODE
, &match_ip_address_prefix_len_cmd
);
1549 install_element (RMAP_NODE
, &no_match_ip_address_prefix_len_cmd
);
1550 install_element (RMAP_NODE
, &match_source_protocol_cmd
);
1551 install_element (RMAP_NODE
, &no_match_source_protocol_cmd
);
1553 install_element (RMAP_NODE
, &set_src_cmd
);
1554 install_element (RMAP_NODE
, &no_set_src_cmd
);