1 /* Route map function of bgpd.
2 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
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
32 #ifdef HAVE_LIBPCREPOSIX
33 #include <pcreposix.h>
36 #endif /* HAVE_LIBPCREPOSIX */
38 #include "sockunion.h"
43 #include "bgpd/bgpd.h"
44 #include "bgpd/bgp_table.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_aspath.h"
47 #include "bgpd/bgp_packet.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_zebra.h"
50 #include "bgpd/bgp_regex.h"
51 #include "bgpd/bgp_community.h"
52 #include "bgpd/bgp_clist.h"
53 #include "bgpd/bgp_filter.h"
54 #include "bgpd/bgp_mplsvpn.h"
55 #include "bgpd/bgp_ecommunity.h"
56 #include "bgpd/bgp_lcommunity.h"
57 #include "bgpd/bgp_vty.h"
58 #include "bgpd/bgp_debug.h"
59 #include "bgpd/bgp_evpn.h"
60 #include "bgpd/bgp_evpn_private.h"
61 #include "bgpd/bgp_evpn_vty.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_pbr.h"
64 #include "bgpd/bgp_flowspec_util.h"
67 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #ifndef VTYSH_EXTRACT_PL
71 #include "bgpd/bgp_routemap_clippy.c"
74 /* Memo of route-map commands.
83 ip route-source : Done
87 ipv6 route-source: (This will not be implemented by bgpd)
88 ipv6 prefix-list : Done
89 length : (This will not be implemented by bgpd)
91 route-type : (This will not be implemented by bgpd)
93 local-preference : Done
95 set as-path prepend : Done
97 automatic-tag : (This will not be implemented by bgpd)
99 large-community : Done
100 large-comm-list : Done
103 default : (This will not be implemented by bgpd)
104 interface : (This will not be implemented by bgpd)
105 ip default : (This will not be implemented by bgpd)
107 ip precedence : (This will not be implemented by bgpd)
108 ip tos : (This will not be implemented by bgpd)
109 level : (This will not be implemented by bgpd)
110 local-preference : Done
112 metric-type : Not yet
119 set ipv6 next-hop global: Done
120 set ipv6 next-hop prefer-global: Done
121 set ipv6 next-hop local : Done
122 set as-path exclude : Done
126 /* generic value manipulation to be shared in multiple rules */
128 #define RMAP_VALUE_SET 0
129 #define RMAP_VALUE_ADD 1
130 #define RMAP_VALUE_SUB 2
138 static int route_value_match(struct rmap_value
*rv
, uint32_t value
)
140 if (rv
->variable
== 0 && value
== rv
->value
)
146 static uint32_t route_value_adjust(struct rmap_value
*rv
, uint32_t current
,
151 switch (rv
->variable
) {
160 switch (rv
->action
) {
162 if (current
> UINT32_MAX
- value
)
164 return current
+ value
;
166 if (current
<= value
)
168 return current
- value
;
174 static void *route_value_compile(const char *arg
)
176 uint8_t action
= RMAP_VALUE_SET
, var
= 0;
177 unsigned long larg
= 0;
179 struct rmap_value
*rv
;
182 action
= RMAP_VALUE_ADD
;
184 } else if (arg
[0] == '-') {
185 action
= RMAP_VALUE_SUB
;
189 if (all_digit(arg
)) {
191 larg
= strtoul(arg
, &endptr
, 10);
192 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
195 if (strcmp(arg
, "rtt") == 0)
201 rv
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_value
));
209 static void route_value_free(void *rule
)
211 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
214 /* generic as path object to be shared in multiple rules */
216 static void *route_aspath_compile(const char *arg
)
218 struct aspath
*aspath
;
220 aspath
= aspath_str2aspath(arg
);
226 static void route_aspath_free(void *rule
)
228 struct aspath
*aspath
= rule
;
232 struct bgp_match_peer_compiled
{
237 /* 'match peer (A.B.C.D|X:X::X:X|WORD)' */
239 /* Compares the peer specified in the 'match peer' clause with the peer
240 received in bgp_path_info->peer. If it is the same, or if the peer structure
241 received is a peer_group containing it, returns RMAP_MATCH. */
242 static route_map_result_t
route_match_peer(void *rule
,
243 const struct prefix
*prefix
,
244 route_map_object_t type
,
247 struct bgp_match_peer_compiled
*pc
;
249 union sockunion su_def
= {
250 .sin
= {.sin_family
= AF_INET
, .sin_addr
.s_addr
= INADDR_ANY
}};
251 struct peer_group
*group
;
253 struct listnode
*node
, *nnode
;
255 if (type
== RMAP_BGP
) {
258 peer
= ((struct bgp_path_info
*)object
)->peer
;
264 if (strcmp(peer
->conf_if
, pc
->interface
) == 0)
270 /* If su='0.0.0.0' (command 'match peer local'), and it's a
272 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH
274 if (sockunion_same(su
, &su_def
)) {
276 if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_NETWORK
)
277 || CHECK_FLAG(peer
->rmap_type
,
278 PEER_RMAP_TYPE_REDISTRIBUTE
)
279 || CHECK_FLAG(peer
->rmap_type
,
280 PEER_RMAP_TYPE_DEFAULT
))
287 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
288 if (sockunion_same(su
, &peer
->su
))
294 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
296 if (sockunion_same(su
, &peer
->su
))
305 static void *route_match_peer_compile(const char *arg
)
307 struct bgp_match_peer_compiled
*pc
;
310 pc
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
,
311 sizeof(struct bgp_match_peer_compiled
));
313 ret
= str2sockunion(strcmp(arg
, "local") ? arg
: "0.0.0.0", &pc
->su
);
315 pc
->interface
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
322 /* Free route map's compiled `ip address' value. */
323 static void route_match_peer_free(void *rule
)
325 struct bgp_match_peer_compiled
*pc
= rule
;
327 XFREE(MTYPE_ROUTE_MAP_COMPILED
, pc
->interface
);
329 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
332 /* Route map commands for ip address matching. */
333 struct route_map_rule_cmd route_match_peer_cmd
= {"peer", route_match_peer
,
334 route_match_peer_compile
,
335 route_match_peer_free
};
337 #if defined(HAVE_LUA)
338 static route_map_result_t
route_match_command(void *rule
,
339 const struct prefix
*prefix
,
340 route_map_object_t type
,
343 int status
= RMAP_NOMATCH
;
344 u_int32_t locpref
= 0;
345 u_int32_t newlocpref
= 0;
346 enum lua_rm_status lrm_status
;
347 struct bgp_path_info
*path
= (struct bgp_path_info
*)object
;
348 lua_State
*L
= lua_initialize("/etc/frr/lua.scr");
354 * Setup the prefix information to pass in
356 lua_setup_prefix_table(L
, prefix
);
358 zlog_debug("Set up prefix table");
360 * Setup the bgp_path_info information
363 lua_pushinteger(L
, path
->attr
->med
);
364 lua_setfield(L
, -2, "metric");
365 lua_pushinteger(L
, path
->attr
->nh_ifindex
);
366 lua_setfield(L
, -2, "ifindex");
367 lua_pushstring(L
, path
->attr
->aspath
->str
);
368 lua_setfield(L
, -2, "aspath");
369 lua_pushinteger(L
, path
->attr
->local_pref
);
370 lua_setfield(L
, -2, "localpref");
371 zlog_debug("%s %d", path
->attr
->aspath
->str
, path
->attr
->nh_ifindex
);
372 lua_setglobal(L
, "nexthop");
374 zlog_debug("Set up nexthop information");
378 lrm_status
= lua_run_rm_rule(L
, rule
);
379 switch (lrm_status
) {
381 zlog_debug("RM_FAILURE");
384 zlog_debug("RM_NOMATCH");
386 case LUA_RM_MATCH_AND_CHANGE
:
387 zlog_debug("MATCH AND CHANGE");
388 lua_getglobal(L
, "nexthop");
389 path
->attr
->med
= get_integer(L
, "metric");
391 * This needs to be abstraced with the set function
393 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
394 locpref
= path
->attr
->local_pref
;
395 newlocpref
= get_integer(L
, "localpref");
396 if (newlocpref
!= locpref
) {
397 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
398 path
->attr
->local_pref
= newlocpref
;
403 zlog_debug("MATCH ONLY");
411 static void *route_match_command_compile(const char *arg
)
415 command
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
420 route_match_command_free(void *rule
)
422 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
425 struct route_map_rule_cmd route_match_command_cmd
= {
428 route_match_command_compile
,
429 route_match_command_free
433 /* `match ip address IP_ACCESS_LIST' */
435 /* Match function should return 1 if match is success else return
437 static route_map_result_t
route_match_ip_address(void *rule
,
438 const struct prefix
*prefix
,
439 route_map_object_t type
,
442 struct access_list
*alist
;
444 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
445 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
449 return (access_list_apply(alist
, prefix
) == FILTER_DENY
456 /* Route map `ip address' match statement. `arg' should be
458 static void *route_match_ip_address_compile(const char *arg
)
460 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
463 /* Free route map's compiled `ip address' value. */
464 static void route_match_ip_address_free(void *rule
)
466 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
469 /* Route map commands for ip address matching. */
470 struct route_map_rule_cmd route_match_ip_address_cmd
= {
471 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
472 route_match_ip_address_free
};
474 /* `match ip next-hop IP_ADDRESS' */
476 /* Match function return 1 if match is success else return zero. */
477 static route_map_result_t
route_match_ip_next_hop(void *rule
,
478 const struct prefix
*prefix
,
479 route_map_object_t type
,
482 struct access_list
*alist
;
483 struct bgp_path_info
*path
;
484 struct prefix_ipv4 p
;
486 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
489 p
.prefix
= path
->attr
->nexthop
;
490 p
.prefixlen
= IPV4_MAX_BITLEN
;
492 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
496 return (access_list_apply(alist
, &p
) == FILTER_DENY
503 /* Route map `ip next-hop' match statement. `arg' is
505 static void *route_match_ip_next_hop_compile(const char *arg
)
507 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
510 /* Free route map's compiled `ip address' value. */
511 static void route_match_ip_next_hop_free(void *rule
)
513 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
516 /* Route map commands for ip next-hop matching. */
517 struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
518 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
519 route_match_ip_next_hop_free
};
521 /* `match ip route-source ACCESS-LIST' */
523 /* Match function return 1 if match is success else return zero. */
524 static route_map_result_t
route_match_ip_route_source(void *rule
,
525 const struct prefix
*pfx
,
526 route_map_object_t type
,
529 struct access_list
*alist
;
530 struct bgp_path_info
*path
;
532 struct prefix_ipv4 p
;
534 if (type
== RMAP_BGP
&& pfx
->family
== AF_INET
) {
538 if (!peer
|| sockunion_family(&peer
->su
) != AF_INET
)
542 p
.prefix
= peer
->su
.sin
.sin_addr
;
543 p
.prefixlen
= IPV4_MAX_BITLEN
;
545 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
549 return (access_list_apply(alist
, &p
) == FILTER_DENY
556 /* Route map `ip route-source' match statement. `arg' is
558 static void *route_match_ip_route_source_compile(const char *arg
)
560 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
563 /* Free route map's compiled `ip address' value. */
564 static void route_match_ip_route_source_free(void *rule
)
566 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
569 /* Route map commands for ip route-source matching. */
570 struct route_map_rule_cmd route_match_ip_route_source_cmd
= {
571 "ip route-source", route_match_ip_route_source
,
572 route_match_ip_route_source_compile
, route_match_ip_route_source_free
};
574 static route_map_result_t
route_match_prefix_list_flowspec(afi_t afi
,
575 struct prefix_list
*plist
,
576 const struct prefix
*p
)
579 struct bgp_pbr_entry_main api
;
581 memset(&api
, 0, sizeof(api
));
583 /* extract match from flowspec entries */
584 ret
= bgp_flowspec_match_rules_fill(
585 (uint8_t *)p
->u
.prefix_flowspec
.ptr
,
586 p
->u
.prefix_flowspec
.prefixlen
, &api
);
589 if (api
.match_bitmask
& PREFIX_DST_PRESENT
||
590 api
.match_bitmask_iprule
& PREFIX_DST_PRESENT
) {
591 if (family2afi((&api
.dst_prefix
)->family
) != afi
)
593 return prefix_list_apply(plist
, &api
.dst_prefix
) == PREFIX_DENY
596 } else if (api
.match_bitmask
& PREFIX_SRC_PRESENT
||
597 api
.match_bitmask_iprule
& PREFIX_SRC_PRESENT
) {
598 if (family2afi((&api
.src_prefix
)->family
) != afi
)
600 return (prefix_list_apply(plist
, &api
.src_prefix
) == PREFIX_DENY
607 /* `match ip address prefix-list PREFIX_LIST' */
608 static route_map_result_t
609 route_match_address_prefix_list(void *rule
, afi_t afi
,
610 const struct prefix
*prefix
,
611 route_map_object_t type
, void *object
)
613 struct prefix_list
*plist
;
615 if (type
!= RMAP_BGP
)
618 plist
= prefix_list_lookup(afi
, (char *)rule
);
622 if (prefix
->family
== AF_FLOWSPEC
)
623 return route_match_prefix_list_flowspec(afi
, plist
,
625 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
? RMAP_NOMATCH
629 static route_map_result_t
630 route_match_ip_address_prefix_list(void *rule
, const struct prefix
*prefix
,
631 route_map_object_t type
, void *object
)
633 return route_match_address_prefix_list(rule
, AFI_IP
, prefix
, type
,
637 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
639 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
642 static void route_match_ip_address_prefix_list_free(void *rule
)
644 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
647 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
648 "ip address prefix-list", route_match_ip_address_prefix_list
,
649 route_match_ip_address_prefix_list_compile
,
650 route_match_ip_address_prefix_list_free
};
652 /* `match ip next-hop prefix-list PREFIX_LIST' */
654 static route_map_result_t
655 route_match_ip_next_hop_prefix_list(void *rule
, const struct prefix
*prefix
,
656 route_map_object_t type
, void *object
)
658 struct prefix_list
*plist
;
659 struct bgp_path_info
*path
;
660 struct prefix_ipv4 p
;
662 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
665 p
.prefix
= path
->attr
->nexthop
;
666 p
.prefixlen
= IPV4_MAX_BITLEN
;
668 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
672 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
679 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
681 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
684 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
686 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
689 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
690 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
691 route_match_ip_next_hop_prefix_list_compile
,
692 route_match_ip_next_hop_prefix_list_free
};
694 /* `match ip next-hop type <blackhole>' */
696 static route_map_result_t
697 route_match_ip_next_hop_type(void *rule
, const struct prefix
*prefix
,
698 route_map_object_t type
, void *object
)
700 struct bgp_path_info
*path
;
702 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
703 path
= (struct bgp_path_info
*)object
;
704 if (!path
|| !path
->attr
)
705 return RMAP_DENYMATCH
;
707 /* If nexthop interface's index can't be resolved and nexthop is
708 set to any address then mark it as type `blackhole`.
709 This logic works for matching kernel/static routes like:
710 `ip route add blackhole 10.0.0.1`. */
711 if (path
->attr
->nexthop
.s_addr
== INADDR_ANY
712 && !path
->attr
->nh_ifindex
)
718 static void *route_match_ip_next_hop_type_compile(const char *arg
)
720 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
723 static void route_match_ip_next_hop_type_free(void *rule
)
725 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
728 static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd
= {
729 "ip next-hop type", route_match_ip_next_hop_type
,
730 route_match_ip_next_hop_type_compile
,
731 route_match_ip_next_hop_type_free
};
733 /* `match ip route-source prefix-list PREFIX_LIST' */
735 static route_map_result_t
736 route_match_ip_route_source_prefix_list(void *rule
,
737 const struct prefix
*prefix
,
738 route_map_object_t type
, void *object
)
740 struct prefix_list
*plist
;
741 struct bgp_path_info
*path
;
743 struct prefix_ipv4 p
;
745 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
749 if (!peer
|| sockunion_family(&peer
->su
) != AF_INET
)
753 p
.prefix
= peer
->su
.sin
.sin_addr
;
754 p
.prefixlen
= IPV4_MAX_BITLEN
;
756 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
760 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
767 static void *route_match_ip_route_source_prefix_list_compile(const char *arg
)
769 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
772 static void route_match_ip_route_source_prefix_list_free(void *rule
)
774 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
777 struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd
= {
778 "ip route-source prefix-list", route_match_ip_route_source_prefix_list
,
779 route_match_ip_route_source_prefix_list_compile
,
780 route_match_ip_route_source_prefix_list_free
};
782 /* `match evpn default-route' */
784 /* Match function should return 1 if match is success else 0 */
785 static route_map_result_t
route_match_evpn_default_route(void *rule
,
786 const struct prefix
*p
,
790 if (type
== RMAP_BGP
&& is_evpn_prefix_default(p
))
796 /* Route map commands for default-route matching. */
797 struct route_map_rule_cmd route_match_evpn_default_route_cmd
= {
798 "evpn default-route", route_match_evpn_default_route
, NULL
, NULL
};
800 /* `match mac address MAC_ACCESS_LIST' */
802 /* Match function should return 1 if match is success else return
804 static route_map_result_t
route_match_mac_address(void *rule
,
805 const struct prefix
*prefix
,
806 route_map_object_t type
,
809 struct access_list
*alist
;
812 if (type
== RMAP_BGP
) {
813 alist
= access_list_lookup(AFI_L2VPN
, (char *)rule
);
817 if (prefix
->u
.prefix_evpn
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
820 p
.family
= AF_ETHERNET
;
821 p
.prefixlen
= ETH_ALEN
* 8;
822 p
.u
.prefix_eth
= prefix
->u
.prefix_evpn
.macip_addr
.mac
;
824 return (access_list_apply(alist
, &p
) == FILTER_DENY
832 /* Route map `mac address' match statement. `arg' should be
834 static void *route_match_mac_address_compile(const char *arg
)
836 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
839 /* Free route map's compiled `ip address' value. */
840 static void route_match_mac_address_free(void *rule
)
842 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
845 /* Route map commands for mac address matching. */
846 struct route_map_rule_cmd route_match_mac_address_cmd
= {
847 "mac address", route_match_mac_address
, route_match_mac_address_compile
,
848 route_match_mac_address_free
};
852 /* Match function should return 1 if match is success else return
854 static route_map_result_t
route_match_vni(void *rule
,
855 const struct prefix
*prefix
,
856 route_map_object_t type
, void *object
)
859 struct bgp_path_info
*path
= NULL
;
861 if (type
== RMAP_BGP
) {
862 vni
= *((vni_t
*)rule
);
863 path
= (struct bgp_path_info
*)object
;
865 if (path
->extra
== NULL
)
868 if (vni
== label2vni(&path
->extra
->label
[0]))
875 /* Route map `vni' match statement. */
876 static void *route_match_vni_compile(const char *arg
)
881 vni
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(vni_t
));
883 *vni
= strtoul(arg
, &end
, 10);
885 XFREE(MTYPE_ROUTE_MAP_COMPILED
, vni
);
892 /* Free route map's compiled `vni' value. */
893 static void route_match_vni_free(void *rule
)
895 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
898 /* Route map commands for vni matching. */
899 struct route_map_rule_cmd route_match_evpn_vni_cmd
= {
900 "evpn vni", route_match_vni
, route_match_vni_compile
,
901 route_match_vni_free
};
903 /* `match evpn route-type' */
905 /* Match function should return 1 if match is success else return
907 static route_map_result_t
route_match_evpn_route_type(void *rule
,
908 const struct prefix
*pfx
,
909 route_map_object_t type
,
912 uint8_t route_type
= 0;
914 if (type
== RMAP_BGP
) {
915 route_type
= *((uint8_t *)rule
);
917 if (route_type
== pfx
->u
.prefix_evpn
.route_type
)
924 /* Route map `route-type' match statement. */
925 static void *route_match_evpn_route_type_compile(const char *arg
)
927 uint8_t *route_type
= NULL
;
929 route_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
931 if (strncmp(arg
, "ma", 2) == 0)
932 *route_type
= BGP_EVPN_MAC_IP_ROUTE
;
933 else if (strncmp(arg
, "mu", 2) == 0)
934 *route_type
= BGP_EVPN_IMET_ROUTE
;
936 *route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
941 /* Free route map's compiled `route-type' value. */
942 static void route_match_evpn_route_type_free(void *rule
)
944 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
947 /* Route map commands for evpn route-type matching. */
948 struct route_map_rule_cmd route_match_evpn_route_type_cmd
= {
949 "evpn route-type", route_match_evpn_route_type
,
950 route_match_evpn_route_type_compile
, route_match_evpn_route_type_free
};
952 /* Route map commands for VRF route leak with source vrf matching */
953 static route_map_result_t
954 route_match_vrl_source_vrf(void *rule
, const struct prefix
*prefix
,
955 route_map_object_t type
, void *object
)
957 struct bgp_path_info
*path
;
960 if (type
== RMAP_BGP
) {
962 path
= (struct bgp_path_info
*)object
;
964 if (strncmp(vrf_name
, "n/a", VRF_NAMSIZ
) == 0)
967 if (path
->extra
== NULL
)
970 if (strncmp(vrf_name
, vrf_id_to_name(
971 path
->extra
->bgp_orig
->vrf_id
), VRF_NAMSIZ
)
979 static void *route_match_vrl_source_vrf_compile(const char *arg
)
981 uint8_t *vrf_name
= NULL
;
983 vrf_name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
988 /* Free route map's compiled `route-type' value. */
989 static void route_match_vrl_source_vrf_free(void *rule
)
991 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
994 struct route_map_rule_cmd route_match_vrl_source_vrf_cmd
= {
995 "source-vrf", route_match_vrl_source_vrf
,
996 route_match_vrl_source_vrf_compile
,
997 route_match_vrl_source_vrf_free
};
999 /* `match local-preference LOCAL-PREF' */
1001 /* Match function return 1 if match is success else return zero. */
1002 static route_map_result_t
route_match_local_pref(void *rule
,
1003 const struct prefix
*prefix
,
1004 route_map_object_t type
,
1007 uint32_t *local_pref
;
1008 struct bgp_path_info
*path
;
1010 if (type
== RMAP_BGP
) {
1014 if (path
->attr
->local_pref
== *local_pref
)
1017 return RMAP_NOMATCH
;
1019 return RMAP_NOMATCH
;
1022 /* Route map `match local-preference' match statement.
1023 `arg' is local-pref value */
1024 static void *route_match_local_pref_compile(const char *arg
)
1026 uint32_t *local_pref
;
1027 char *endptr
= NULL
;
1028 unsigned long tmpval
;
1030 /* Locpref value shoud be integer. */
1031 if (!all_digit(arg
))
1035 tmpval
= strtoul(arg
, &endptr
, 10);
1036 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1039 local_pref
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1041 *local_pref
= tmpval
;
1045 /* Free route map's compiled `match local-preference' value. */
1046 static void route_match_local_pref_free(void *rule
)
1048 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1051 /* Route map commands for metric matching. */
1052 struct route_map_rule_cmd route_match_local_pref_cmd
= {
1053 "local-preference", route_match_local_pref
,
1054 route_match_local_pref_compile
, route_match_local_pref_free
};
1056 /* `match metric METRIC' */
1058 /* Match function return 1 if match is success else return zero. */
1059 static route_map_result_t
route_match_metric(void *rule
,
1060 const struct prefix
*prefix
,
1061 route_map_object_t type
,
1064 struct rmap_value
*rv
;
1065 struct bgp_path_info
*path
;
1067 if (type
== RMAP_BGP
) {
1070 return route_value_match(rv
, path
->attr
->med
);
1072 return RMAP_NOMATCH
;
1075 /* Route map commands for metric matching. */
1076 struct route_map_rule_cmd route_match_metric_cmd
= {
1077 "metric", route_match_metric
, route_value_compile
, route_value_free
,
1080 /* `match as-path ASPATH' */
1082 /* Match function for as-path match. I assume given object is */
1083 static route_map_result_t
route_match_aspath(void *rule
,
1084 const struct prefix
*prefix
,
1085 route_map_object_t type
,
1089 struct as_list
*as_list
;
1090 struct bgp_path_info
*path
;
1092 if (type
== RMAP_BGP
) {
1093 as_list
= as_list_lookup((char *)rule
);
1094 if (as_list
== NULL
)
1095 return RMAP_NOMATCH
;
1099 /* Perform match. */
1100 return ((as_list_apply(as_list
, path
->attr
->aspath
)
1105 return RMAP_NOMATCH
;
1108 /* Compile function for as-path match. */
1109 static void *route_match_aspath_compile(const char *arg
)
1111 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1114 /* Compile function for as-path match. */
1115 static void route_match_aspath_free(void *rule
)
1117 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1120 /* Route map commands for aspath matching. */
1121 struct route_map_rule_cmd route_match_aspath_cmd
= {
1122 "as-path", route_match_aspath
, route_match_aspath_compile
,
1123 route_match_aspath_free
};
1125 /* `match community COMMUNIY' */
1126 struct rmap_community
{
1132 /* Match function for community match. */
1133 static route_map_result_t
route_match_community(void *rule
,
1134 const struct prefix
*prefix
,
1135 route_map_object_t type
,
1138 struct community_list
*list
;
1139 struct bgp_path_info
*path
;
1140 struct rmap_community
*rcom
= rule
;
1142 if (type
== RMAP_BGP
) {
1146 list
= community_list_lookup(bgp_clist
, rcom
->name
,
1148 COMMUNITY_LIST_MASTER
);
1150 return RMAP_NOMATCH
;
1153 if (community_list_exact_match(path
->attr
->community
,
1157 if (community_list_match(path
->attr
->community
, list
))
1161 return RMAP_NOMATCH
;
1164 /* Compile function for community match. */
1165 static void *route_match_community_compile(const char *arg
)
1167 struct rmap_community
*rcom
;
1171 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1173 p
= strchr(arg
, ' ');
1176 rcom
->name
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1177 memcpy(rcom
->name
, arg
, len
);
1180 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1184 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1188 /* Compile function for community match. */
1189 static void route_match_community_free(void *rule
)
1191 struct rmap_community
*rcom
= rule
;
1193 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1194 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1197 /* Route map commands for community matching. */
1198 struct route_map_rule_cmd route_match_community_cmd
= {
1199 "community", route_match_community
, route_match_community_compile
,
1200 route_match_community_free
};
1202 /* Match function for lcommunity match. */
1203 static route_map_result_t
route_match_lcommunity(void *rule
,
1204 const struct prefix
*prefix
,
1205 route_map_object_t type
,
1208 struct community_list
*list
;
1209 struct bgp_path_info
*path
;
1210 struct rmap_community
*rcom
= rule
;
1212 if (type
== RMAP_BGP
) {
1215 list
= community_list_lookup(bgp_clist
, rcom
->name
,
1217 LARGE_COMMUNITY_LIST_MASTER
);
1219 return RMAP_NOMATCH
;
1222 if (lcommunity_list_exact_match(
1223 path
->attr
->lcommunity
,
1227 if (lcommunity_list_match(
1228 path
->attr
->lcommunity
,
1233 return RMAP_NOMATCH
;
1236 /* Compile function for community match. */
1237 static void *route_match_lcommunity_compile(const char *arg
)
1239 struct rmap_community
*rcom
;
1243 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1245 p
= strchr(arg
, ' ');
1248 rcom
->name
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1249 memcpy(rcom
->name
, arg
, len
);
1252 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1256 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1260 /* Compile function for community match. */
1261 static void route_match_lcommunity_free(void *rule
)
1263 struct rmap_community
*rcom
= rule
;
1265 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1266 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1269 /* Route map commands for community matching. */
1270 struct route_map_rule_cmd route_match_lcommunity_cmd
= {
1271 "large-community", route_match_lcommunity
,
1272 route_match_lcommunity_compile
, route_match_lcommunity_free
};
1275 /* Match function for extcommunity match. */
1276 static route_map_result_t
route_match_ecommunity(void *rule
,
1277 const struct prefix
*prefix
,
1278 route_map_object_t type
,
1281 struct community_list
*list
;
1282 struct bgp_path_info
*path
;
1283 struct rmap_community
*rcom
= rule
;
1285 if (type
== RMAP_BGP
) {
1288 list
= community_list_lookup(bgp_clist
, rcom
->name
,
1290 EXTCOMMUNITY_LIST_MASTER
);
1292 return RMAP_NOMATCH
;
1294 if (ecommunity_list_match(path
->attr
->ecommunity
, list
))
1297 return RMAP_NOMATCH
;
1300 /* Compile function for extcommunity match. */
1301 static void *route_match_ecommunity_compile(const char *arg
)
1303 struct rmap_community
*rcom
;
1305 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1306 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1307 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1312 /* Compile function for extcommunity match. */
1313 static void route_match_ecommunity_free(void *rule
)
1315 struct rmap_community
*rcom
= rule
;
1317 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1318 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1321 /* Route map commands for community matching. */
1322 struct route_map_rule_cmd route_match_ecommunity_cmd
= {
1323 "extcommunity", route_match_ecommunity
, route_match_ecommunity_compile
,
1324 route_match_ecommunity_free
};
1326 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
1327 and `address-family vpnv4'. */
1329 /* `match origin' */
1330 static route_map_result_t
route_match_origin(void *rule
,
1331 const struct prefix
*prefix
,
1332 route_map_object_t type
,
1336 struct bgp_path_info
*path
;
1338 if (type
== RMAP_BGP
) {
1342 if (path
->attr
->origin
== *origin
)
1346 return RMAP_NOMATCH
;
1349 static void *route_match_origin_compile(const char *arg
)
1353 origin
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1355 if (strcmp(arg
, "igp") == 0)
1357 else if (strcmp(arg
, "egp") == 0)
1365 /* Free route map's compiled `ip address' value. */
1366 static void route_match_origin_free(void *rule
)
1368 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1371 /* Route map commands for origin matching. */
1372 struct route_map_rule_cmd route_match_origin_cmd
= {
1373 "origin", route_match_origin
, route_match_origin_compile
,
1374 route_match_origin_free
};
1376 /* match probability { */
1378 static route_map_result_t
route_match_probability(void *rule
,
1379 const struct prefix
*prefix
,
1380 route_map_object_t type
,
1385 switch (*(long *)rule
) {
1391 if (r
< *(long *)rule
) {
1396 return RMAP_NOMATCH
;
1399 static void *route_match_probability_compile(const char *arg
)
1405 lobule
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(long));
1415 *lobule
= RAND_MAX
/ 100 * perc
;
1421 static void route_match_probability_free(void *rule
)
1423 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1426 struct route_map_rule_cmd route_match_probability_cmd
= {
1427 "probability", route_match_probability
, route_match_probability_compile
,
1428 route_match_probability_free
};
1430 /* `match interface IFNAME' */
1431 /* Match function should return 1 if match is success else return
1433 static route_map_result_t
route_match_interface(void *rule
,
1434 const struct prefix
*prefix
,
1435 route_map_object_t type
,
1438 struct interface
*ifp
;
1439 struct bgp_path_info
*path
;
1441 if (type
== RMAP_BGP
) {
1444 if (!path
|| !path
->attr
)
1445 return RMAP_NOMATCH
;
1447 ifp
= if_lookup_by_name_all_vrf((char *)rule
);
1449 if (ifp
== NULL
|| ifp
->ifindex
!= path
->attr
->nh_ifindex
)
1450 return RMAP_NOMATCH
;
1454 return RMAP_NOMATCH
;
1457 /* Route map `interface' match statement. `arg' should be
1459 static void *route_match_interface_compile(const char *arg
)
1461 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1464 /* Free route map's compiled `interface' value. */
1465 static void route_match_interface_free(void *rule
)
1467 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1470 /* Route map commands for ip address matching. */
1471 struct route_map_rule_cmd route_match_interface_cmd
= {
1472 "interface", route_match_interface
, route_match_interface_compile
,
1473 route_match_interface_free
};
1477 /* `set ip next-hop IP_ADDRESS' */
1479 /* Match function return 1 if match is success else return zero. */
1480 static route_map_result_t
route_match_tag(void *rule
,
1481 const struct prefix
*prefix
,
1482 route_map_object_t type
, void *object
)
1485 struct bgp_path_info
*path
;
1487 if (type
== RMAP_BGP
) {
1491 return ((path
->attr
->tag
== *tag
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1494 return RMAP_NOMATCH
;
1498 /* Route map commands for tag matching. */
1499 static struct route_map_rule_cmd route_match_tag_cmd
= {
1500 "tag", route_match_tag
, route_map_rule_tag_compile
,
1501 route_map_rule_tag_free
,
1505 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1506 struct rmap_ip_nexthop_set
{
1507 struct in_addr
*address
;
1512 static route_map_result_t
route_set_ip_nexthop(void *rule
,
1513 const struct prefix
*prefix
,
1514 route_map_object_t type
,
1517 struct rmap_ip_nexthop_set
*rins
= rule
;
1518 struct bgp_path_info
*path
;
1521 if (type
!= RMAP_BGP
)
1524 if (prefix
->family
== AF_INET6
)
1530 if (rins
->unchanged
) {
1531 SET_FLAG(path
->attr
->rmap_change_flags
,
1532 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1533 } else if (rins
->peer_address
) {
1534 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
1535 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1537 && sockunion_family(peer
->su_remote
) == AF_INET
) {
1538 path
->attr
->nexthop
.s_addr
=
1539 sockunion2ip(peer
->su_remote
);
1540 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1541 } else if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
)) {
1542 /* The next hop value will be set as part of
1543 * packet rewrite. Set the flags here to indicate
1544 * that rewrite needs to be done.
1545 * Also, clear the value.
1547 SET_FLAG(path
->attr
->rmap_change_flags
,
1548 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1549 path
->attr
->nexthop
.s_addr
= 0;
1552 /* Set next hop value. */
1553 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1554 path
->attr
->nexthop
= *rins
->address
;
1555 SET_FLAG(path
->attr
->rmap_change_flags
,
1556 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1557 /* case for MP-BGP : MPLS VPN */
1558 path
->attr
->mp_nexthop_global_in
= *rins
->address
;
1559 path
->attr
->mp_nexthop_len
= sizeof(*rins
->address
);
1565 /* Route map `ip nexthop' compile function. Given string is converted
1566 to struct in_addr structure. */
1567 static void *route_set_ip_nexthop_compile(const char *arg
)
1569 struct rmap_ip_nexthop_set
*rins
;
1570 struct in_addr
*address
= NULL
;
1571 int peer_address
= 0;
1575 if (strcmp(arg
, "peer-address") == 0)
1577 else if (strcmp(arg
, "unchanged") == 0)
1580 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
1581 sizeof(struct in_addr
));
1582 ret
= inet_aton(arg
, address
);
1585 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
1590 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
,
1591 sizeof(struct rmap_ip_nexthop_set
));
1593 rins
->address
= address
;
1594 rins
->peer_address
= peer_address
;
1595 rins
->unchanged
= unchanged
;
1600 /* Free route map's compiled `ip nexthop' value. */
1601 static void route_set_ip_nexthop_free(void *rule
)
1603 struct rmap_ip_nexthop_set
*rins
= rule
;
1605 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1607 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rins
);
1610 /* Route map commands for ip nexthop set. */
1611 struct route_map_rule_cmd route_set_ip_nexthop_cmd
= {
1612 "ip next-hop", route_set_ip_nexthop
, route_set_ip_nexthop_compile
,
1613 route_set_ip_nexthop_free
};
1615 /* `set local-preference LOCAL_PREF' */
1617 /* Set local preference. */
1618 static route_map_result_t
route_set_local_pref(void *rule
,
1619 const struct prefix
*prefix
,
1620 route_map_object_t type
,
1623 struct rmap_value
*rv
;
1624 struct bgp_path_info
*path
;
1625 uint32_t locpref
= 0;
1627 if (type
== RMAP_BGP
) {
1628 /* Fetch routemap's rule information. */
1632 /* Set local preference value. */
1633 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1634 locpref
= path
->attr
->local_pref
;
1636 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1637 path
->attr
->local_pref
=
1638 route_value_adjust(rv
, locpref
, path
->peer
);
1644 /* Set local preference rule structure. */
1645 struct route_map_rule_cmd route_set_local_pref_cmd
= {
1646 "local-preference", route_set_local_pref
, route_value_compile
,
1650 /* `set weight WEIGHT' */
1653 static route_map_result_t
route_set_weight(void *rule
,
1654 const struct prefix
*prefix
,
1655 route_map_object_t type
,
1658 struct rmap_value
*rv
;
1659 struct bgp_path_info
*path
;
1661 if (type
== RMAP_BGP
) {
1662 /* Fetch routemap's rule information. */
1666 /* Set weight value. */
1667 path
->attr
->weight
= route_value_adjust(rv
, 0, path
->peer
);
1673 /* Set local preference rule structure. */
1674 struct route_map_rule_cmd route_set_weight_cmd
= {
1675 "weight", route_set_weight
, route_value_compile
, route_value_free
,
1678 /* `set metric METRIC' */
1680 /* Set metric to attribute. */
1681 static route_map_result_t
route_set_metric(void *rule
,
1682 const struct prefix
*prefix
,
1683 route_map_object_t type
,
1686 struct rmap_value
*rv
;
1687 struct bgp_path_info
*path
;
1690 if (type
== RMAP_BGP
) {
1691 /* Fetch routemap's rule information. */
1695 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
1696 med
= path
->attr
->med
;
1698 path
->attr
->med
= route_value_adjust(rv
, med
, path
->peer
);
1699 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
1704 /* Set metric rule structure. */
1705 struct route_map_rule_cmd route_set_metric_cmd
= {
1706 "metric", route_set_metric
, route_value_compile
, route_value_free
,
1709 /* `set as-path prepend ASPATH' */
1711 /* For AS path prepend mechanism. */
1712 static route_map_result_t
route_set_aspath_prepend(void *rule
,
1713 const struct prefix
*prefix
,
1714 route_map_object_t type
,
1717 struct aspath
*aspath
;
1719 struct bgp_path_info
*path
;
1721 if (type
== RMAP_BGP
) {
1724 if (path
->attr
->aspath
->refcnt
)
1725 new = aspath_dup(path
->attr
->aspath
);
1727 new = path
->attr
->aspath
;
1729 if ((uintptr_t)rule
> 10) {
1731 aspath_prepend(aspath
, new);
1733 as_t as
= aspath_leftmost(new);
1735 as
= path
->peer
->as
;
1736 new = aspath_add_seq_n(new, as
, (uintptr_t)rule
);
1739 path
->attr
->aspath
= new;
1745 static void *route_set_aspath_prepend_compile(const char *arg
)
1749 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
<= 10)
1750 return (void *)(uintptr_t)num
;
1752 return route_aspath_compile(arg
);
1755 static void route_set_aspath_prepend_free(void *rule
)
1757 if ((uintptr_t)rule
> 10)
1758 route_aspath_free(rule
);
1762 /* Set as-path prepend rule structure. */
1763 struct route_map_rule_cmd route_set_aspath_prepend_cmd
= {
1764 "as-path prepend", route_set_aspath_prepend
,
1765 route_set_aspath_prepend_compile
, route_set_aspath_prepend_free
,
1768 /* `set as-path exclude ASn' */
1770 /* For ASN exclude mechanism.
1771 * Iterate over ASns requested and filter them from the given AS_PATH one by
1773 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1775 static route_map_result_t
route_set_aspath_exclude(void *rule
,
1776 const struct prefix
*dummy
,
1777 route_map_object_t type
,
1780 struct aspath
*new_path
, *exclude_path
;
1781 struct bgp_path_info
*path
;
1783 if (type
== RMAP_BGP
) {
1784 exclude_path
= rule
;
1786 if (path
->attr
->aspath
->refcnt
)
1787 new_path
= aspath_dup(path
->attr
->aspath
);
1789 new_path
= path
->attr
->aspath
;
1790 path
->attr
->aspath
=
1791 aspath_filter_exclude(new_path
, exclude_path
);
1796 /* Set ASn exlude rule structure. */
1797 struct route_map_rule_cmd route_set_aspath_exclude_cmd
= {
1798 "as-path exclude", route_set_aspath_exclude
, route_aspath_compile
,
1802 /* `set community COMMUNITY' */
1803 struct rmap_com_set
{
1804 struct community
*com
;
1809 /* For community set mechanism. */
1810 static route_map_result_t
route_set_community(void *rule
,
1811 const struct prefix
*prefix
,
1812 route_map_object_t type
,
1815 struct rmap_com_set
*rcs
;
1816 struct bgp_path_info
*path
;
1818 struct community
*new = NULL
;
1819 struct community
*old
;
1820 struct community
*merge
;
1822 if (type
== RMAP_BGP
) {
1826 old
= attr
->community
;
1830 attr
->flag
&= ~(ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
));
1831 attr
->community
= NULL
;
1832 /* See the longer comment down below. */
1833 if (old
&& old
->refcnt
== 0)
1834 community_free(&old
);
1838 /* "additive" case. */
1839 if (rcs
->additive
&& old
) {
1840 merge
= community_merge(community_dup(old
), rcs
->com
);
1842 new = community_uniq_sort(merge
);
1843 community_free(&merge
);
1845 new = community_dup(rcs
->com
);
1847 /* HACK: if the old community is not intern'd,
1848 * we should free it here, or all reference to it may be
1850 * Really need to cleanup attribute caching sometime.
1852 if (old
&& old
->refcnt
== 0)
1853 community_free(&old
);
1855 /* will be interned by caller if required */
1856 attr
->community
= new;
1858 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1864 /* Compile function for set community. */
1865 static void *route_set_community_compile(const char *arg
)
1867 struct rmap_com_set
*rcs
;
1868 struct community
*com
= NULL
;
1873 if (strcmp(arg
, "none") == 0)
1876 sp
= strstr(arg
, "additive");
1878 if (sp
&& sp
> arg
) {
1879 /* "additive" keyword is included. */
1884 com
= community_str2com(arg
);
1893 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_com_set
));
1895 rcs
->additive
= additive
;
1901 /* Free function for set community. */
1902 static void route_set_community_free(void *rule
)
1904 struct rmap_com_set
*rcs
= rule
;
1907 community_free(&rcs
->com
);
1908 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1911 /* Set community rule structure. */
1912 struct route_map_rule_cmd route_set_community_cmd
= {
1913 "community", route_set_community
, route_set_community_compile
,
1914 route_set_community_free
,
1917 /* `set community COMMUNITY' */
1918 struct rmap_lcom_set
{
1919 struct lcommunity
*lcom
;
1925 /* For lcommunity set mechanism. */
1926 static route_map_result_t
route_set_lcommunity(void *rule
,
1927 const struct prefix
*prefix
,
1928 route_map_object_t type
,
1931 struct rmap_lcom_set
*rcs
;
1932 struct bgp_path_info
*path
;
1934 struct lcommunity
*new = NULL
;
1935 struct lcommunity
*old
;
1936 struct lcommunity
*merge
;
1938 if (type
== RMAP_BGP
) {
1942 old
= attr
->lcommunity
;
1947 ~(ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
));
1948 attr
->lcommunity
= NULL
;
1950 /* See the longer comment down below. */
1951 if (old
&& old
->refcnt
== 0)
1952 lcommunity_free(&old
);
1956 if (rcs
->additive
&& old
) {
1957 merge
= lcommunity_merge(lcommunity_dup(old
),
1960 new = lcommunity_uniq_sort(merge
);
1961 lcommunity_free(&merge
);
1963 new = lcommunity_dup(rcs
->lcom
);
1965 /* HACK: if the old large-community is not intern'd,
1966 * we should free it here, or all reference to it may be
1968 * Really need to cleanup attribute caching sometime.
1970 if (old
&& old
->refcnt
== 0)
1971 lcommunity_free(&old
);
1973 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1974 attr
->lcommunity
= new;
1976 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
);
1982 /* Compile function for set community. */
1983 static void *route_set_lcommunity_compile(const char *arg
)
1985 struct rmap_lcom_set
*rcs
;
1986 struct lcommunity
*lcom
= NULL
;
1991 if (strcmp(arg
, "none") == 0)
1994 sp
= strstr(arg
, "additive");
1996 if (sp
&& sp
> arg
) {
1997 /* "additive" keyworkd is included. */
2002 lcom
= lcommunity_str2com(arg
);
2011 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_com_set
));
2013 rcs
->additive
= additive
;
2019 /* Free function for set lcommunity. */
2020 static void route_set_lcommunity_free(void *rule
)
2022 struct rmap_lcom_set
*rcs
= rule
;
2025 lcommunity_free(&rcs
->lcom
);
2027 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
2030 /* Set community rule structure. */
2031 struct route_map_rule_cmd route_set_lcommunity_cmd
= {
2032 "large-community", route_set_lcommunity
, route_set_lcommunity_compile
,
2033 route_set_lcommunity_free
,
2036 /* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
2038 /* For large community set mechanism. */
2039 static route_map_result_t
route_set_lcommunity_delete(void *rule
,
2040 const struct prefix
*pfx
,
2041 route_map_object_t type
,
2044 struct community_list
*list
;
2045 struct lcommunity
*merge
;
2046 struct lcommunity
*new;
2047 struct lcommunity
*old
;
2048 struct bgp_path_info
*path
;
2049 struct rmap_community
*rcom
= rule
;
2051 if (type
== RMAP_BGP
) {
2056 list
= community_list_lookup(bgp_clist
, rcom
->name
,
2058 LARGE_COMMUNITY_LIST_MASTER
);
2059 old
= path
->attr
->lcommunity
;
2062 merge
= lcommunity_list_match_delete(
2063 lcommunity_dup(old
), list
);
2064 new = lcommunity_uniq_sort(merge
);
2065 lcommunity_free(&merge
);
2067 /* HACK: if the old community is not intern'd,
2068 * we should free it here, or all reference to it may be
2070 * Really need to cleanup attribute caching sometime.
2072 if (old
->refcnt
== 0)
2073 lcommunity_free(&old
);
2075 if (new->size
== 0) {
2076 path
->attr
->lcommunity
= NULL
;
2077 path
->attr
->flag
&= ~ATTR_FLAG_BIT(
2078 BGP_ATTR_LARGE_COMMUNITIES
);
2079 lcommunity_free(&new);
2081 path
->attr
->lcommunity
= new;
2082 path
->attr
->flag
|= ATTR_FLAG_BIT(
2083 BGP_ATTR_LARGE_COMMUNITIES
);
2091 /* Compile function for set lcommunity. */
2092 static void *route_set_lcommunity_delete_compile(const char *arg
)
2094 struct rmap_community
*rcom
;
2096 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
2098 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
2099 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
2104 /* Free function for set lcommunity. */
2105 static void route_set_lcommunity_delete_free(void *rule
)
2107 struct rmap_community
*rcom
= rule
;
2109 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
2110 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
2113 /* Set lcommunity rule structure. */
2114 struct route_map_rule_cmd route_set_lcommunity_delete_cmd
= {
2115 "large-comm-list", route_set_lcommunity_delete
,
2116 route_set_lcommunity_delete_compile
, route_set_lcommunity_delete_free
,
2120 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
2122 /* For community set mechanism. */
2123 static route_map_result_t
route_set_community_delete(
2125 const struct prefix
*prefix
,
2126 route_map_object_t type
,
2129 struct community_list
*list
;
2130 struct community
*merge
;
2131 struct community
*new;
2132 struct community
*old
;
2133 struct bgp_path_info
*path
;
2134 struct rmap_community
*rcom
= rule
;
2136 if (type
== RMAP_BGP
) {
2141 list
= community_list_lookup(bgp_clist
, rcom
->name
,
2143 COMMUNITY_LIST_MASTER
);
2144 old
= path
->attr
->community
;
2147 merge
= community_list_match_delete(community_dup(old
),
2149 new = community_uniq_sort(merge
);
2150 community_free(&merge
);
2152 /* HACK: if the old community is not intern'd,
2153 * we should free it here, or all reference to it may be
2155 * Really need to cleanup attribute caching sometime.
2157 if (old
->refcnt
== 0)
2158 community_free(&old
);
2160 if (new->size
== 0) {
2161 path
->attr
->community
= NULL
;
2163 ~ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2164 community_free(&new);
2166 path
->attr
->community
= new;
2168 ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2176 /* Compile function for set community. */
2177 static void *route_set_community_delete_compile(const char *arg
)
2179 struct rmap_community
*rcom
;
2183 frrstr_split(arg
, " ", &splits
, &num
);
2185 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
2186 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, splits
[0]);
2187 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
2189 for (int i
= 0; i
< num
; i
++)
2190 XFREE(MTYPE_TMP
, splits
[i
]);
2191 XFREE(MTYPE_TMP
, splits
);
2196 /* Free function for set community. */
2197 static void route_set_community_delete_free(void *rule
)
2199 struct rmap_community
*rcom
= rule
;
2201 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
2202 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
2205 /* Set community rule structure. */
2206 struct route_map_rule_cmd route_set_community_delete_cmd
= {
2207 "comm-list", route_set_community_delete
,
2208 route_set_community_delete_compile
, route_set_community_delete_free
,
2211 /* `set extcommunity rt COMMUNITY' */
2213 /* For community set mechanism. Used by _rt and _soo. */
2214 static route_map_result_t
route_set_ecommunity(void *rule
,
2215 const struct prefix
*prefix
,
2216 route_map_object_t type
,
2219 struct ecommunity
*ecom
;
2220 struct ecommunity
*new_ecom
;
2221 struct ecommunity
*old_ecom
;
2222 struct bgp_path_info
*path
;
2224 if (type
== RMAP_BGP
) {
2231 /* We assume additive for Extended Community. */
2232 old_ecom
= path
->attr
->ecommunity
;
2235 new_ecom
= ecommunity_merge(ecommunity_dup(old_ecom
),
2238 /* old_ecom->refcnt = 1 => owned elsewhere, e.g.
2239 * bgp_update_receive()
2240 * ->refcnt = 0 => set by a previous route-map
2242 if (!old_ecom
->refcnt
)
2243 ecommunity_free(&old_ecom
);
2245 new_ecom
= ecommunity_dup(ecom
);
2247 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
2248 path
->attr
->ecommunity
= new_ecom
;
2250 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
2255 /* Compile function for set community. */
2256 static void *route_set_ecommunity_rt_compile(const char *arg
)
2258 struct ecommunity
*ecom
;
2260 ecom
= ecommunity_str2com(arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
2263 return ecommunity_intern(ecom
);
2266 /* Free function for set community. Used by _rt and _soo */
2267 static void route_set_ecommunity_free(void *rule
)
2269 struct ecommunity
*ecom
= rule
;
2270 ecommunity_unintern(&ecom
);
2273 /* Set community rule structure. */
2274 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
= {
2275 "extcommunity rt", route_set_ecommunity
,
2276 route_set_ecommunity_rt_compile
, route_set_ecommunity_free
,
2279 /* `set extcommunity soo COMMUNITY' */
2281 /* Compile function for set community. */
2282 static void *route_set_ecommunity_soo_compile(const char *arg
)
2284 struct ecommunity
*ecom
;
2286 ecom
= ecommunity_str2com(arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
2290 return ecommunity_intern(ecom
);
2293 /* Set community rule structure. */
2294 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
= {
2295 "extcommunity soo", route_set_ecommunity
,
2296 route_set_ecommunity_soo_compile
, route_set_ecommunity_free
,
2299 /* `set origin ORIGIN' */
2301 /* For origin set. */
2302 static route_map_result_t
route_set_origin(void *rule
,
2303 const struct prefix
*prefix
,
2304 route_map_object_t type
,
2308 struct bgp_path_info
*path
;
2310 if (type
== RMAP_BGP
) {
2314 path
->attr
->origin
= *origin
;
2320 /* Compile function for origin set. */
2321 static void *route_set_origin_compile(const char *arg
)
2325 origin
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
2327 if (strcmp(arg
, "igp") == 0)
2329 else if (strcmp(arg
, "egp") == 0)
2337 /* Compile function for origin set. */
2338 static void route_set_origin_free(void *rule
)
2340 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2343 /* Set origin rule structure. */
2344 struct route_map_rule_cmd route_set_origin_cmd
= {
2345 "origin", route_set_origin
, route_set_origin_compile
,
2346 route_set_origin_free
,
2349 /* `set atomic-aggregate' */
2351 /* For atomic aggregate set. */
2352 static route_map_result_t
route_set_atomic_aggregate(void *rule
,
2353 const struct prefix
*pfx
,
2354 route_map_object_t type
,
2357 struct bgp_path_info
*path
;
2359 if (type
== RMAP_BGP
) {
2361 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
2367 /* Compile function for atomic aggregate. */
2368 static void *route_set_atomic_aggregate_compile(const char *arg
)
2373 /* Compile function for atomic aggregate. */
2374 static void route_set_atomic_aggregate_free(void *rule
)
2379 /* Set atomic aggregate rule structure. */
2380 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
= {
2381 "atomic-aggregate", route_set_atomic_aggregate
,
2382 route_set_atomic_aggregate_compile
, route_set_atomic_aggregate_free
,
2385 /* `set aggregator as AS A.B.C.D' */
2388 struct in_addr address
;
2391 static route_map_result_t
route_set_aggregator_as(void *rule
,
2392 const struct prefix
*prefix
,
2393 route_map_object_t type
,
2396 struct bgp_path_info
*path
;
2397 struct aggregator
*aggregator
;
2399 if (type
== RMAP_BGP
) {
2403 path
->attr
->aggregator_as
= aggregator
->as
;
2404 path
->attr
->aggregator_addr
= aggregator
->address
;
2405 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
);
2411 static void *route_set_aggregator_as_compile(const char *arg
)
2413 struct aggregator
*aggregator
;
2419 XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct aggregator
));
2420 if (sscanf(arg
, "%s %s", as
, address
) != 2) {
2421 XFREE(MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2425 aggregator
->as
= strtoul(as
, NULL
, 10);
2426 ret
= inet_aton(address
, &aggregator
->address
);
2428 XFREE(MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2434 static void route_set_aggregator_as_free(void *rule
)
2436 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2439 struct route_map_rule_cmd route_set_aggregator_as_cmd
= {
2440 "aggregator as", route_set_aggregator_as
,
2441 route_set_aggregator_as_compile
, route_set_aggregator_as_free
,
2444 /* Set tag to object. object must be pointer to struct bgp_path_info */
2445 static route_map_result_t
route_set_tag(void *rule
,
2446 const struct prefix
*prefix
,
2447 route_map_object_t type
, void *object
)
2450 struct bgp_path_info
*path
;
2452 if (type
== RMAP_BGP
) {
2457 path
->attr
->tag
= *tag
;
2463 /* Route map commands for tag set. */
2464 static struct route_map_rule_cmd route_set_tag_cmd
= {
2465 "tag", route_set_tag
, route_map_rule_tag_compile
,
2466 route_map_rule_tag_free
,
2469 /* Set label-index to object. object must be pointer to struct bgp_path_info */
2470 static route_map_result_t
route_set_label_index(void *rule
,
2471 const struct prefix
*prefix
,
2472 route_map_object_t type
,
2475 struct rmap_value
*rv
;
2476 struct bgp_path_info
*path
;
2477 uint32_t label_index
;
2479 if (type
== RMAP_BGP
) {
2480 /* Fetch routemap's rule information. */
2484 /* Set label-index value. */
2485 label_index
= rv
->value
;
2487 path
->attr
->label_index
= label_index
;
2488 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
2495 /* Route map commands for label-index set. */
2496 static struct route_map_rule_cmd route_set_label_index_cmd
= {
2497 "label-index", route_set_label_index
, route_value_compile
,
2501 /* `match ipv6 address IP_ACCESS_LIST' */
2503 static route_map_result_t
route_match_ipv6_address(void *rule
,
2504 const struct prefix
*prefix
,
2505 route_map_object_t type
,
2508 struct access_list
*alist
;
2510 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET6
) {
2511 alist
= access_list_lookup(AFI_IP6
, (char *)rule
);
2513 return RMAP_NOMATCH
;
2515 return (access_list_apply(alist
, prefix
) == FILTER_DENY
2519 return RMAP_NOMATCH
;
2522 static void *route_match_ipv6_address_compile(const char *arg
)
2524 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
2527 static void route_match_ipv6_address_free(void *rule
)
2529 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2532 /* Route map commands for ip address matching. */
2533 struct route_map_rule_cmd route_match_ipv6_address_cmd
= {
2534 "ipv6 address", route_match_ipv6_address
,
2535 route_match_ipv6_address_compile
, route_match_ipv6_address_free
};
2537 /* `match ipv6 next-hop IP_ADDRESS' */
2539 static route_map_result_t
route_match_ipv6_next_hop(void *rule
,
2540 const struct prefix
*prefix
,
2541 route_map_object_t type
,
2544 struct in6_addr
*addr
= rule
;
2545 struct bgp_path_info
*path
;
2547 if (type
== RMAP_BGP
) {
2550 if (IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_global
, addr
))
2553 if (path
->attr
->mp_nexthop_len
2554 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
2555 && IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_local
, rule
))
2558 return RMAP_NOMATCH
;
2561 return RMAP_NOMATCH
;
2564 static void *route_match_ipv6_next_hop_compile(const char *arg
)
2566 struct in6_addr
*address
;
2569 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2571 ret
= inet_pton(AF_INET6
, arg
, address
);
2573 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2580 static void route_match_ipv6_next_hop_free(void *rule
)
2582 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2585 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
= {
2586 "ipv6 next-hop", route_match_ipv6_next_hop
,
2587 route_match_ipv6_next_hop_compile
, route_match_ipv6_next_hop_free
};
2589 /* `match ipv6 address prefix-list PREFIX_LIST' */
2591 static route_map_result_t
2592 route_match_ipv6_address_prefix_list(void *rule
, const struct prefix
*prefix
,
2593 route_map_object_t type
, void *object
)
2595 return route_match_address_prefix_list(rule
, AFI_IP6
, prefix
, type
,
2599 static void *route_match_ipv6_address_prefix_list_compile(const char *arg
)
2601 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
2604 static void route_match_ipv6_address_prefix_list_free(void *rule
)
2606 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2609 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
= {
2610 "ipv6 address prefix-list", route_match_ipv6_address_prefix_list
,
2611 route_match_ipv6_address_prefix_list_compile
,
2612 route_match_ipv6_address_prefix_list_free
};
2614 /* `match ipv6 next-hop type <TYPE>' */
2616 static route_map_result_t
2617 route_match_ipv6_next_hop_type(void *rule
, const struct prefix
*prefix
,
2618 route_map_object_t type
, void *object
)
2620 struct bgp_path_info
*path
;
2621 struct in6_addr
*addr
= rule
;
2623 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET6
) {
2624 path
= (struct bgp_path_info
*)object
;
2625 if (!path
|| !path
->attr
)
2626 return RMAP_DENYMATCH
;
2628 if (IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_global
, addr
)
2629 && !path
->attr
->nh_ifindex
)
2632 return RMAP_NOMATCH
;
2635 static void *route_match_ipv6_next_hop_type_compile(const char *arg
)
2637 struct in6_addr
*address
;
2640 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2642 ret
= inet_pton(AF_INET6
, "::0", address
);
2644 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2651 static void route_match_ipv6_next_hop_type_free(void *rule
)
2653 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2656 struct route_map_rule_cmd route_match_ipv6_next_hop_type_cmd
= {
2657 "ipv6 next-hop type", route_match_ipv6_next_hop_type
,
2658 route_match_ipv6_next_hop_type_compile
,
2659 route_match_ipv6_next_hop_type_free
};
2661 /* `set ipv6 nexthop global IP_ADDRESS' */
2663 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2664 static route_map_result_t
route_set_ipv6_nexthop_global(void *rule
,
2665 const struct prefix
*p
,
2666 route_map_object_t type
,
2669 struct in6_addr
*address
;
2670 struct bgp_path_info
*path
;
2672 if (type
== RMAP_BGP
) {
2673 /* Fetch routemap's rule information. */
2677 /* Set next hop value. */
2678 path
->attr
->mp_nexthop_global
= *address
;
2680 /* Set nexthop length. */
2681 if (path
->attr
->mp_nexthop_len
== 0)
2682 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2684 SET_FLAG(path
->attr
->rmap_change_flags
,
2685 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2691 /* Route map `ip next-hop' compile function. Given string is converted
2692 to struct in_addr structure. */
2693 static void *route_set_ipv6_nexthop_global_compile(const char *arg
)
2696 struct in6_addr
*address
;
2698 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2700 ret
= inet_pton(AF_INET6
, arg
, address
);
2703 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2710 /* Free route map's compiled `ip next-hop' value. */
2711 static void route_set_ipv6_nexthop_global_free(void *rule
)
2713 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2716 /* Route map commands for ip nexthop set. */
2717 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
= {
2718 "ipv6 next-hop global", route_set_ipv6_nexthop_global
,
2719 route_set_ipv6_nexthop_global_compile
,
2720 route_set_ipv6_nexthop_global_free
};
2722 /* Set next-hop preference value. */
2723 static route_map_result_t
2724 route_set_ipv6_nexthop_prefer_global(void *rule
, const struct prefix
*prefix
,
2725 route_map_object_t type
, void *object
)
2727 struct bgp_path_info
*path
;
2730 if (type
== RMAP_BGP
) {
2731 /* Fetch routemap's rule information. */
2735 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
2736 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2738 && sockunion_family(peer
->su_remote
) == AF_INET6
) {
2739 /* Set next hop preference to global */
2740 path
->attr
->mp_nexthop_prefer_global
= true;
2741 SET_FLAG(path
->attr
->rmap_change_flags
,
2742 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2744 path
->attr
->mp_nexthop_prefer_global
= false;
2745 SET_FLAG(path
->attr
->rmap_change_flags
,
2746 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2752 static void *route_set_ipv6_nexthop_prefer_global_compile(const char *arg
)
2756 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
2762 /* Free route map's compiled `ip next-hop' value. */
2763 static void route_set_ipv6_nexthop_prefer_global_free(void *rule
)
2765 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2768 /* Route map commands for ip nexthop set preferred. */
2769 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
= {
2770 "ipv6 next-hop prefer-global", route_set_ipv6_nexthop_prefer_global
,
2771 route_set_ipv6_nexthop_prefer_global_compile
,
2772 route_set_ipv6_nexthop_prefer_global_free
};
2774 /* `set ipv6 nexthop local IP_ADDRESS' */
2776 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2777 static route_map_result_t
route_set_ipv6_nexthop_local(void *rule
,
2778 const struct prefix
*p
,
2779 route_map_object_t type
,
2782 struct in6_addr
*address
;
2783 struct bgp_path_info
*path
;
2785 if (type
== RMAP_BGP
) {
2786 /* Fetch routemap's rule information. */
2790 /* Set next hop value. */
2791 path
->attr
->mp_nexthop_local
= *address
;
2793 /* Set nexthop length. */
2794 if (path
->attr
->mp_nexthop_len
2795 != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2796 path
->attr
->mp_nexthop_len
=
2797 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2799 SET_FLAG(path
->attr
->rmap_change_flags
,
2800 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2806 /* Route map `ip nexthop' compile function. Given string is converted
2807 to struct in_addr structure. */
2808 static void *route_set_ipv6_nexthop_local_compile(const char *arg
)
2811 struct in6_addr
*address
;
2813 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2815 ret
= inet_pton(AF_INET6
, arg
, address
);
2818 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2825 /* Free route map's compiled `ip nexthop' value. */
2826 static void route_set_ipv6_nexthop_local_free(void *rule
)
2828 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2831 /* Route map commands for ip nexthop set. */
2832 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
= {
2833 "ipv6 next-hop local", route_set_ipv6_nexthop_local
,
2834 route_set_ipv6_nexthop_local_compile
,
2835 route_set_ipv6_nexthop_local_free
};
2837 /* `set ipv6 nexthop peer-address' */
2839 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2840 static route_map_result_t
route_set_ipv6_nexthop_peer(void *rule
,
2841 const struct prefix
*pfx
,
2842 route_map_object_t type
,
2845 struct in6_addr peer_address
;
2846 struct bgp_path_info
*path
;
2849 if (type
== RMAP_BGP
) {
2850 /* Fetch routemap's rule information. */
2854 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
2855 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2857 && sockunion_family(peer
->su_remote
) == AF_INET6
) {
2858 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
2859 /* Set next hop value and length in attribute. */
2860 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
)) {
2861 path
->attr
->mp_nexthop_local
= peer_address
;
2862 if (path
->attr
->mp_nexthop_len
!= 32)
2863 path
->attr
->mp_nexthop_len
= 32;
2865 path
->attr
->mp_nexthop_global
= peer_address
;
2866 if (path
->attr
->mp_nexthop_len
== 0)
2867 path
->attr
->mp_nexthop_len
= 16;
2870 } else if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
)) {
2871 /* The next hop value will be set as part of packet
2873 * Set the flags here to indicate that rewrite needs to
2875 * Also, clear the value - we clear both global and
2877 * nexthops, whether we send one or both is determined
2880 SET_FLAG(path
->attr
->rmap_change_flags
,
2881 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2882 /* clear next hop value. */
2883 memset(&(path
->attr
->mp_nexthop_global
), 0,
2884 sizeof(struct in6_addr
));
2885 memset(&(path
->attr
->mp_nexthop_local
), 0,
2886 sizeof(struct in6_addr
));
2893 /* Route map `ip next-hop' compile function. Given string is converted
2894 to struct in_addr structure. */
2895 static void *route_set_ipv6_nexthop_peer_compile(const char *arg
)
2899 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
2905 /* Free route map's compiled `ip next-hop' value. */
2906 static void route_set_ipv6_nexthop_peer_free(void *rule
)
2908 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2911 /* Route map commands for ip nexthop set. */
2912 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
= {
2913 "ipv6 next-hop peer-address", route_set_ipv6_nexthop_peer
,
2914 route_set_ipv6_nexthop_peer_compile
, route_set_ipv6_nexthop_peer_free
};
2916 /* `set ipv4 vpn next-hop A.B.C.D' */
2918 static route_map_result_t
route_set_vpnv4_nexthop(void *rule
,
2919 const struct prefix
*prefix
,
2920 route_map_object_t type
,
2923 struct in_addr
*address
;
2924 struct bgp_path_info
*path
;
2926 if (type
== RMAP_BGP
) {
2927 /* Fetch routemap's rule information. */
2931 /* Set next hop value. */
2932 path
->attr
->mp_nexthop_global_in
= *address
;
2933 path
->attr
->mp_nexthop_len
= 4;
2939 static void *route_set_vpnv4_nexthop_compile(const char *arg
)
2942 struct in_addr
*address
;
2944 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
2946 ret
= inet_aton(arg
, address
);
2949 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2956 /* `set ipv6 vpn next-hop A.B.C.D' */
2958 static route_map_result_t
route_set_vpnv6_nexthop(void *rule
,
2959 const struct prefix
*prefix
,
2960 route_map_object_t type
,
2963 struct in6_addr
*address
;
2964 struct bgp_path_info
*path
;
2966 if (type
== RMAP_BGP
) {
2967 /* Fetch routemap's rule information. */
2971 /* Set next hop value. */
2972 memcpy(&path
->attr
->mp_nexthop_global
, address
,
2973 sizeof(struct in6_addr
));
2974 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_VPNV6_GLOBAL
;
2980 static void *route_set_vpnv6_nexthop_compile(const char *arg
)
2983 struct in6_addr
*address
;
2985 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2986 ret
= inet_pton(AF_INET6
, arg
, address
);
2989 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2996 static void route_set_vpn_nexthop_free(void *rule
)
2998 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3001 /* Route map commands for ipv4 next-hop set. */
3002 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
= {
3003 "ipv4 vpn next-hop", route_set_vpnv4_nexthop
,
3004 route_set_vpnv4_nexthop_compile
, route_set_vpn_nexthop_free
};
3006 /* Route map commands for ipv6 next-hop set. */
3007 struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd
= {
3008 "ipv6 vpn next-hop", route_set_vpnv6_nexthop
,
3009 route_set_vpnv6_nexthop_compile
, route_set_vpn_nexthop_free
};
3011 /* `set originator-id' */
3013 /* For origin set. */
3014 static route_map_result_t
route_set_originator_id(void *rule
,
3015 const struct prefix
*prefix
,
3016 route_map_object_t type
,
3019 struct in_addr
*address
;
3020 struct bgp_path_info
*path
;
3022 if (type
== RMAP_BGP
) {
3026 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
);
3027 path
->attr
->originator_id
= *address
;
3033 /* Compile function for originator-id set. */
3034 static void *route_set_originator_id_compile(const char *arg
)
3037 struct in_addr
*address
;
3039 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
3041 ret
= inet_aton(arg
, address
);
3044 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3051 /* Compile function for originator_id set. */
3052 static void route_set_originator_id_free(void *rule
)
3054 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3057 /* Set originator-id rule structure. */
3058 struct route_map_rule_cmd route_set_originator_id_cmd
= {
3059 "originator-id", route_set_originator_id
,
3060 route_set_originator_id_compile
, route_set_originator_id_free
,
3063 /* Add bgp route map rule. */
3064 static int bgp_route_match_add(struct vty
*vty
, const char *command
,
3065 const char *arg
, route_map_event_t type
)
3067 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
3068 int retval
= CMD_SUCCESS
;
3071 ret
= route_map_add_match(index
, command
, arg
, type
);
3073 case RMAP_RULE_MISSING
:
3074 vty_out(vty
, "%% BGP Can't find rule.\n");
3075 retval
= CMD_WARNING_CONFIG_FAILED
;
3077 case RMAP_COMPILE_ERROR
:
3078 vty_out(vty
, "%% BGP Argument is malformed.\n");
3079 retval
= CMD_WARNING_CONFIG_FAILED
;
3081 case RMAP_COMPILE_SUCCESS
:
3082 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
3083 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
3091 /* Delete bgp route map rule. */
3092 static int bgp_route_match_delete(struct vty
*vty
, const char *command
,
3093 const char *arg
, route_map_event_t type
)
3095 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
3097 int retval
= CMD_SUCCESS
;
3098 char *dep_name
= NULL
;
3100 char *rmap_name
= NULL
;
3102 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
3103 /* ignore the mundane, the types without any dependency */
3105 if ((tmpstr
= route_map_get_match_arg(index
, command
))
3108 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
3110 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
3112 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
3115 ret
= route_map_delete_match(index
, command
, dep_name
);
3117 case RMAP_RULE_MISSING
:
3118 vty_out(vty
, "%% BGP Can't find rule.\n");
3119 retval
= CMD_WARNING_CONFIG_FAILED
;
3121 case RMAP_COMPILE_ERROR
:
3122 vty_out(vty
, "%% BGP Argument is malformed.\n");
3123 retval
= CMD_WARNING_CONFIG_FAILED
;
3125 case RMAP_COMPILE_SUCCESS
:
3126 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
3127 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
3131 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
3132 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
3138 * This is the workhorse routine for processing in/out routemap
3141 static void bgp_route_map_process_peer(const char *rmap_name
,
3142 struct route_map
*map
, struct peer
*peer
,
3143 int afi
, int safi
, int route_update
)
3145 struct bgp_filter
*filter
;
3147 if (!peer
|| !rmap_name
)
3150 filter
= &peer
->filter
[afi
][safi
];
3152 * in is for non-route-server clients,
3153 * out is for all peers
3155 if (filter
->map
[RMAP_IN
].name
3156 && (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0)) {
3157 filter
->map
[RMAP_IN
].map
= map
;
3159 if (route_update
&& peer
->status
== Established
) {
3160 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
3161 PEER_FLAG_SOFT_RECONFIG
)) {
3162 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
3164 "Processing route_map %s update on peer %s (inbound, soft-reconfig)",
3165 rmap_name
, peer
->host
);
3167 bgp_soft_reconfig_in(peer
, afi
, safi
);
3168 } else if (CHECK_FLAG(peer
->cap
,
3169 PEER_CAP_REFRESH_OLD_RCV
)
3170 || CHECK_FLAG(peer
->cap
,
3171 PEER_CAP_REFRESH_NEW_RCV
)) {
3172 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
3174 "Processing route_map %s update on peer %s (inbound, route-refresh)",
3175 rmap_name
, peer
->host
);
3176 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
3183 * For outbound, unsuppress and default-originate map change (content or
3184 * map created), merely update the "config" here, the actual route
3185 * announcement happens at the group level.
3187 if (filter
->map
[RMAP_OUT
].name
3188 && (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
3189 filter
->map
[RMAP_OUT
].map
= map
;
3191 if (filter
->usmap
.name
&& (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3192 filter
->usmap
.map
= map
;
3194 if (peer
->default_rmap
[afi
][safi
].name
3195 && (strcmp(rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
3196 peer
->default_rmap
[afi
][safi
].map
= map
;
3199 static void bgp_route_map_update_peer_group(const char *rmap_name
,
3200 struct route_map
*map
,
3203 struct peer_group
*group
;
3204 struct listnode
*node
, *nnode
;
3205 struct bgp_filter
*filter
;
3212 /* All the peers have been updated correctly already. This is
3213 * just updating the placeholder data. No real update required.
3215 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
3216 FOREACH_AFI_SAFI (afi
, safi
) {
3217 filter
= &group
->conf
->filter
[afi
][safi
];
3219 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++) {
3220 if ((filter
->map
[direct
].name
)
3221 && (strcmp(rmap_name
,
3222 filter
->map
[direct
].name
)
3224 filter
->map
[direct
].map
= map
;
3227 if (filter
->usmap
.name
3228 && (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3229 filter
->usmap
.map
= map
;
3235 * Note that if an extreme number (tens of thousands) of route-maps are in use
3236 * and if bgp has an extreme number of peers, network statements, etc then this
3237 * function can consume a lot of cycles. This is due to this function being
3238 * called for each route-map and within this function we walk the list of peers,
3239 * network statements, etc looking to see if they use this route-map.
3241 static void bgp_route_map_process_update(struct bgp
*bgp
, const char *rmap_name
,
3248 struct bgp_node
*bn
;
3249 struct bgp_static
*bgp_static
;
3250 struct listnode
*node
, *nnode
;
3251 struct route_map
*map
;
3252 char buf
[INET6_ADDRSTRLEN
];
3254 map
= route_map_lookup_by_name(rmap_name
);
3256 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
3258 /* Ignore dummy peer-group structure */
3259 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3262 FOREACH_AFI_SAFI (afi
, safi
) {
3263 /* process in/out/import/export/default-orig
3265 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
,
3266 safi
, route_update
);
3270 /* for outbound/default-orig route-maps, process for groups */
3271 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
3274 /* update peer-group config (template) */
3275 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
3277 FOREACH_AFI_SAFI (afi
, safi
) {
3278 /* For table route-map updates. */
3279 if (!bgp_fibupd_safi(safi
))
3282 if (bgp
->table_map
[afi
][safi
].name
3283 && (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
)
3286 /* bgp->table_map[afi][safi].map is NULL.
3287 * i.e Route map creation event.
3288 * So update applied_counter.
3289 * If it is not NULL, i.e It may be routemap updation or
3290 * deletion. so no need to update the counter.
3292 if (!bgp
->table_map
[afi
][safi
].map
)
3293 route_map_counter_increment(map
);
3294 bgp
->table_map
[afi
][safi
].map
= map
;
3296 if (BGP_DEBUG(zebra
, ZEBRA
))
3298 "Processing route_map %s update on "
3302 bgp_zebra_announce_table(bgp
, afi
, safi
);
3305 /* For network route-map updates. */
3306 for (bn
= bgp_table_top(bgp
->route
[afi
][safi
]); bn
;
3307 bn
= bgp_route_next(bn
)) {
3308 bgp_static
= bgp_node_get_bgp_static_info(bn
);
3312 if (!bgp_static
->rmap
.name
3313 || (strcmp(rmap_name
, bgp_static
->rmap
.name
) != 0))
3316 if (!bgp_static
->rmap
.map
)
3317 route_map_counter_increment(map
);
3319 bgp_static
->rmap
.map
= map
;
3321 if (route_update
&& !bgp_static
->backdoor
) {
3322 if (bgp_debug_zebra(&bn
->p
))
3324 "Processing route_map %s update on static route %s",
3326 inet_ntop(bn
->p
.family
,
3327 &bn
->p
.u
.prefix
, buf
,
3329 bgp_static_update(bgp
, &bn
->p
, bgp_static
, afi
,
3335 /* For redistribute route-map updates. */
3336 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3337 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3338 struct list
*red_list
;
3339 struct bgp_redist
*red
;
3341 red_list
= bgp
->redist
[afi
][i
];
3345 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
)) {
3347 || (strcmp(rmap_name
, red
->rmap
.name
) != 0))
3351 route_map_counter_increment(map
);
3353 red
->rmap
.map
= map
;
3358 if (BGP_DEBUG(zebra
, ZEBRA
))
3360 "Processing route_map %s update on redistributed routes",
3363 bgp_redistribute_resend(bgp
, afi
, i
,
3368 /* for type5 command route-maps */
3369 FOREACH_AFI_SAFI (afi
, safi
) {
3370 if (!bgp
->adv_cmd_rmap
[afi
][safi
].name
3371 || strcmp(rmap_name
, bgp
->adv_cmd_rmap
[afi
][safi
].name
)
3375 /* Make sure the route-map is populated here if not already done */
3376 bgp
->adv_cmd_rmap
[afi
][safi
].map
= map
;
3378 if (BGP_DEBUG(zebra
, ZEBRA
))
3380 "Processing route_map %s update on advertise type5 route command",
3383 if (route_update
&& advertise_type5_routes(bgp
, afi
)) {
3384 bgp_evpn_withdraw_type5_routes(bgp
, afi
, safi
);
3385 bgp_evpn_advertise_type5_routes(bgp
, afi
, safi
);
3390 static void bgp_route_map_process_update_cb(char *rmap_name
)
3392 struct listnode
*node
, *nnode
;
3395 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
3396 bgp_route_map_process_update(bgp
, rmap_name
, 1);
3399 /* zlog_debug("%s: calling vnc_routemap_update", __func__); */
3400 vnc_routemap_update(bgp
, __func__
);
3404 vpn_policy_routemap_event(rmap_name
);
3407 int bgp_route_map_update_timer(struct thread
*thread
)
3409 bm
->t_rmap_update
= NULL
;
3411 route_map_walk_update_list(bgp_route_map_process_update_cb
);
3416 static void bgp_route_map_mark_update(const char *rmap_name
)
3418 if (bm
->t_rmap_update
== NULL
) {
3419 struct listnode
*node
, *nnode
;
3422 /* rmap_update_timer of 0 means don't do route updates */
3423 if (bm
->rmap_update_timer
) {
3424 bm
->t_rmap_update
= NULL
;
3425 thread_add_timer(bm
->master
, bgp_route_map_update_timer
,
3426 NULL
, bm
->rmap_update_timer
,
3427 &bm
->t_rmap_update
);
3429 /* Signal the groups that a route-map update event has
3431 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3432 update_group_policy_update(bgp
,
3433 BGP_POLICY_ROUTE_MAP
,
3436 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3437 bgp_route_map_process_update(bgp
, rmap_name
, 0);
3439 zlog_debug("%s: calling vnc_routemap_update", __func__
);
3440 vnc_routemap_update(bgp
, __func__
);
3446 static void bgp_route_map_add(const char *rmap_name
)
3448 if (route_map_mark_updated(rmap_name
) == 0)
3449 bgp_route_map_mark_update(rmap_name
);
3451 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3454 static void bgp_route_map_delete(const char *rmap_name
)
3456 if (route_map_mark_updated(rmap_name
) == 0)
3457 bgp_route_map_mark_update(rmap_name
);
3459 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
3462 static void bgp_route_map_event(const char *rmap_name
)
3464 if (route_map_mark_updated(rmap_name
) == 0)
3465 bgp_route_map_mark_update(rmap_name
);
3467 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3470 DEFUN (match_mac_address
,
3471 match_mac_address_cmd
,
3472 "match mac address WORD",
3475 "Match address of route\n"
3476 "MAC Access-list name\n")
3478 return bgp_route_match_add(vty
, "mac address", argv
[3]->arg
,
3479 RMAP_EVENT_FILTER_ADDED
);
3482 DEFUN (no_match_mac_address
,
3483 no_match_mac_address_cmd
,
3484 "no match mac address WORD",
3488 "Match address of route\n"
3489 "MAC acess-list name\n")
3491 return bgp_route_match_delete(vty
, "mac address", argv
[4]->arg
,
3492 RMAP_EVENT_FILTER_DELETED
);
3495 DEFUN (match_evpn_route_type
,
3496 match_evpn_route_type_cmd
,
3497 "match evpn route-type <macip | multicast | prefix>",
3500 "Match route-type\n"
3505 return bgp_route_match_add(vty
, "evpn route-type", argv
[3]->arg
,
3506 RMAP_EVENT_MATCH_ADDED
);
3509 DEFUN (no_match_evpn_route_type
,
3510 no_match_evpn_route_type_cmd
,
3511 "no match evpn route-type <macip | multicast | prefix>",
3515 "Match route-type\n"
3520 return bgp_route_match_delete(vty
, "evpn route-type", argv
[4]->arg
,
3521 RMAP_EVENT_MATCH_DELETED
);
3525 DEFUN (match_evpn_vni
,
3527 "match evpn vni " CMD_VNI_RANGE
,
3533 return bgp_route_match_add(vty
, "evpn vni", argv
[3]->arg
,
3534 RMAP_EVENT_MATCH_ADDED
);
3537 DEFUN (no_match_evpn_vni
,
3538 no_match_evpn_vni_cmd
,
3539 "no match evpn vni " CMD_VNI_RANGE
,
3546 return bgp_route_match_delete(vty
, "evpn vni", argv
[4]->arg
,
3547 RMAP_EVENT_MATCH_DELETED
);
3550 DEFUN (match_evpn_default_route
,
3551 match_evpn_default_route_cmd
,
3552 "match evpn default-route",
3555 "default EVPN type-5 route\n")
3557 return bgp_route_match_add(vty
, "evpn default-route", NULL
,
3558 RMAP_EVENT_MATCH_ADDED
);
3561 DEFUN (no_match_evpn_default_route
,
3562 no_match_evpn_default_route_cmd
,
3563 "no match evpn default-route",
3567 "default EVPN type-5 route\n")
3569 return bgp_route_match_delete(vty
, "evpn default-route", NULL
,
3570 RMAP_EVENT_MATCH_DELETED
);
3573 DEFPY(match_vrl_source_vrf
,
3574 match_vrl_source_vrf_cmd
,
3575 "match source-vrf NAME$vrf_name",
3580 return bgp_route_match_add(vty
, "source-vrf", vrf_name
,
3581 RMAP_EVENT_MATCH_ADDED
);
3584 DEFPY(no_match_vrl_source_vrf
,
3585 no_match_vrl_source_vrf_cmd
,
3586 "no match source-vrf NAME$vrf_name",
3592 return bgp_route_match_delete(vty
, "source-vrf", vrf_name
,
3593 RMAP_EVENT_MATCH_DELETED
);
3598 "match peer <A.B.C.D|X:X::X:X|WORD>",
3600 "Match peer address\n"
3601 "IP address of peer\n"
3602 "IPv6 address of peer\n"
3603 "Interface name of peer\n")
3606 return bgp_route_match_add(vty
, "peer", argv
[idx_ip
]->arg
,
3607 RMAP_EVENT_MATCH_ADDED
);
3610 DEFUN (match_peer_local
,
3611 match_peer_local_cmd
,
3614 "Match peer address\n"
3615 "Static or Redistributed routes\n")
3617 return bgp_route_match_add(vty
, "peer", "local",
3618 RMAP_EVENT_MATCH_DELETED
);
3621 DEFUN (no_match_peer
,
3623 "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
3626 "Match peer address\n"
3627 "Static or Redistributed routes\n"
3628 "IP address of peer\n"
3629 "IPv6 address of peer\n"
3630 "Interface name of peer\n")
3634 if (argc
<= idx_peer
)
3635 return bgp_route_match_delete(vty
, "peer", NULL
,
3636 RMAP_EVENT_MATCH_DELETED
);
3637 return bgp_route_match_delete(vty
, "peer", argv
[idx_peer
]->arg
,
3638 RMAP_EVENT_MATCH_DELETED
);
3641 #if defined(HAVE_LUA)
3642 DEFUN (match_command
,
3644 "match command WORD",
3646 "Run a command to match\n"
3647 "The command to run\n")
3649 return bgp_route_match_add(vty
, "command", argv
[2]->arg
,
3650 RMAP_EVENT_FILTER_ADDED
);
3653 DEFUN (no_match_command
,
3654 no_match_command_cmd
,
3655 "no match command WORD",
3658 "Run a command to match\n"
3659 "The command to run\n")
3661 return bgp_route_match_delete(vty
, "command", argv
[3]->arg
,
3662 RMAP_EVENT_FILTER_DELETED
);
3666 /* match probability */
3667 DEFUN (match_probability
,
3668 match_probability_cmd
,
3669 "match probability (0-100)",
3671 "Match portion of routes defined by percentage value\n"
3672 "Percentage of routes\n")
3675 return bgp_route_match_add(vty
, "probability", argv
[idx_number
]->arg
,
3676 RMAP_EVENT_MATCH_ADDED
);
3680 DEFUN (no_match_probability
,
3681 no_match_probability_cmd
,
3682 "no match probability [(1-99)]",
3685 "Match portion of routes defined by percentage value\n"
3686 "Percentage of routes\n")
3689 if (argc
<= idx_number
)
3690 return bgp_route_match_delete(vty
, "probability", NULL
,
3691 RMAP_EVENT_MATCH_DELETED
);
3692 return bgp_route_match_delete(vty
, "probability", argv
[idx_number
]->arg
,
3693 RMAP_EVENT_MATCH_DELETED
);
3697 DEFUN (match_ip_route_source
,
3698 match_ip_route_source_cmd
,
3699 "match ip route-source <(1-199)|(1300-2699)|WORD>",
3702 "Match advertising source address of route\n"
3703 "IP access-list number\n"
3704 "IP access-list number (expanded range)\n"
3705 "IP standard access-list name\n")
3708 return bgp_route_match_add(vty
, "ip route-source", argv
[idx_acl
]->arg
,
3709 RMAP_EVENT_FILTER_ADDED
);
3713 DEFUN (no_match_ip_route_source
,
3714 no_match_ip_route_source_cmd
,
3715 "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
3719 "Match advertising source address of route\n"
3720 "IP access-list number\n"
3721 "IP access-list number (expanded range)\n"
3722 "IP standard access-list name\n")
3725 if (argc
<= idx_number
)
3726 return bgp_route_match_delete(vty
, "ip route-source", NULL
,
3727 RMAP_EVENT_FILTER_DELETED
);
3728 return bgp_route_match_delete(vty
, "ip route-source",
3729 argv
[idx_number
]->arg
,
3730 RMAP_EVENT_FILTER_DELETED
);
3734 DEFUN (match_ip_route_source_prefix_list
,
3735 match_ip_route_source_prefix_list_cmd
,
3736 "match ip route-source prefix-list WORD",
3739 "Match advertising source address of route\n"
3740 "Match entries of prefix-lists\n"
3741 "IP prefix-list name\n")
3744 return bgp_route_match_add(vty
, "ip route-source prefix-list",
3745 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3749 DEFUN (no_match_ip_route_source_prefix_list
,
3750 no_match_ip_route_source_prefix_list_cmd
,
3751 "no match ip route-source prefix-list [WORD]",
3755 "Match advertising source address of route\n"
3756 "Match entries of prefix-lists\n"
3757 "IP prefix-list name\n")
3760 if (argc
<= idx_word
)
3761 return bgp_route_match_delete(vty
,
3762 "ip route-source prefix-list",
3763 NULL
, RMAP_EVENT_PLIST_DELETED
);
3764 return bgp_route_match_delete(vty
, "ip route-source prefix-list",
3765 argv
[idx_word
]->arg
,
3766 RMAP_EVENT_PLIST_DELETED
);
3770 DEFUN (match_local_pref
,
3771 match_local_pref_cmd
,
3772 "match local-preference (0-4294967295)",
3774 "Match local-preference of route\n"
3778 return bgp_route_match_add(vty
, "local-preference",
3779 argv
[idx_number
]->arg
,
3780 RMAP_EVENT_MATCH_ADDED
);
3784 DEFUN (no_match_local_pref
,
3785 no_match_local_pref_cmd
,
3786 "no match local-preference [(0-4294967295)]",
3789 "Match local preference of route\n"
3790 "Local preference value\n")
3792 int idx_localpref
= 3;
3793 if (argc
<= idx_localpref
)
3794 return bgp_route_match_delete(vty
, "local-preference", NULL
,
3795 RMAP_EVENT_MATCH_DELETED
);
3796 return bgp_route_match_delete(vty
, "local-preference",
3797 argv
[idx_localpref
]->arg
,
3798 RMAP_EVENT_MATCH_DELETED
);
3802 DEFUN (match_community
,
3803 match_community_cmd
,
3804 "match community <(1-99)|(100-500)|WORD> [exact-match]",
3806 "Match BGP community list\n"
3807 "Community-list number (standard)\n"
3808 "Community-list number (expanded)\n"
3809 "Community-list name\n"
3810 "Do exact matching of communities\n")
3812 int idx_comm_list
= 2;
3817 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
3818 strlen(argv
[idx_comm_list
]->arg
)
3819 + strlen("exact-match") + 2);
3821 sprintf(argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3823 argstr
= argv
[idx_comm_list
]->arg
;
3825 ret
= bgp_route_match_add(vty
, "community", argstr
,
3826 RMAP_EVENT_CLIST_ADDED
);
3828 if (argstr
!= argv
[idx_comm_list
]->arg
)
3829 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3834 DEFUN (no_match_community
,
3835 no_match_community_cmd
,
3836 "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
3839 "Match BGP community list\n"
3840 "Community-list number (standard)\n"
3841 "Community-list number (expanded)\n"
3842 "Community-list name\n"
3843 "Do exact matching of communities\n")
3845 return bgp_route_match_delete(vty
, "community", NULL
,
3846 RMAP_EVENT_CLIST_DELETED
);
3849 DEFUN (match_lcommunity
,
3850 match_lcommunity_cmd
,
3851 "match large-community <(1-99)|(100-500)|WORD> [exact-match]",
3853 "Match BGP large community list\n"
3854 "Large Community-list number (standard)\n"
3855 "Large Community-list number (expanded)\n"
3856 "Large Community-list name\n"
3857 "Do exact matching of communities\n")
3859 int idx_lcomm_list
= 2;
3864 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
3865 strlen(argv
[idx_lcomm_list
]->arg
)
3866 + strlen("exact-match") + 2);
3868 sprintf(argstr
, "%s exact-match", argv
[idx_lcomm_list
]->arg
);
3870 argstr
= argv
[idx_lcomm_list
]->arg
;
3872 ret
= bgp_route_match_add(vty
, "large-community", argstr
,
3873 RMAP_EVENT_LLIST_ADDED
);
3874 if (argstr
!= argv
[idx_lcomm_list
]->arg
)
3875 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3880 DEFUN (no_match_lcommunity
,
3881 no_match_lcommunity_cmd
,
3882 "no match large-community [<(1-99)|(100-500)|WORD> [exact-match]]",
3885 "Match BGP large community list\n"
3886 "Large Community-list number (standard)\n"
3887 "Large Community-list number (expanded)\n"
3888 "Large Community-list name\n"
3889 "Do exact matching of communities\n")
3891 return bgp_route_match_delete(vty
, "large-community", NULL
,
3892 RMAP_EVENT_LLIST_DELETED
);
3895 DEFUN (match_ecommunity
,
3896 match_ecommunity_cmd
,
3897 "match extcommunity <(1-99)|(100-500)|WORD>",
3899 "Match BGP/VPN extended community list\n"
3900 "Extended community-list number (standard)\n"
3901 "Extended community-list number (expanded)\n"
3902 "Extended community-list name\n")
3904 int idx_comm_list
= 2;
3905 return bgp_route_match_add(vty
, "extcommunity",
3906 argv
[idx_comm_list
]->arg
,
3907 RMAP_EVENT_ECLIST_ADDED
);
3911 DEFUN (no_match_ecommunity
,
3912 no_match_ecommunity_cmd
,
3913 "no match extcommunity [<(1-99)|(100-500)|WORD>]",
3916 "Match BGP/VPN extended community list\n"
3917 "Extended community-list number (standard)\n"
3918 "Extended community-list number (expanded)\n"
3919 "Extended community-list name\n")
3921 return bgp_route_match_delete(vty
, "extcommunity", NULL
,
3922 RMAP_EVENT_ECLIST_DELETED
);
3926 DEFUN (match_aspath
,
3928 "match as-path WORD",
3930 "Match BGP AS path list\n"
3931 "AS path access-list name\n")
3934 return bgp_route_match_add(vty
, "as-path", argv
[idx_word
]->arg
,
3935 RMAP_EVENT_ASLIST_ADDED
);
3939 DEFUN (no_match_aspath
,
3940 no_match_aspath_cmd
,
3941 "no match as-path [WORD]",
3944 "Match BGP AS path list\n"
3945 "AS path access-list name\n")
3947 return bgp_route_match_delete(vty
, "as-path", NULL
,
3948 RMAP_EVENT_ASLIST_DELETED
);
3952 DEFUN (match_origin
,
3954 "match origin <egp|igp|incomplete>",
3959 "unknown heritage\n")
3962 if (strncmp(argv
[idx_origin
]->arg
, "igp", 2) == 0)
3963 return bgp_route_match_add(vty
, "origin", "igp",
3964 RMAP_EVENT_MATCH_ADDED
);
3965 if (strncmp(argv
[idx_origin
]->arg
, "egp", 1) == 0)
3966 return bgp_route_match_add(vty
, "origin", "egp",
3967 RMAP_EVENT_MATCH_ADDED
);
3968 if (strncmp(argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3969 return bgp_route_match_add(vty
, "origin", "incomplete",
3970 RMAP_EVENT_MATCH_ADDED
);
3972 vty_out(vty
, "%% Invalid match origin type\n");
3973 return CMD_WARNING_CONFIG_FAILED
;
3977 DEFUN (no_match_origin
,
3978 no_match_origin_cmd
,
3979 "no match origin [<egp|igp|incomplete>]",
3985 "unknown heritage\n")
3987 return bgp_route_match_delete(vty
, "origin", NULL
,
3988 RMAP_EVENT_MATCH_DELETED
);
3991 DEFUN (set_ip_nexthop_peer
,
3992 set_ip_nexthop_peer_cmd
,
3993 "[no] set ip next-hop peer-address",
3997 "Next hop address\n"
3998 "Use peer address (for BGP only)\n")
4000 int (*func
)(struct vty
*, struct route_map_index
*, const char *,
4001 const char *) = strmatch(argv
[0]->text
, "no")
4002 ? generic_set_delete
4005 return func(vty
, VTY_GET_CONTEXT(route_map_index
), "ip next-hop",
4009 DEFUN (set_ip_nexthop_unchanged
,
4010 set_ip_nexthop_unchanged_cmd
,
4011 "[no] set ip next-hop unchanged",
4015 "Next hop address\n"
4016 "Don't modify existing Next hop address\n")
4018 int (*func
)(struct vty
*, struct route_map_index
*, const char *,
4019 const char *) = strmatch(argv
[0]->text
, "no")
4020 ? generic_set_delete
4023 return func(vty
, VTY_GET_CONTEXT(route_map_index
), "ip next-hop",
4028 DEFUN (set_local_pref
,
4030 "set local-preference (0-4294967295)",
4032 "BGP local preference path attribute\n"
4033 "Preference value\n")
4036 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4037 "local-preference", argv
[idx_number
]->arg
);
4041 DEFUN (no_set_local_pref
,
4042 no_set_local_pref_cmd
,
4043 "no set local-preference [(0-4294967295)]",
4046 "BGP local preference path attribute\n"
4047 "Preference value\n")
4049 int idx_localpref
= 3;
4050 if (argc
<= idx_localpref
)
4051 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4052 "local-preference", NULL
);
4053 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4054 "local-preference", argv
[idx_localpref
]->arg
);
4060 "set weight (0-4294967295)",
4062 "BGP weight for routing table\n"
4066 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
4067 argv
[idx_number
]->arg
);
4071 DEFUN (no_set_weight
,
4073 "no set weight [(0-4294967295)]",
4076 "BGP weight for routing table\n"
4080 if (argc
<= idx_weight
)
4081 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4083 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4084 "weight", argv
[idx_weight
]->arg
);
4087 DEFUN (set_label_index
,
4088 set_label_index_cmd
,
4089 "set label-index (0-1048560)",
4091 "Label index to associate with the prefix\n"
4092 "Label index value\n")
4095 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4096 "label-index", argv
[idx_number
]->arg
);
4099 DEFUN (no_set_label_index
,
4100 no_set_label_index_cmd
,
4101 "no set label-index [(0-1048560)]",
4104 "Label index to associate with the prefix\n"
4105 "Label index value\n")
4107 int idx_label_index
= 3;
4108 if (argc
<= idx_label_index
)
4109 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4110 "label-index", NULL
);
4111 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4112 "label-index", argv
[idx_label_index
]->arg
);
4115 DEFUN (set_aspath_prepend_asn
,
4116 set_aspath_prepend_asn_cmd
,
4117 "set as-path prepend (1-4294967295)...",
4119 "Transform BGP AS_PATH attribute\n"
4120 "Prepend to the as-path\n"
4127 str
= argv_concat(argv
, argc
, idx_asn
);
4128 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4129 "as-path prepend", str
);
4130 XFREE(MTYPE_TMP
, str
);
4135 DEFUN (set_aspath_prepend_lastas
,
4136 set_aspath_prepend_lastas_cmd
,
4137 "set as-path prepend last-as (1-10)",
4139 "Transform BGP AS_PATH attribute\n"
4140 "Prepend to the as-path\n"
4141 "Use the peer's AS-number\n"
4142 "Number of times to insert\n")
4144 return set_aspath_prepend_asn(self
, vty
, argc
, argv
);
4147 DEFUN (no_set_aspath_prepend
,
4148 no_set_aspath_prepend_cmd
,
4149 "no set as-path prepend [(1-4294967295)]",
4152 "Transform BGP AS_PATH attribute\n"
4153 "Prepend to the as-path\n"
4160 str
= argv_concat(argv
, argc
, idx_asn
);
4161 ret
= generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4162 "as-path prepend", str
);
4163 XFREE(MTYPE_TMP
, str
);
4168 DEFUN (set_aspath_exclude
,
4169 set_aspath_exclude_cmd
,
4170 "set as-path exclude (1-4294967295)...",
4172 "Transform BGP AS-path attribute\n"
4173 "Exclude from the as-path\n"
4180 str
= argv_concat(argv
, argc
, idx_asn
);
4181 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4182 "as-path exclude", str
);
4183 XFREE(MTYPE_TMP
, str
);
4187 DEFUN (no_set_aspath_exclude
,
4188 no_set_aspath_exclude_cmd
,
4189 "no set as-path exclude (1-4294967295)...",
4192 "Transform BGP AS_PATH attribute\n"
4193 "Exclude from the as-path\n"
4200 str
= argv_concat(argv
, argc
, idx_asn
);
4201 ret
= generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4202 "as-path exclude", str
);
4203 XFREE(MTYPE_TMP
, str
);
4207 ALIAS(no_set_aspath_exclude
, no_set_aspath_exclude_all_cmd
,
4208 "no set as-path exclude",
4210 "Transform BGP AS_PATH attribute\n"
4211 "Exclude from the as-path\n")
4213 DEFUN (set_community
,
4215 "set community AA:NN...",
4217 "BGP community attribute\n"
4225 struct community
*com
= NULL
;
4230 b
= buffer_new(1024);
4232 for (i
= idx_aa_nn
; i
< argc
; i
++) {
4233 if (strncmp(argv
[i
]->arg
, "additive", strlen(argv
[i
]->arg
))
4240 buffer_putc(b
, ' ');
4244 if (strncmp(argv
[i
]->arg
, "internet", strlen(argv
[i
]->arg
))
4246 buffer_putstr(b
, "internet");
4249 if (strncmp(argv
[i
]->arg
, "local-AS", strlen(argv
[i
]->arg
))
4251 buffer_putstr(b
, "local-AS");
4254 if (strncmp(argv
[i
]->arg
, "no-a", strlen("no-a")) == 0
4255 && strncmp(argv
[i
]->arg
, "no-advertise",
4256 strlen(argv
[i
]->arg
))
4258 buffer_putstr(b
, "no-advertise");
4261 if (strncmp(argv
[i
]->arg
, "no-e", strlen("no-e")) == 0
4262 && strncmp(argv
[i
]->arg
, "no-export", strlen(argv
[i
]->arg
))
4264 buffer_putstr(b
, "no-export");
4267 if (strncmp(argv
[i
]->arg
, "graceful-shutdown",
4268 strlen(argv
[i
]->arg
))
4270 buffer_putstr(b
, "graceful-shutdown");
4273 buffer_putstr(b
, argv
[i
]->arg
);
4275 buffer_putc(b
, '\0');
4277 /* Fetch result string then compile it to communities attribute. */
4278 str
= buffer_getstr(b
);
4282 com
= community_str2com(str
);
4283 XFREE(MTYPE_TMP
, str
);
4286 /* Can't compile user input into communities attribute. */
4288 vty_out(vty
, "%% Malformed communities attribute\n");
4289 return CMD_WARNING_CONFIG_FAILED
;
4292 /* Set communites attribute string. */
4293 str
= community_str(com
, false);
4296 size_t argstr_sz
= strlen(str
) + strlen(" additive") + 1;
4297 argstr
= XCALLOC(MTYPE_TMP
, argstr_sz
);
4298 strlcpy(argstr
, str
, argstr_sz
);
4299 strlcat(argstr
, " additive", argstr_sz
);
4300 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4301 "community", argstr
);
4302 XFREE(MTYPE_TMP
, argstr
);
4304 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4307 community_free(&com
);
4312 DEFUN (set_community_none
,
4313 set_community_none_cmd
,
4314 "set community none",
4316 "BGP community attribute\n"
4317 "No community attribute\n")
4319 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4320 "community", "none");
4323 DEFUN (no_set_community
,
4324 no_set_community_cmd
,
4325 "no set community AA:NN...",
4328 "BGP community attribute\n"
4331 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4335 ALIAS (no_set_community
,
4336 no_set_community_short_cmd
,
4340 "BGP community attribute\n")
4343 DEFUN (set_community_delete
,
4344 set_community_delete_cmd
,
4345 "set comm-list <(1-99)|(100-500)|WORD> delete",
4347 "set BGP community list (for deletion)\n"
4348 "Community-list number (standard)\n"
4349 "Community-list number (expanded)\n"
4350 "Community-list name\n"
4351 "Delete matching communities\n")
4353 int idx_comm_list
= 2;
4356 args
= argv_concat(argv
, argc
, idx_comm_list
);
4357 generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
), "comm-list",
4359 XFREE(MTYPE_TMP
, args
);
4364 DEFUN (no_set_community_delete
,
4365 no_set_community_delete_cmd
,
4366 "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
4369 "set BGP community list (for deletion)\n"
4370 "Community-list number (standard)\n"
4371 "Community-list number (expanded)\n"
4372 "Community-list name\n"
4373 "Delete matching communities\n")
4375 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4379 DEFUN (set_lcommunity
,
4381 "set large-community AA:BB:CC...",
4383 "BGP large community attribute\n"
4384 "Large Community number in aa:bb:cc format or additive\n")
4389 str
= argv_concat(argv
, argc
, 2);
4390 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4391 "large-community", str
);
4392 XFREE(MTYPE_TMP
, str
);
4397 DEFUN (set_lcommunity_none
,
4398 set_lcommunity_none_cmd
,
4399 "set large-community none",
4401 "BGP large community attribute\n"
4402 "No large community attribute\n")
4404 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4405 "large-community", "none");
4408 DEFUN (no_set_lcommunity
,
4409 no_set_lcommunity_cmd
,
4410 "no set large-community none",
4413 "BGP large community attribute\n"
4414 "No community attribute\n")
4416 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4417 "large-community", NULL
);
4420 DEFUN (no_set_lcommunity1
,
4421 no_set_lcommunity1_cmd
,
4422 "no set large-community AA:BB:CC...",
4425 "BGP large community attribute\n"
4426 "Large community in AA:BB:CC... format or additive\n")
4428 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4429 "large-community", NULL
);
4432 ALIAS (no_set_lcommunity1
,
4433 no_set_lcommunity1_short_cmd
,
4434 "no set large-community",
4437 "BGP large community attribute\n")
4439 DEFUN (set_lcommunity_delete
,
4440 set_lcommunity_delete_cmd
,
4441 "set large-comm-list <(1-99)|(100-500)|WORD> delete",
4443 "set BGP large community list (for deletion)\n"
4444 "Large Community-list number (standard)\n"
4445 "Large Communitly-list number (expanded)\n"
4446 "Large Community-list name\n"
4447 "Delete matching large communities\n")
4449 int idx_lcomm_list
= 2;
4452 args
= argv_concat(argv
, argc
, idx_lcomm_list
);
4453 generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4454 "large-comm-list", args
);
4455 XFREE(MTYPE_TMP
, args
);
4460 DEFUN (no_set_lcommunity_delete
,
4461 no_set_lcommunity_delete_cmd
,
4462 "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
4465 "set BGP large community list (for deletion)\n"
4466 "Large Community-list number (standard)\n"
4467 "Large Communitly-list number (expanded)\n"
4468 "Large Community-list name\n"
4469 "Delete matching large communities\n")
4471 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4472 "large-comm-list", NULL
);
4475 ALIAS (no_set_lcommunity_delete
,
4476 no_set_lcommunity_delete_short_cmd
,
4477 "no set large-comm-list",
4480 "set BGP large community list (for deletion)\n")
4482 DEFUN (set_ecommunity_rt
,
4483 set_ecommunity_rt_cmd
,
4484 "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
4486 "BGP extended community attribute\n"
4487 "Route Target extended community\n"
4488 "VPN extended community\n")
4494 str
= argv_concat(argv
, argc
, idx_asn_nn
);
4495 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4496 "extcommunity rt", str
);
4497 XFREE(MTYPE_TMP
, str
);
4502 DEFUN (no_set_ecommunity_rt
,
4503 no_set_ecommunity_rt_cmd
,
4504 "no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
4507 "BGP extended community attribute\n"
4508 "Route Target extended community\n"
4509 "VPN extended community\n")
4511 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4512 "extcommunity rt", NULL
);
4515 ALIAS (no_set_ecommunity_rt
,
4516 no_set_ecommunity_rt_short_cmd
,
4517 "no set extcommunity rt",
4520 "BGP extended community attribute\n"
4521 "Route Target extended community\n")
4523 DEFUN (set_ecommunity_soo
,
4524 set_ecommunity_soo_cmd
,
4525 "set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
4527 "BGP extended community attribute\n"
4528 "Site-of-Origin extended community\n"
4529 "VPN extended community\n")
4535 str
= argv_concat(argv
, argc
, idx_asn_nn
);
4536 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4537 "extcommunity soo", str
);
4538 XFREE(MTYPE_TMP
, str
);
4543 DEFUN (no_set_ecommunity_soo
,
4544 no_set_ecommunity_soo_cmd
,
4545 "no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
4548 "BGP extended community attribute\n"
4549 "Site-of-Origin extended community\n"
4550 "VPN extended community\n")
4552 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4553 "extcommunity soo", NULL
);
4556 ALIAS (no_set_ecommunity_soo
,
4557 no_set_ecommunity_soo_short_cmd
,
4558 "no set extcommunity soo",
4561 "GP extended community attribute\n"
4562 "Site-of-Origin extended community\n")
4566 "set origin <egp|igp|incomplete>",
4571 "unknown heritage\n")
4574 if (strncmp(argv
[idx_origin
]->arg
, "igp", 2) == 0)
4575 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4577 if (strncmp(argv
[idx_origin
]->arg
, "egp", 1) == 0)
4578 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4580 if (strncmp(argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
4581 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4582 "origin", "incomplete");
4584 vty_out(vty
, "%% Invalid set origin type\n");
4585 return CMD_WARNING_CONFIG_FAILED
;
4589 DEFUN (no_set_origin
,
4591 "no set origin [<egp|igp|incomplete>]",
4597 "unknown heritage\n")
4599 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4604 DEFUN (set_atomic_aggregate
,
4605 set_atomic_aggregate_cmd
,
4606 "set atomic-aggregate",
4608 "BGP atomic aggregate attribute\n" )
4610 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4611 "atomic-aggregate", NULL
);
4614 DEFUN (no_set_atomic_aggregate
,
4615 no_set_atomic_aggregate_cmd
,
4616 "no set atomic-aggregate",
4619 "BGP atomic aggregate attribute\n" )
4621 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4622 "atomic-aggregate", NULL
);
4625 DEFUN (set_aggregator_as
,
4626 set_aggregator_as_cmd
,
4627 "set aggregator as (1-4294967295) A.B.C.D",
4629 "BGP aggregator attribute\n"
4630 "AS number of aggregator\n"
4632 "IP address of aggregator\n")
4637 struct in_addr address
;
4640 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &address
);
4642 vty_out(vty
, "Aggregator IP address is invalid\n");
4643 return CMD_WARNING_CONFIG_FAILED
;
4646 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
4647 strlen(argv
[idx_number
]->arg
)
4648 + strlen(argv
[idx_ipv4
]->arg
) + 2);
4650 sprintf(argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
4652 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4653 "aggregator as", argstr
);
4655 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4661 DEFUN (no_set_aggregator_as
,
4662 no_set_aggregator_as_cmd
,
4663 "no set aggregator as [(1-4294967295) A.B.C.D]",
4666 "BGP aggregator attribute\n"
4667 "AS number of aggregator\n"
4669 "IP address of aggregator\n")
4674 struct in_addr address
;
4677 if (argc
<= idx_asn
)
4678 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4679 "aggregator as", NULL
);
4681 ret
= inet_aton(argv
[idx_ip
]->arg
, &address
);
4683 vty_out(vty
, "Aggregator IP address is invalid\n");
4684 return CMD_WARNING_CONFIG_FAILED
;
4687 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
4688 strlen(argv
[idx_asn
]->arg
) + strlen(argv
[idx_ip
]->arg
)
4691 sprintf(argstr
, "%s %s", argv
[idx_asn
]->arg
, argv
[idx_ip
]->arg
);
4693 ret
= generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4694 "aggregator as", argstr
);
4696 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4701 DEFUN (match_ipv6_next_hop
,
4702 match_ipv6_next_hop_cmd
,
4703 "match ipv6 next-hop X:X::X:X",
4706 "Match IPv6 next-hop address of route\n"
4707 "IPv6 address of next hop\n")
4710 return bgp_route_match_add(vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4711 RMAP_EVENT_MATCH_ADDED
);
4714 DEFUN (no_match_ipv6_next_hop
,
4715 no_match_ipv6_next_hop_cmd
,
4716 "no match ipv6 next-hop X:X::X:X",
4720 "Match IPv6 next-hop address of route\n"
4721 "IPv6 address of next hop\n")
4724 return bgp_route_match_delete(vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4725 RMAP_EVENT_MATCH_DELETED
);
4729 DEFUN (set_ipv6_nexthop_peer
,
4730 set_ipv6_nexthop_peer_cmd
,
4731 "set ipv6 next-hop peer-address",
4734 "Next hop address\n"
4735 "Use peer address (for BGP only)\n")
4737 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4738 "ipv6 next-hop peer-address", NULL
);
4741 DEFUN (no_set_ipv6_nexthop_peer
,
4742 no_set_ipv6_nexthop_peer_cmd
,
4743 "no set ipv6 next-hop peer-address",
4747 "IPv6 next-hop address\n"
4748 "Use peer address (for BGP only)\n")
4750 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4751 "ipv6 next-hop peer-address", NULL
);
4754 DEFUN (set_ipv6_nexthop_prefer_global
,
4755 set_ipv6_nexthop_prefer_global_cmd
,
4756 "set ipv6 next-hop prefer-global",
4759 "IPv6 next-hop address\n"
4760 "Prefer global over link-local if both exist\n")
4762 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4763 "ipv6 next-hop prefer-global", NULL
);
4767 DEFUN (no_set_ipv6_nexthop_prefer_global
,
4768 no_set_ipv6_nexthop_prefer_global_cmd
,
4769 "no set ipv6 next-hop prefer-global",
4773 "IPv6 next-hop address\n"
4774 "Prefer global over link-local if both exist\n")
4776 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4777 "ipv6 next-hop prefer-global", NULL
);
4780 DEFUN (set_ipv6_nexthop_global
,
4781 set_ipv6_nexthop_global_cmd
,
4782 "set ipv6 next-hop global X:X::X:X",
4785 "IPv6 next-hop address\n"
4786 "IPv6 global address\n"
4787 "IPv6 address of next hop\n")
4790 struct in6_addr addr
;
4793 ret
= inet_pton(AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
4795 vty_out(vty
, "%% Malformed nexthop address\n");
4796 return CMD_WARNING_CONFIG_FAILED
;
4798 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) || IN6_IS_ADDR_LOOPBACK(&addr
)
4799 || IN6_IS_ADDR_MULTICAST(&addr
) || IN6_IS_ADDR_LINKLOCAL(&addr
)) {
4800 vty_out(vty
, "%% Invalid global nexthop address\n");
4801 return CMD_WARNING_CONFIG_FAILED
;
4804 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4805 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4809 DEFUN (no_set_ipv6_nexthop_global
,
4810 no_set_ipv6_nexthop_global_cmd
,
4811 "no set ipv6 next-hop global X:X::X:X",
4815 "IPv6 next-hop address\n"
4816 "IPv6 global address\n"
4817 "IPv6 address of next hop\n")
4820 if (argc
<= idx_ipv6
)
4821 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4822 "ipv6 next-hop global", NULL
);
4823 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4824 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4827 #ifdef KEEP_OLD_VPN_COMMANDS
4828 DEFUN (set_vpn_nexthop
,
4829 set_vpn_nexthop_cmd
,
4830 "set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
4832 "VPNv4 information\n"
4833 "VPN next-hop address\n"
4834 "IP address of next hop\n"
4835 "VPNv6 information\n"
4836 "VPN next-hop address\n"
4837 "IPv6 address of next hop\n")
4843 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
4845 return generic_set_add(
4846 vty
, VTY_GET_CONTEXT(route_map_index
),
4847 "ipv4 vpn next-hop", argv
[idx_ip
]->arg
);
4849 return generic_set_add(
4850 vty
, VTY_GET_CONTEXT(route_map_index
),
4851 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4856 DEFUN (no_set_vpn_nexthop
,
4857 no_set_vpn_nexthop_cmd
,
4858 "no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
4861 "VPNv4 information\n"
4862 "VPN next-hop address\n"
4863 "IP address of next hop\n"
4864 "VPNv6 information\n"
4865 "VPN next-hop address\n"
4866 "IPv6 address of next hop\n")
4876 arg
= argv
[idx_ip
]->arg
;
4877 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
4879 return generic_set_delete(
4880 vty
, VTY_GET_CONTEXT(route_map_index
),
4881 "ipv4 vpn next-hop", arg
);
4883 return generic_set_delete(
4884 vty
, VTY_GET_CONTEXT(route_map_index
),
4885 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4889 #endif /* KEEP_OLD_VPN_COMMANDS */
4891 DEFUN (set_ipx_vpn_nexthop
,
4892 set_ipx_vpn_nexthop_cmd
,
4893 "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
4895 "IPv4 information\n"
4896 "IPv6 information\n"
4898 "VPN next-hop address\n"
4899 "IP address of next hop\n"
4900 "IPv6 address of next hop\n")
4906 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
4908 return generic_set_add(
4909 vty
, VTY_GET_CONTEXT(route_map_index
),
4910 "ipv4 vpn next-hop", argv
[idx_ip
]->arg
);
4912 return generic_set_add(
4913 vty
, VTY_GET_CONTEXT(route_map_index
),
4914 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4919 DEFUN (no_set_ipx_vpn_nexthop
,
4920 no_set_ipx_vpn_nexthop_cmd
,
4921 "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
4924 "IPv4 information\n"
4925 "IPv6 information\n"
4927 "VPN next-hop address\n"
4928 "IP address of next hop\n"
4929 "IPv6 address of next hop\n")
4939 arg
= argv
[idx_ip
]->arg
;
4940 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
4942 return generic_set_delete(
4943 vty
, VTY_GET_CONTEXT(route_map_index
),
4944 "ipv4 vpn next-hop", arg
);
4946 return generic_set_delete(
4947 vty
, VTY_GET_CONTEXT(route_map_index
),
4948 "ipv6 vpn next-hop", arg
);
4953 DEFUN (set_originator_id
,
4954 set_originator_id_cmd
,
4955 "set originator-id A.B.C.D",
4957 "BGP originator ID attribute\n"
4958 "IP address of originator\n")
4961 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4962 "originator-id", argv
[idx_ipv4
]->arg
);
4966 DEFUN (no_set_originator_id
,
4967 no_set_originator_id_cmd
,
4968 "no set originator-id [A.B.C.D]",
4971 "BGP originator ID attribute\n"
4972 "IP address of originator\n")
4976 argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
4978 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4979 "originator-id", arg
);
4983 /* Initialization of route map. */
4984 void bgp_route_map_init(void)
4988 route_map_add_hook(bgp_route_map_add
);
4989 route_map_delete_hook(bgp_route_map_delete
);
4990 route_map_event_hook(bgp_route_map_event
);
4992 route_map_match_interface_hook(generic_match_add
);
4993 route_map_no_match_interface_hook(generic_match_delete
);
4995 route_map_match_ip_address_hook(generic_match_add
);
4996 route_map_no_match_ip_address_hook(generic_match_delete
);
4998 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
4999 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
5001 route_map_match_ip_next_hop_hook(generic_match_add
);
5002 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
5004 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
5005 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
5007 route_map_match_ip_next_hop_type_hook(generic_match_add
);
5008 route_map_no_match_ip_next_hop_type_hook(generic_match_delete
);
5010 route_map_match_ipv6_address_hook(generic_match_add
);
5011 route_map_no_match_ipv6_address_hook(generic_match_delete
);
5013 route_map_match_ipv6_address_prefix_list_hook(generic_match_add
);
5014 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete
);
5016 route_map_match_ipv6_next_hop_type_hook(generic_match_add
);
5017 route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete
);
5019 route_map_match_metric_hook(generic_match_add
);
5020 route_map_no_match_metric_hook(generic_match_delete
);
5022 route_map_match_tag_hook(generic_match_add
);
5023 route_map_no_match_tag_hook(generic_match_delete
);
5025 route_map_set_ip_nexthop_hook(generic_set_add
);
5026 route_map_no_set_ip_nexthop_hook(generic_set_delete
);
5028 route_map_set_ipv6_nexthop_local_hook(generic_set_add
);
5029 route_map_no_set_ipv6_nexthop_local_hook(generic_set_delete
);
5031 route_map_set_metric_hook(generic_set_add
);
5032 route_map_no_set_metric_hook(generic_set_delete
);
5034 route_map_set_tag_hook(generic_set_add
);
5035 route_map_no_set_tag_hook(generic_set_delete
);
5037 route_map_install_match(&route_match_peer_cmd
);
5038 route_map_install_match(&route_match_local_pref_cmd
);
5039 #if defined(HAVE_LUA)
5040 route_map_install_match(&route_match_command_cmd
);
5042 route_map_install_match(&route_match_ip_address_cmd
);
5043 route_map_install_match(&route_match_ip_next_hop_cmd
);
5044 route_map_install_match(&route_match_ip_route_source_cmd
);
5045 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
5046 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
5047 route_map_install_match(&route_match_ip_next_hop_type_cmd
);
5048 route_map_install_match(&route_match_ip_route_source_prefix_list_cmd
);
5049 route_map_install_match(&route_match_aspath_cmd
);
5050 route_map_install_match(&route_match_community_cmd
);
5051 route_map_install_match(&route_match_lcommunity_cmd
);
5052 route_map_install_match(&route_match_ecommunity_cmd
);
5053 route_map_install_match(&route_match_local_pref_cmd
);
5054 route_map_install_match(&route_match_metric_cmd
);
5055 route_map_install_match(&route_match_origin_cmd
);
5056 route_map_install_match(&route_match_probability_cmd
);
5057 route_map_install_match(&route_match_interface_cmd
);
5058 route_map_install_match(&route_match_tag_cmd
);
5059 route_map_install_match(&route_match_mac_address_cmd
);
5060 route_map_install_match(&route_match_evpn_vni_cmd
);
5061 route_map_install_match(&route_match_evpn_route_type_cmd
);
5062 route_map_install_match(&route_match_evpn_default_route_cmd
);
5063 route_map_install_match(&route_match_vrl_source_vrf_cmd
);
5065 route_map_install_set(&route_set_ip_nexthop_cmd
);
5066 route_map_install_set(&route_set_local_pref_cmd
);
5067 route_map_install_set(&route_set_weight_cmd
);
5068 route_map_install_set(&route_set_label_index_cmd
);
5069 route_map_install_set(&route_set_metric_cmd
);
5070 route_map_install_set(&route_set_aspath_prepend_cmd
);
5071 route_map_install_set(&route_set_aspath_exclude_cmd
);
5072 route_map_install_set(&route_set_origin_cmd
);
5073 route_map_install_set(&route_set_atomic_aggregate_cmd
);
5074 route_map_install_set(&route_set_aggregator_as_cmd
);
5075 route_map_install_set(&route_set_community_cmd
);
5076 route_map_install_set(&route_set_community_delete_cmd
);
5077 route_map_install_set(&route_set_lcommunity_cmd
);
5078 route_map_install_set(&route_set_lcommunity_delete_cmd
);
5079 route_map_install_set(&route_set_vpnv4_nexthop_cmd
);
5080 route_map_install_set(&route_set_vpnv6_nexthop_cmd
);
5081 route_map_install_set(&route_set_originator_id_cmd
);
5082 route_map_install_set(&route_set_ecommunity_rt_cmd
);
5083 route_map_install_set(&route_set_ecommunity_soo_cmd
);
5084 route_map_install_set(&route_set_tag_cmd
);
5085 route_map_install_set(&route_set_label_index_cmd
);
5087 install_element(RMAP_NODE
, &match_peer_cmd
);
5088 install_element(RMAP_NODE
, &match_peer_local_cmd
);
5089 install_element(RMAP_NODE
, &no_match_peer_cmd
);
5090 install_element(RMAP_NODE
, &match_ip_route_source_cmd
);
5091 install_element(RMAP_NODE
, &no_match_ip_route_source_cmd
);
5092 install_element(RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
5093 install_element(RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
5094 install_element(RMAP_NODE
, &match_mac_address_cmd
);
5095 install_element(RMAP_NODE
, &no_match_mac_address_cmd
);
5096 install_element(RMAP_NODE
, &match_evpn_vni_cmd
);
5097 install_element(RMAP_NODE
, &no_match_evpn_vni_cmd
);
5098 install_element(RMAP_NODE
, &match_evpn_route_type_cmd
);
5099 install_element(RMAP_NODE
, &no_match_evpn_route_type_cmd
);
5100 install_element(RMAP_NODE
, &match_evpn_default_route_cmd
);
5101 install_element(RMAP_NODE
, &no_match_evpn_default_route_cmd
);
5102 install_element(RMAP_NODE
, &match_vrl_source_vrf_cmd
);
5103 install_element(RMAP_NODE
, &no_match_vrl_source_vrf_cmd
);
5105 install_element(RMAP_NODE
, &match_aspath_cmd
);
5106 install_element(RMAP_NODE
, &no_match_aspath_cmd
);
5107 install_element(RMAP_NODE
, &match_local_pref_cmd
);
5108 install_element(RMAP_NODE
, &no_match_local_pref_cmd
);
5109 install_element(RMAP_NODE
, &match_community_cmd
);
5110 install_element(RMAP_NODE
, &no_match_community_cmd
);
5111 install_element(RMAP_NODE
, &match_lcommunity_cmd
);
5112 install_element(RMAP_NODE
, &no_match_lcommunity_cmd
);
5113 install_element(RMAP_NODE
, &match_ecommunity_cmd
);
5114 install_element(RMAP_NODE
, &no_match_ecommunity_cmd
);
5115 install_element(RMAP_NODE
, &match_origin_cmd
);
5116 install_element(RMAP_NODE
, &no_match_origin_cmd
);
5117 install_element(RMAP_NODE
, &match_probability_cmd
);
5118 install_element(RMAP_NODE
, &no_match_probability_cmd
);
5120 install_element(RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
5121 install_element(RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
5122 install_element(RMAP_NODE
, &set_local_pref_cmd
);
5123 install_element(RMAP_NODE
, &no_set_local_pref_cmd
);
5124 install_element(RMAP_NODE
, &set_weight_cmd
);
5125 install_element(RMAP_NODE
, &set_label_index_cmd
);
5126 install_element(RMAP_NODE
, &no_set_weight_cmd
);
5127 install_element(RMAP_NODE
, &no_set_label_index_cmd
);
5128 install_element(RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
5129 install_element(RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
5130 install_element(RMAP_NODE
, &set_aspath_exclude_cmd
);
5131 install_element(RMAP_NODE
, &no_set_aspath_prepend_cmd
);
5132 install_element(RMAP_NODE
, &no_set_aspath_exclude_cmd
);
5133 install_element(RMAP_NODE
, &no_set_aspath_exclude_all_cmd
);
5134 install_element(RMAP_NODE
, &set_origin_cmd
);
5135 install_element(RMAP_NODE
, &no_set_origin_cmd
);
5136 install_element(RMAP_NODE
, &set_atomic_aggregate_cmd
);
5137 install_element(RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
5138 install_element(RMAP_NODE
, &set_aggregator_as_cmd
);
5139 install_element(RMAP_NODE
, &no_set_aggregator_as_cmd
);
5140 install_element(RMAP_NODE
, &set_community_cmd
);
5141 install_element(RMAP_NODE
, &set_community_none_cmd
);
5142 install_element(RMAP_NODE
, &no_set_community_cmd
);
5143 install_element(RMAP_NODE
, &no_set_community_short_cmd
);
5144 install_element(RMAP_NODE
, &set_community_delete_cmd
);
5145 install_element(RMAP_NODE
, &no_set_community_delete_cmd
);
5146 install_element(RMAP_NODE
, &set_lcommunity_cmd
);
5147 install_element(RMAP_NODE
, &set_lcommunity_none_cmd
);
5148 install_element(RMAP_NODE
, &no_set_lcommunity_cmd
);
5149 install_element(RMAP_NODE
, &no_set_lcommunity1_cmd
);
5150 install_element(RMAP_NODE
, &no_set_lcommunity1_short_cmd
);
5151 install_element(RMAP_NODE
, &set_lcommunity_delete_cmd
);
5152 install_element(RMAP_NODE
, &no_set_lcommunity_delete_cmd
);
5153 install_element(RMAP_NODE
, &no_set_lcommunity_delete_short_cmd
);
5154 install_element(RMAP_NODE
, &set_ecommunity_rt_cmd
);
5155 install_element(RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
5156 install_element(RMAP_NODE
, &no_set_ecommunity_rt_short_cmd
);
5157 install_element(RMAP_NODE
, &set_ecommunity_soo_cmd
);
5158 install_element(RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
5159 install_element(RMAP_NODE
, &no_set_ecommunity_soo_short_cmd
);
5160 #ifdef KEEP_OLD_VPN_COMMANDS
5161 install_element(RMAP_NODE
, &set_vpn_nexthop_cmd
);
5162 install_element(RMAP_NODE
, &no_set_vpn_nexthop_cmd
);
5163 #endif /* KEEP_OLD_VPN_COMMANDS */
5164 install_element(RMAP_NODE
, &set_ipx_vpn_nexthop_cmd
);
5165 install_element(RMAP_NODE
, &no_set_ipx_vpn_nexthop_cmd
);
5166 install_element(RMAP_NODE
, &set_originator_id_cmd
);
5167 install_element(RMAP_NODE
, &no_set_originator_id_cmd
);
5169 route_map_install_match(&route_match_ipv6_address_cmd
);
5170 route_map_install_match(&route_match_ipv6_next_hop_cmd
);
5171 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd
);
5172 route_map_install_match(&route_match_ipv6_next_hop_type_cmd
);
5173 route_map_install_set(&route_set_ipv6_nexthop_global_cmd
);
5174 route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd
);
5175 route_map_install_set(&route_set_ipv6_nexthop_local_cmd
);
5176 route_map_install_set(&route_set_ipv6_nexthop_peer_cmd
);
5178 install_element(RMAP_NODE
, &match_ipv6_next_hop_cmd
);
5179 install_element(RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
5180 install_element(RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
5181 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
5182 install_element(RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
5183 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
5184 install_element(RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
5185 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
5186 #if defined(HAVE_LUA)
5187 install_element(RMAP_NODE
, &match_command_cmd
);
5188 install_element(RMAP_NODE
, &no_match_command_cmd
);
5192 void bgp_route_map_terminate(void)
5194 /* ToDo: Cleanup all the used memory */