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"
65 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
68 #ifndef VTYSH_EXTRACT_PL
69 #include "bgpd/bgp_routemap_clippy.c"
72 /* Memo of route-map commands.
81 ip route-source : Done
85 ipv6 route-source: (This will not be implemented by bgpd)
86 ipv6 prefix-list : Done
87 length : (This will not be implemented by bgpd)
89 route-type : (This will not be implemented by bgpd)
91 local-preference : Done
93 set as-path prepend : Done
95 automatic-tag : (This will not be implemented by bgpd)
97 large-community : Done
98 large-comm-list : Done
101 default : (This will not be implemented by bgpd)
102 interface : (This will not be implemented by bgpd)
103 ip default : (This will not be implemented by bgpd)
105 ip precedence : (This will not be implemented by bgpd)
106 ip tos : (This will not be implemented by bgpd)
107 level : (This will not be implemented by bgpd)
108 local-preference : Done
110 metric-type : Not yet
117 set ipv6 next-hop global: Done
118 set ipv6 next-hop prefer-global: Done
119 set ipv6 next-hop local : Done
120 set as-path exclude : Done
124 /* generic value manipulation to be shared in multiple rules */
126 #define RMAP_VALUE_SET 0
127 #define RMAP_VALUE_ADD 1
128 #define RMAP_VALUE_SUB 2
136 static int route_value_match(struct rmap_value
*rv
, uint32_t value
)
138 if (rv
->variable
== 0 && value
== rv
->value
)
144 static uint32_t route_value_adjust(struct rmap_value
*rv
, uint32_t current
,
149 switch (rv
->variable
) {
158 switch (rv
->action
) {
160 if (current
> UINT32_MAX
- value
)
162 return current
+ value
;
164 if (current
<= value
)
166 return current
- value
;
172 static void *route_value_compile(const char *arg
)
174 uint8_t action
= RMAP_VALUE_SET
, var
= 0;
175 unsigned long larg
= 0;
177 struct rmap_value
*rv
;
180 action
= RMAP_VALUE_ADD
;
182 } else if (arg
[0] == '-') {
183 action
= RMAP_VALUE_SUB
;
187 if (all_digit(arg
)) {
189 larg
= strtoul(arg
, &endptr
, 10);
190 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
193 if (strcmp(arg
, "rtt") == 0)
199 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
;
328 XFREE(MTYPE_ROUTE_MAP_COMPILED
, pc
->interface
);
330 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
333 /* Route map commands for ip address matching. */
334 struct route_map_rule_cmd route_match_peer_cmd
= {"peer", route_match_peer
,
335 route_match_peer_compile
,
336 route_match_peer_free
};
338 #if defined(HAVE_LUA)
339 static route_map_result_t
route_match_command(void *rule
,
340 const struct prefix
*prefix
,
341 route_map_object_t type
,
344 int status
= RMAP_NOMATCH
;
345 u_int32_t locpref
= 0;
346 u_int32_t newlocpref
= 0;
347 enum lua_rm_status lrm_status
;
348 struct bgp_path_info
*path
= (struct bgp_path_info
*)object
;
349 lua_State
*L
= lua_initialize("/etc/frr/lua.scr");
355 * Setup the prefix information to pass in
357 lua_setup_prefix_table(L
, prefix
);
359 zlog_debug("Set up prefix table");
361 * Setup the bgp_path_info information
364 lua_pushinteger(L
, path
->attr
->med
);
365 lua_setfield(L
, -2, "metric");
366 lua_pushinteger(L
, path
->attr
->nh_ifindex
);
367 lua_setfield(L
, -2, "ifindex");
368 lua_pushstring(L
, path
->attr
->aspath
->str
);
369 lua_setfield(L
, -2, "aspath");
370 lua_pushinteger(L
, path
->attr
->local_pref
);
371 lua_setfield(L
, -2, "localpref");
372 zlog_debug("%s %d", path
->attr
->aspath
->str
, path
->attr
->nh_ifindex
);
373 lua_setglobal(L
, "nexthop");
375 zlog_debug("Set up nexthop information");
379 lrm_status
= lua_run_rm_rule(L
, rule
);
380 switch (lrm_status
) {
382 zlog_debug("RM_FAILURE");
385 zlog_debug("RM_NOMATCH");
387 case LUA_RM_MATCH_AND_CHANGE
:
388 zlog_debug("MATCH AND CHANGE");
389 lua_getglobal(L
, "nexthop");
390 path
->attr
->med
= get_integer(L
, "metric");
392 * This needs to be abstraced with the set function
394 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
395 locpref
= path
->attr
->local_pref
;
396 newlocpref
= get_integer(L
, "localpref");
397 if (newlocpref
!= locpref
) {
398 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
399 path
->attr
->local_pref
= newlocpref
;
404 zlog_debug("MATCH ONLY");
412 static void *route_match_command_compile(const char *arg
)
416 command
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
421 route_match_command_free(void *rule
)
423 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
426 struct route_map_rule_cmd route_match_command_cmd
= {
429 route_match_command_compile
,
430 route_match_command_free
434 /* `match ip address IP_ACCESS_LIST' */
436 /* Match function should return 1 if match is success else return
438 static route_map_result_t
route_match_ip_address(void *rule
,
439 const struct prefix
*prefix
,
440 route_map_object_t type
,
443 struct access_list
*alist
;
445 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
446 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
450 return (access_list_apply(alist
, prefix
) == FILTER_DENY
457 /* Route map `ip address' match statement. `arg' should be
459 static void *route_match_ip_address_compile(const char *arg
)
461 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
464 /* Free route map's compiled `ip address' value. */
465 static void route_match_ip_address_free(void *rule
)
467 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
470 /* Route map commands for ip address matching. */
471 struct route_map_rule_cmd route_match_ip_address_cmd
= {
472 "ip address", route_match_ip_address
, route_match_ip_address_compile
,
473 route_match_ip_address_free
};
475 /* `match ip next-hop IP_ADDRESS' */
477 /* Match function return 1 if match is success else return zero. */
478 static route_map_result_t
route_match_ip_next_hop(void *rule
,
479 const struct prefix
*prefix
,
480 route_map_object_t type
,
483 struct access_list
*alist
;
484 struct bgp_path_info
*path
;
485 struct prefix_ipv4 p
;
487 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
490 p
.prefix
= path
->attr
->nexthop
;
491 p
.prefixlen
= IPV4_MAX_BITLEN
;
493 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
497 return (access_list_apply(alist
, &p
) == FILTER_DENY
504 /* Route map `ip next-hop' match statement. `arg' is
506 static void *route_match_ip_next_hop_compile(const char *arg
)
508 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
511 /* Free route map's compiled `ip address' value. */
512 static void route_match_ip_next_hop_free(void *rule
)
514 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
517 /* Route map commands for ip next-hop matching. */
518 struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
519 "ip next-hop", route_match_ip_next_hop
, route_match_ip_next_hop_compile
,
520 route_match_ip_next_hop_free
};
522 /* `match ip route-source ACCESS-LIST' */
524 /* Match function return 1 if match is success else return zero. */
525 static route_map_result_t
route_match_ip_route_source(void *rule
,
526 const struct prefix
*pfx
,
527 route_map_object_t type
,
530 struct access_list
*alist
;
531 struct bgp_path_info
*path
;
533 struct prefix_ipv4 p
;
535 if (type
== RMAP_BGP
&& pfx
->family
== AF_INET
) {
539 if (!peer
|| sockunion_family(&peer
->su
) != AF_INET
)
543 p
.prefix
= peer
->su
.sin
.sin_addr
;
544 p
.prefixlen
= IPV4_MAX_BITLEN
;
546 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
550 return (access_list_apply(alist
, &p
) == FILTER_DENY
557 /* Route map `ip route-source' match statement. `arg' is
559 static void *route_match_ip_route_source_compile(const char *arg
)
561 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
564 /* Free route map's compiled `ip address' value. */
565 static void route_match_ip_route_source_free(void *rule
)
567 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
570 /* Route map commands for ip route-source matching. */
571 struct route_map_rule_cmd route_match_ip_route_source_cmd
= {
572 "ip route-source", route_match_ip_route_source
,
573 route_match_ip_route_source_compile
, route_match_ip_route_source_free
};
575 /* `match ip address prefix-list PREFIX_LIST' */
577 static route_map_result_t
578 route_match_ip_address_prefix_list(void *rule
, const struct prefix
*prefix
,
579 route_map_object_t type
, void *object
)
581 struct prefix_list
*plist
;
583 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
584 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
588 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
595 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
597 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
600 static void route_match_ip_address_prefix_list_free(void *rule
)
602 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
605 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
= {
606 "ip address prefix-list", route_match_ip_address_prefix_list
,
607 route_match_ip_address_prefix_list_compile
,
608 route_match_ip_address_prefix_list_free
};
610 /* `match ip next-hop prefix-list PREFIX_LIST' */
612 static route_map_result_t
613 route_match_ip_next_hop_prefix_list(void *rule
, const struct prefix
*prefix
,
614 route_map_object_t type
, void *object
)
616 struct prefix_list
*plist
;
617 struct bgp_path_info
*path
;
618 struct prefix_ipv4 p
;
620 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
623 p
.prefix
= path
->attr
->nexthop
;
624 p
.prefixlen
= IPV4_MAX_BITLEN
;
626 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
630 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
637 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
639 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
642 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
644 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
647 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
= {
648 "ip next-hop prefix-list", route_match_ip_next_hop_prefix_list
,
649 route_match_ip_next_hop_prefix_list_compile
,
650 route_match_ip_next_hop_prefix_list_free
};
652 /* `match ip next-hop type <blackhole>' */
654 static route_map_result_t
655 route_match_ip_next_hop_type(void *rule
, const struct prefix
*prefix
,
656 route_map_object_t type
, void *object
)
658 struct bgp_path_info
*path
;
660 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
661 path
= (struct bgp_path_info
*)object
;
662 if (!path
|| !path
->attr
)
663 return RMAP_DENYMATCH
;
665 /* If nexthop interface's index can't be resolved and nexthop is
666 set to any address then mark it as type `blackhole`.
667 This logic works for matching kernel/static routes like:
668 `ip route add blackhole 10.0.0.1`. */
669 if (path
->attr
->nexthop
.s_addr
== INADDR_ANY
670 && !path
->attr
->nh_ifindex
)
676 static void *route_match_ip_next_hop_type_compile(const char *arg
)
678 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
681 static void route_match_ip_next_hop_type_free(void *rule
)
683 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
686 static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd
= {
687 "ip next-hop type", route_match_ip_next_hop_type
,
688 route_match_ip_next_hop_type_compile
,
689 route_match_ip_next_hop_type_free
};
691 /* `match ip route-source prefix-list PREFIX_LIST' */
693 static route_map_result_t
694 route_match_ip_route_source_prefix_list(void *rule
,
695 const struct prefix
*prefix
,
696 route_map_object_t type
, void *object
)
698 struct prefix_list
*plist
;
699 struct bgp_path_info
*path
;
701 struct prefix_ipv4 p
;
703 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET
) {
707 if (!peer
|| sockunion_family(&peer
->su
) != AF_INET
)
711 p
.prefix
= peer
->su
.sin
.sin_addr
;
712 p
.prefixlen
= IPV4_MAX_BITLEN
;
714 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
718 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
725 static void *route_match_ip_route_source_prefix_list_compile(const char *arg
)
727 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
730 static void route_match_ip_route_source_prefix_list_free(void *rule
)
732 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
735 struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd
= {
736 "ip route-source prefix-list", route_match_ip_route_source_prefix_list
,
737 route_match_ip_route_source_prefix_list_compile
,
738 route_match_ip_route_source_prefix_list_free
};
740 /* `match evpn default-route' */
742 /* Match function should return 1 if match is success else 0 */
743 static route_map_result_t
route_match_evpn_default_route(void *rule
,
744 const struct prefix
*p
,
748 if (type
== RMAP_BGP
&& is_evpn_prefix_default(p
))
754 /* Route map commands for default-route matching. */
755 struct route_map_rule_cmd route_match_evpn_default_route_cmd
= {
756 "evpn default-route", route_match_evpn_default_route
, NULL
, NULL
};
758 /* `match mac address MAC_ACCESS_LIST' */
760 /* Match function should return 1 if match is success else return
762 static route_map_result_t
route_match_mac_address(void *rule
,
763 const struct prefix
*prefix
,
764 route_map_object_t type
,
767 struct access_list
*alist
;
770 if (type
== RMAP_BGP
) {
771 alist
= access_list_lookup(AFI_L2VPN
, (char *)rule
);
775 if (prefix
->u
.prefix_evpn
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
778 p
.family
= AF_ETHERNET
;
779 p
.prefixlen
= ETH_ALEN
* 8;
780 p
.u
.prefix_eth
= prefix
->u
.prefix_evpn
.macip_addr
.mac
;
782 return (access_list_apply(alist
, &p
) == FILTER_DENY
790 /* Route map `mac address' match statement. `arg' should be
792 static void *route_match_mac_address_compile(const char *arg
)
794 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
797 /* Free route map's compiled `ip address' value. */
798 static void route_match_mac_address_free(void *rule
)
800 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
803 /* Route map commands for mac address matching. */
804 struct route_map_rule_cmd route_match_mac_address_cmd
= {
805 "mac address", route_match_mac_address
, route_match_mac_address_compile
,
806 route_match_mac_address_free
};
810 /* Match function should return 1 if match is success else return
812 static route_map_result_t
route_match_vni(void *rule
,
813 const struct prefix
*prefix
,
814 route_map_object_t type
, void *object
)
817 struct bgp_path_info
*path
= NULL
;
819 if (type
== RMAP_BGP
) {
820 vni
= *((vni_t
*)rule
);
821 path
= (struct bgp_path_info
*)object
;
823 if (path
->extra
== NULL
)
826 if (vni
== label2vni(&path
->extra
->label
[0]))
833 /* Route map `vni' match statement. */
834 static void *route_match_vni_compile(const char *arg
)
839 vni
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(vni_t
));
843 *vni
= strtoul(arg
, &end
, 10);
845 XFREE(MTYPE_ROUTE_MAP_COMPILED
, vni
);
852 /* Free route map's compiled `vni' value. */
853 static void route_match_vni_free(void *rule
)
855 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
858 /* Route map commands for vni matching. */
859 struct route_map_rule_cmd route_match_evpn_vni_cmd
= {
860 "evpn vni", route_match_vni
, route_match_vni_compile
,
861 route_match_vni_free
};
863 /* `match evpn route-type' */
865 /* Match function should return 1 if match is success else return
867 static route_map_result_t
route_match_evpn_route_type(void *rule
,
868 const struct prefix
*pfx
,
869 route_map_object_t type
,
872 uint8_t route_type
= 0;
874 if (type
== RMAP_BGP
) {
875 route_type
= *((uint8_t *)rule
);
877 if (route_type
== pfx
->u
.prefix_evpn
.route_type
)
884 /* Route map `route-type' match statement. */
885 static void *route_match_evpn_route_type_compile(const char *arg
)
887 uint8_t *route_type
= NULL
;
889 route_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
891 if (strncmp(arg
, "ma", 2) == 0)
892 *route_type
= BGP_EVPN_MAC_IP_ROUTE
;
893 else if (strncmp(arg
, "mu", 2) == 0)
894 *route_type
= BGP_EVPN_IMET_ROUTE
;
896 *route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
901 /* Free route map's compiled `route-type' value. */
902 static void route_match_evpn_route_type_free(void *rule
)
904 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
907 /* Route map commands for evpn route-type matching. */
908 struct route_map_rule_cmd route_match_evpn_route_type_cmd
= {
909 "evpn route-type", route_match_evpn_route_type
,
910 route_match_evpn_route_type_compile
, route_match_evpn_route_type_free
};
912 /* Route map commands for VRF route leak with source vrf matching */
913 static route_map_result_t
914 route_match_vrl_source_vrf(void *rule
, const struct prefix
*prefix
,
915 route_map_object_t type
, void *object
)
917 struct bgp_path_info
*path
;
920 if (type
== RMAP_BGP
) {
922 path
= (struct bgp_path_info
*)object
;
924 if (strncmp(vrf_name
, "n/a", VRF_NAMSIZ
) == 0)
927 if (path
->extra
== NULL
)
930 if (strncmp(vrf_name
, vrf_id_to_name(
931 path
->extra
->bgp_orig
->vrf_id
), VRF_NAMSIZ
)
939 static void *route_match_vrl_source_vrf_compile(const char *arg
)
941 uint8_t *vrf_name
= NULL
;
943 vrf_name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
948 /* Free route map's compiled `route-type' value. */
949 static void route_match_vrl_source_vrf_free(void *rule
)
951 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
954 struct route_map_rule_cmd route_match_vrl_source_vrf_cmd
= {
955 "source-vrf", route_match_vrl_source_vrf
,
956 route_match_vrl_source_vrf_compile
,
957 route_match_vrl_source_vrf_free
};
959 /* `match local-preference LOCAL-PREF' */
961 /* Match function return 1 if match is success else return zero. */
962 static route_map_result_t
route_match_local_pref(void *rule
,
963 const struct prefix
*prefix
,
964 route_map_object_t type
,
967 uint32_t *local_pref
;
968 struct bgp_path_info
*path
;
970 if (type
== RMAP_BGP
) {
974 if (path
->attr
->local_pref
== *local_pref
)
982 /* Route map `match local-preference' match statement.
983 `arg' is local-pref value */
984 static void *route_match_local_pref_compile(const char *arg
)
986 uint32_t *local_pref
;
988 unsigned long tmpval
;
990 /* Locpref value shoud be integer. */
995 tmpval
= strtoul(arg
, &endptr
, 10);
996 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
999 local_pref
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1004 *local_pref
= tmpval
;
1008 /* Free route map's compiled `match local-preference' value. */
1009 static void route_match_local_pref_free(void *rule
)
1011 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1014 /* Route map commands for metric matching. */
1015 struct route_map_rule_cmd route_match_local_pref_cmd
= {
1016 "local-preference", route_match_local_pref
,
1017 route_match_local_pref_compile
, route_match_local_pref_free
};
1019 /* `match metric METRIC' */
1021 /* Match function return 1 if match is success else return zero. */
1022 static route_map_result_t
route_match_metric(void *rule
,
1023 const struct prefix
*prefix
,
1024 route_map_object_t type
,
1027 struct rmap_value
*rv
;
1028 struct bgp_path_info
*path
;
1030 if (type
== RMAP_BGP
) {
1033 return route_value_match(rv
, path
->attr
->med
);
1035 return RMAP_NOMATCH
;
1038 /* Route map commands for metric matching. */
1039 struct route_map_rule_cmd route_match_metric_cmd
= {
1040 "metric", route_match_metric
, route_value_compile
, route_value_free
,
1043 /* `match as-path ASPATH' */
1045 /* Match function for as-path match. I assume given object is */
1046 static route_map_result_t
route_match_aspath(void *rule
,
1047 const struct prefix
*prefix
,
1048 route_map_object_t type
,
1052 struct as_list
*as_list
;
1053 struct bgp_path_info
*path
;
1055 if (type
== RMAP_BGP
) {
1056 as_list
= as_list_lookup((char *)rule
);
1057 if (as_list
== NULL
)
1058 return RMAP_NOMATCH
;
1062 /* Perform match. */
1063 return ((as_list_apply(as_list
, path
->attr
->aspath
)
1068 return RMAP_NOMATCH
;
1071 /* Compile function for as-path match. */
1072 static void *route_match_aspath_compile(const char *arg
)
1074 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1077 /* Compile function for as-path match. */
1078 static void route_match_aspath_free(void *rule
)
1080 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1083 /* Route map commands for aspath matching. */
1084 struct route_map_rule_cmd route_match_aspath_cmd
= {
1085 "as-path", route_match_aspath
, route_match_aspath_compile
,
1086 route_match_aspath_free
};
1088 /* `match community COMMUNIY' */
1089 struct rmap_community
{
1095 /* Match function for community match. */
1096 static route_map_result_t
route_match_community(void *rule
,
1097 const struct prefix
*prefix
,
1098 route_map_object_t type
,
1101 struct community_list
*list
;
1102 struct bgp_path_info
*path
;
1103 struct rmap_community
*rcom
= rule
;
1105 if (type
== RMAP_BGP
) {
1109 list
= community_list_lookup(bgp_clist
, rcom
->name
,
1111 COMMUNITY_LIST_MASTER
);
1113 return RMAP_NOMATCH
;
1116 if (community_list_exact_match(path
->attr
->community
,
1120 if (community_list_match(path
->attr
->community
, list
))
1124 return RMAP_NOMATCH
;
1127 /* Compile function for community match. */
1128 static void *route_match_community_compile(const char *arg
)
1130 struct rmap_community
*rcom
;
1134 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1136 p
= strchr(arg
, ' ');
1139 rcom
->name
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1140 memcpy(rcom
->name
, arg
, len
);
1143 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1147 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1151 /* Compile function for community match. */
1152 static void route_match_community_free(void *rule
)
1154 struct rmap_community
*rcom
= rule
;
1156 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1157 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1160 /* Route map commands for community matching. */
1161 struct route_map_rule_cmd route_match_community_cmd
= {
1162 "community", route_match_community
, route_match_community_compile
,
1163 route_match_community_free
};
1165 /* Match function for lcommunity match. */
1166 static route_map_result_t
route_match_lcommunity(void *rule
,
1167 const struct prefix
*prefix
,
1168 route_map_object_t type
,
1171 struct community_list
*list
;
1172 struct bgp_path_info
*path
;
1173 struct rmap_community
*rcom
= rule
;
1175 if (type
== RMAP_BGP
) {
1178 list
= community_list_lookup(bgp_clist
, rcom
->name
,
1180 LARGE_COMMUNITY_LIST_MASTER
);
1182 return RMAP_NOMATCH
;
1184 if (lcommunity_list_match(path
->attr
->lcommunity
, list
))
1187 return RMAP_NOMATCH
;
1190 /* Compile function for community match. */
1191 static void *route_match_lcommunity_compile(const char *arg
)
1193 struct rmap_community
*rcom
;
1197 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1199 p
= strchr(arg
, ' ');
1202 rcom
->name
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1203 memcpy(rcom
->name
, arg
, len
);
1205 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1209 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1213 /* Compile function for community match. */
1214 static void route_match_lcommunity_free(void *rule
)
1216 struct rmap_community
*rcom
= rule
;
1218 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1219 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1222 /* Route map commands for community matching. */
1223 struct route_map_rule_cmd route_match_lcommunity_cmd
= {
1224 "large-community", route_match_lcommunity
,
1225 route_match_lcommunity_compile
, route_match_lcommunity_free
};
1228 /* Match function for extcommunity match. */
1229 static route_map_result_t
route_match_ecommunity(void *rule
,
1230 const struct prefix
*prefix
,
1231 route_map_object_t type
,
1234 struct community_list
*list
;
1235 struct bgp_path_info
*path
;
1236 struct rmap_community
*rcom
= rule
;
1238 if (type
== RMAP_BGP
) {
1241 list
= community_list_lookup(bgp_clist
, rcom
->name
,
1243 EXTCOMMUNITY_LIST_MASTER
);
1245 return RMAP_NOMATCH
;
1247 if (ecommunity_list_match(path
->attr
->ecommunity
, list
))
1250 return RMAP_NOMATCH
;
1253 /* Compile function for extcommunity match. */
1254 static void *route_match_ecommunity_compile(const char *arg
)
1256 struct rmap_community
*rcom
;
1258 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1259 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1260 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1265 /* Compile function for extcommunity match. */
1266 static void route_match_ecommunity_free(void *rule
)
1268 struct rmap_community
*rcom
= rule
;
1270 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1271 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1274 /* Route map commands for community matching. */
1275 struct route_map_rule_cmd route_match_ecommunity_cmd
= {
1276 "extcommunity", route_match_ecommunity
, route_match_ecommunity_compile
,
1277 route_match_ecommunity_free
};
1279 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
1280 and `address-family vpnv4'. */
1282 /* `match origin' */
1283 static route_map_result_t
route_match_origin(void *rule
,
1284 const struct prefix
*prefix
,
1285 route_map_object_t type
,
1289 struct bgp_path_info
*path
;
1291 if (type
== RMAP_BGP
) {
1295 if (path
->attr
->origin
== *origin
)
1299 return RMAP_NOMATCH
;
1302 static void *route_match_origin_compile(const char *arg
)
1306 origin
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1308 if (strcmp(arg
, "igp") == 0)
1310 else if (strcmp(arg
, "egp") == 0)
1318 /* Free route map's compiled `ip address' value. */
1319 static void route_match_origin_free(void *rule
)
1321 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1324 /* Route map commands for origin matching. */
1325 struct route_map_rule_cmd route_match_origin_cmd
= {
1326 "origin", route_match_origin
, route_match_origin_compile
,
1327 route_match_origin_free
};
1329 /* match probability { */
1331 static route_map_result_t
route_match_probability(void *rule
,
1332 const struct prefix
*prefix
,
1333 route_map_object_t type
,
1338 switch (*(long *)rule
) {
1344 if (r
< *(long *)rule
) {
1349 return RMAP_NOMATCH
;
1352 static void *route_match_probability_compile(const char *arg
)
1358 lobule
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(long));
1368 *lobule
= RAND_MAX
/ 100 * perc
;
1374 static void route_match_probability_free(void *rule
)
1376 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1379 struct route_map_rule_cmd route_match_probability_cmd
= {
1380 "probability", route_match_probability
, route_match_probability_compile
,
1381 route_match_probability_free
};
1383 /* `match interface IFNAME' */
1384 /* Match function should return 1 if match is success else return
1386 static route_map_result_t
route_match_interface(void *rule
,
1387 const struct prefix
*prefix
,
1388 route_map_object_t type
,
1391 struct interface
*ifp
;
1392 struct bgp_path_info
*path
;
1394 if (type
== RMAP_BGP
) {
1397 if (!path
|| !path
->attr
)
1398 return RMAP_NOMATCH
;
1400 ifp
= if_lookup_by_name_all_vrf((char *)rule
);
1402 if (ifp
== NULL
|| ifp
->ifindex
!= path
->attr
->nh_ifindex
)
1403 return RMAP_NOMATCH
;
1407 return RMAP_NOMATCH
;
1410 /* Route map `interface' match statement. `arg' should be
1412 static void *route_match_interface_compile(const char *arg
)
1414 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1417 /* Free route map's compiled `interface' value. */
1418 static void route_match_interface_free(void *rule
)
1420 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1423 /* Route map commands for ip address matching. */
1424 struct route_map_rule_cmd route_match_interface_cmd
= {
1425 "interface", route_match_interface
, route_match_interface_compile
,
1426 route_match_interface_free
};
1430 /* `set ip next-hop IP_ADDRESS' */
1432 /* Match function return 1 if match is success else return zero. */
1433 static route_map_result_t
route_match_tag(void *rule
,
1434 const struct prefix
*prefix
,
1435 route_map_object_t type
, void *object
)
1438 struct bgp_path_info
*path
;
1440 if (type
== RMAP_BGP
) {
1444 return ((path
->attr
->tag
== *tag
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1447 return RMAP_NOMATCH
;
1451 /* Route map commands for tag matching. */
1452 static struct route_map_rule_cmd route_match_tag_cmd
= {
1453 "tag", route_match_tag
, route_map_rule_tag_compile
,
1454 route_map_rule_tag_free
,
1458 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1459 struct rmap_ip_nexthop_set
{
1460 struct in_addr
*address
;
1465 static route_map_result_t
route_set_ip_nexthop(void *rule
,
1466 const struct prefix
*prefix
,
1467 route_map_object_t type
,
1470 struct rmap_ip_nexthop_set
*rins
= rule
;
1471 struct bgp_path_info
*path
;
1474 if (type
!= RMAP_BGP
)
1477 if (prefix
->family
== AF_INET6
)
1483 if (rins
->unchanged
) {
1484 SET_FLAG(path
->attr
->rmap_change_flags
,
1485 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1486 } else if (rins
->peer_address
) {
1487 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
1488 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1490 && sockunion_family(peer
->su_remote
) == AF_INET
) {
1491 path
->attr
->nexthop
.s_addr
=
1492 sockunion2ip(peer
->su_remote
);
1493 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1494 } else if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
)) {
1495 /* The next hop value will be set as part of
1496 * packet rewrite. Set the flags here to indicate
1497 * that rewrite needs to be done.
1498 * Also, clear the value.
1500 SET_FLAG(path
->attr
->rmap_change_flags
,
1501 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1502 path
->attr
->nexthop
.s_addr
= 0;
1505 /* Set next hop value. */
1506 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1507 path
->attr
->nexthop
= *rins
->address
;
1508 SET_FLAG(path
->attr
->rmap_change_flags
,
1509 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1510 /* case for MP-BGP : MPLS VPN */
1511 path
->attr
->mp_nexthop_global_in
= *rins
->address
;
1512 path
->attr
->mp_nexthop_len
= sizeof(*rins
->address
);
1518 /* Route map `ip nexthop' compile function. Given string is converted
1519 to struct in_addr structure. */
1520 static void *route_set_ip_nexthop_compile(const char *arg
)
1522 struct rmap_ip_nexthop_set
*rins
;
1523 struct in_addr
*address
= NULL
;
1524 int peer_address
= 0;
1528 if (strcmp(arg
, "peer-address") == 0)
1530 else if (strcmp(arg
, "unchanged") == 0)
1533 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
1534 sizeof(struct in_addr
));
1535 ret
= inet_aton(arg
, address
);
1538 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
1543 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
,
1544 sizeof(struct rmap_ip_nexthop_set
));
1546 rins
->address
= address
;
1547 rins
->peer_address
= peer_address
;
1548 rins
->unchanged
= unchanged
;
1553 /* Free route map's compiled `ip nexthop' value. */
1554 static void route_set_ip_nexthop_free(void *rule
)
1556 struct rmap_ip_nexthop_set
*rins
= rule
;
1559 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1561 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rins
);
1564 /* Route map commands for ip nexthop set. */
1565 struct route_map_rule_cmd route_set_ip_nexthop_cmd
= {
1566 "ip next-hop", route_set_ip_nexthop
, route_set_ip_nexthop_compile
,
1567 route_set_ip_nexthop_free
};
1569 /* `set local-preference LOCAL_PREF' */
1571 /* Set local preference. */
1572 static route_map_result_t
route_set_local_pref(void *rule
,
1573 const struct prefix
*prefix
,
1574 route_map_object_t type
,
1577 struct rmap_value
*rv
;
1578 struct bgp_path_info
*path
;
1579 uint32_t locpref
= 0;
1581 if (type
== RMAP_BGP
) {
1582 /* Fetch routemap's rule information. */
1586 /* Set local preference value. */
1587 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1588 locpref
= path
->attr
->local_pref
;
1590 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1591 path
->attr
->local_pref
=
1592 route_value_adjust(rv
, locpref
, path
->peer
);
1598 /* Set local preference rule structure. */
1599 struct route_map_rule_cmd route_set_local_pref_cmd
= {
1600 "local-preference", route_set_local_pref
, route_value_compile
,
1604 /* `set weight WEIGHT' */
1607 static route_map_result_t
route_set_weight(void *rule
,
1608 const struct prefix
*prefix
,
1609 route_map_object_t type
,
1612 struct rmap_value
*rv
;
1613 struct bgp_path_info
*path
;
1615 if (type
== RMAP_BGP
) {
1616 /* Fetch routemap's rule information. */
1620 /* Set weight value. */
1621 path
->attr
->weight
= route_value_adjust(rv
, 0, path
->peer
);
1627 /* Set local preference rule structure. */
1628 struct route_map_rule_cmd route_set_weight_cmd
= {
1629 "weight", route_set_weight
, route_value_compile
, route_value_free
,
1632 /* `set metric METRIC' */
1634 /* Set metric to attribute. */
1635 static route_map_result_t
route_set_metric(void *rule
,
1636 const struct prefix
*prefix
,
1637 route_map_object_t type
,
1640 struct rmap_value
*rv
;
1641 struct bgp_path_info
*path
;
1644 if (type
== RMAP_BGP
) {
1645 /* Fetch routemap's rule information. */
1649 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
1650 med
= path
->attr
->med
;
1652 path
->attr
->med
= route_value_adjust(rv
, med
, path
->peer
);
1653 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
1658 /* Set metric rule structure. */
1659 struct route_map_rule_cmd route_set_metric_cmd
= {
1660 "metric", route_set_metric
, route_value_compile
, route_value_free
,
1663 /* `set as-path prepend ASPATH' */
1665 /* For AS path prepend mechanism. */
1666 static route_map_result_t
route_set_aspath_prepend(void *rule
,
1667 const struct prefix
*prefix
,
1668 route_map_object_t type
,
1671 struct aspath
*aspath
;
1673 struct bgp_path_info
*path
;
1675 if (type
== RMAP_BGP
) {
1678 if (path
->attr
->aspath
->refcnt
)
1679 new = aspath_dup(path
->attr
->aspath
);
1681 new = path
->attr
->aspath
;
1683 if ((uintptr_t)rule
> 10) {
1685 aspath_prepend(aspath
, new);
1687 as_t as
= aspath_leftmost(new);
1689 as
= path
->peer
->as
;
1690 new = aspath_add_seq_n(new, as
, (uintptr_t)rule
);
1693 path
->attr
->aspath
= new;
1699 static void *route_set_aspath_prepend_compile(const char *arg
)
1703 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
<= 10)
1704 return (void *)(uintptr_t)num
;
1706 return route_aspath_compile(arg
);
1709 static void route_set_aspath_prepend_free(void *rule
)
1711 if ((uintptr_t)rule
> 10)
1712 route_aspath_free(rule
);
1716 /* Set as-path prepend rule structure. */
1717 struct route_map_rule_cmd route_set_aspath_prepend_cmd
= {
1718 "as-path prepend", route_set_aspath_prepend
,
1719 route_set_aspath_prepend_compile
, route_set_aspath_prepend_free
,
1722 /* `set as-path exclude ASn' */
1724 /* For ASN exclude mechanism.
1725 * Iterate over ASns requested and filter them from the given AS_PATH one by
1727 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1729 static route_map_result_t
route_set_aspath_exclude(void *rule
,
1730 const struct prefix
*dummy
,
1731 route_map_object_t type
,
1734 struct aspath
*new_path
, *exclude_path
;
1735 struct bgp_path_info
*path
;
1737 if (type
== RMAP_BGP
) {
1738 exclude_path
= rule
;
1740 if (path
->attr
->aspath
->refcnt
)
1741 new_path
= aspath_dup(path
->attr
->aspath
);
1743 new_path
= path
->attr
->aspath
;
1744 path
->attr
->aspath
=
1745 aspath_filter_exclude(new_path
, exclude_path
);
1750 /* Set ASn exlude rule structure. */
1751 struct route_map_rule_cmd route_set_aspath_exclude_cmd
= {
1752 "as-path exclude", route_set_aspath_exclude
, route_aspath_compile
,
1756 /* `set community COMMUNITY' */
1757 struct rmap_com_set
{
1758 struct community
*com
;
1763 /* For community set mechanism. */
1764 static route_map_result_t
route_set_community(void *rule
,
1765 const struct prefix
*prefix
,
1766 route_map_object_t type
,
1769 struct rmap_com_set
*rcs
;
1770 struct bgp_path_info
*path
;
1772 struct community
*new = NULL
;
1773 struct community
*old
;
1774 struct community
*merge
;
1776 if (type
== RMAP_BGP
) {
1780 old
= attr
->community
;
1784 attr
->flag
&= ~(ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
));
1785 attr
->community
= NULL
;
1786 /* See the longer comment down below. */
1787 if (old
&& old
->refcnt
== 0)
1788 community_free(&old
);
1792 /* "additive" case. */
1793 if (rcs
->additive
&& old
) {
1794 merge
= community_merge(community_dup(old
), rcs
->com
);
1796 new = community_uniq_sort(merge
);
1797 community_free(&merge
);
1799 new = community_dup(rcs
->com
);
1801 /* HACK: if the old community is not intern'd,
1802 * we should free it here, or all reference to it may be
1804 * Really need to cleanup attribute caching sometime.
1806 if (old
&& old
->refcnt
== 0)
1807 community_free(&old
);
1809 /* will be interned by caller if required */
1810 attr
->community
= new;
1812 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1818 /* Compile function for set community. */
1819 static void *route_set_community_compile(const char *arg
)
1821 struct rmap_com_set
*rcs
;
1822 struct community
*com
= NULL
;
1827 if (strcmp(arg
, "none") == 0)
1830 sp
= strstr(arg
, "additive");
1832 if (sp
&& sp
> arg
) {
1833 /* "additive" keyword is included. */
1838 com
= community_str2com(arg
);
1847 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_com_set
));
1849 rcs
->additive
= additive
;
1855 /* Free function for set community. */
1856 static void route_set_community_free(void *rule
)
1858 struct rmap_com_set
*rcs
= rule
;
1861 community_free(&rcs
->com
);
1862 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1865 /* Set community rule structure. */
1866 struct route_map_rule_cmd route_set_community_cmd
= {
1867 "community", route_set_community
, route_set_community_compile
,
1868 route_set_community_free
,
1871 /* `set community COMMUNITY' */
1872 struct rmap_lcom_set
{
1873 struct lcommunity
*lcom
;
1879 /* For lcommunity set mechanism. */
1880 static route_map_result_t
route_set_lcommunity(void *rule
,
1881 const struct prefix
*prefix
,
1882 route_map_object_t type
,
1885 struct rmap_lcom_set
*rcs
;
1886 struct bgp_path_info
*path
;
1888 struct lcommunity
*new = NULL
;
1889 struct lcommunity
*old
;
1890 struct lcommunity
*merge
;
1892 if (type
== RMAP_BGP
) {
1896 old
= attr
->lcommunity
;
1901 ~(ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
));
1902 attr
->lcommunity
= NULL
;
1904 /* See the longer comment down below. */
1905 if (old
&& old
->refcnt
== 0)
1906 lcommunity_free(&old
);
1910 if (rcs
->additive
&& old
) {
1911 merge
= lcommunity_merge(lcommunity_dup(old
),
1914 new = lcommunity_uniq_sort(merge
);
1915 lcommunity_free(&merge
);
1917 new = lcommunity_dup(rcs
->lcom
);
1919 /* HACK: if the old large-community is not intern'd,
1920 * we should free it here, or all reference to it may be
1922 * Really need to cleanup attribute caching sometime.
1924 if (old
&& old
->refcnt
== 0)
1925 lcommunity_free(&old
);
1927 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1928 attr
->lcommunity
= new;
1930 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
);
1936 /* Compile function for set community. */
1937 static void *route_set_lcommunity_compile(const char *arg
)
1939 struct rmap_lcom_set
*rcs
;
1940 struct lcommunity
*lcom
= NULL
;
1945 if (strcmp(arg
, "none") == 0)
1948 sp
= strstr(arg
, "additive");
1950 if (sp
&& sp
> arg
) {
1951 /* "additive" keyworkd is included. */
1956 lcom
= lcommunity_str2com(arg
);
1965 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_com_set
));
1967 rcs
->additive
= additive
;
1973 /* Free function for set lcommunity. */
1974 static void route_set_lcommunity_free(void *rule
)
1976 struct rmap_lcom_set
*rcs
= rule
;
1979 lcommunity_free(&rcs
->lcom
);
1981 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1984 /* Set community rule structure. */
1985 struct route_map_rule_cmd route_set_lcommunity_cmd
= {
1986 "large-community", route_set_lcommunity
, route_set_lcommunity_compile
,
1987 route_set_lcommunity_free
,
1990 /* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
1992 /* For large community set mechanism. */
1993 static route_map_result_t
route_set_lcommunity_delete(void *rule
,
1994 const struct prefix
*pfx
,
1995 route_map_object_t type
,
1998 struct community_list
*list
;
1999 struct lcommunity
*merge
;
2000 struct lcommunity
*new;
2001 struct lcommunity
*old
;
2002 struct bgp_path_info
*path
;
2003 struct rmap_community
*rcom
= rule
;
2005 if (type
== RMAP_BGP
) {
2010 list
= community_list_lookup(bgp_clist
, rcom
->name
,
2012 LARGE_COMMUNITY_LIST_MASTER
);
2013 old
= path
->attr
->lcommunity
;
2016 merge
= lcommunity_list_match_delete(
2017 lcommunity_dup(old
), list
);
2018 new = lcommunity_uniq_sort(merge
);
2019 lcommunity_free(&merge
);
2021 /* HACK: if the old community is not intern'd,
2022 * we should free it here, or all reference to it may be
2024 * Really need to cleanup attribute caching sometime.
2026 if (old
->refcnt
== 0)
2027 lcommunity_free(&old
);
2029 if (new->size
== 0) {
2030 path
->attr
->lcommunity
= NULL
;
2031 path
->attr
->flag
&= ~ATTR_FLAG_BIT(
2032 BGP_ATTR_LARGE_COMMUNITIES
);
2033 lcommunity_free(&new);
2035 path
->attr
->lcommunity
= new;
2036 path
->attr
->flag
|= ATTR_FLAG_BIT(
2037 BGP_ATTR_LARGE_COMMUNITIES
);
2045 /* Compile function for set lcommunity. */
2046 static void *route_set_lcommunity_delete_compile(const char *arg
)
2048 struct rmap_community
*rcom
;
2053 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
2055 p
= strchr(arg
, ' ');
2058 str
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
2059 memcpy(str
, arg
, len
);
2064 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
2068 /* Free function for set lcommunity. */
2069 static void route_set_lcommunity_delete_free(void *rule
)
2071 struct rmap_community
*rcom
= rule
;
2073 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
2074 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
2077 /* Set lcommunity rule structure. */
2078 struct route_map_rule_cmd route_set_lcommunity_delete_cmd
= {
2079 "large-comm-list", route_set_lcommunity_delete
,
2080 route_set_lcommunity_delete_compile
, route_set_lcommunity_delete_free
,
2084 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
2086 /* For community set mechanism. */
2087 static route_map_result_t
route_set_community_delete(
2089 const struct prefix
*prefix
,
2090 route_map_object_t type
,
2093 struct community_list
*list
;
2094 struct community
*merge
;
2095 struct community
*new;
2096 struct community
*old
;
2097 struct bgp_path_info
*path
;
2098 struct rmap_community
*rcom
= rule
;
2100 if (type
== RMAP_BGP
) {
2105 list
= community_list_lookup(bgp_clist
, rcom
->name
,
2107 COMMUNITY_LIST_MASTER
);
2108 old
= path
->attr
->community
;
2111 merge
= community_list_match_delete(community_dup(old
),
2113 new = community_uniq_sort(merge
);
2114 community_free(&merge
);
2116 /* HACK: if the old community is not intern'd,
2117 * we should free it here, or all reference to it may be
2119 * Really need to cleanup attribute caching sometime.
2121 if (old
->refcnt
== 0)
2122 community_free(&old
);
2124 if (new->size
== 0) {
2125 path
->attr
->community
= NULL
;
2127 ~ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2128 community_free(&new);
2130 path
->attr
->community
= new;
2132 ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2140 /* Compile function for set community. */
2141 static void *route_set_community_delete_compile(const char *arg
)
2143 struct rmap_community
*rcom
;
2148 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
2150 p
= strchr(arg
, ' ');
2153 str
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
2154 memcpy(str
, arg
, len
);
2159 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
2163 /* Free function for set community. */
2164 static void route_set_community_delete_free(void *rule
)
2166 struct rmap_community
*rcom
= rule
;
2168 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
2169 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
2172 /* Set community rule structure. */
2173 struct route_map_rule_cmd route_set_community_delete_cmd
= {
2174 "comm-list", route_set_community_delete
,
2175 route_set_community_delete_compile
, route_set_community_delete_free
,
2178 /* `set extcommunity rt COMMUNITY' */
2180 /* For community set mechanism. Used by _rt and _soo. */
2181 static route_map_result_t
route_set_ecommunity(void *rule
,
2182 const struct prefix
*prefix
,
2183 route_map_object_t type
,
2186 struct ecommunity
*ecom
;
2187 struct ecommunity
*new_ecom
;
2188 struct ecommunity
*old_ecom
;
2189 struct bgp_path_info
*path
;
2191 if (type
== RMAP_BGP
) {
2198 /* We assume additive for Extended Community. */
2199 old_ecom
= path
->attr
->ecommunity
;
2202 new_ecom
= ecommunity_merge(ecommunity_dup(old_ecom
),
2205 /* old_ecom->refcnt = 1 => owned elsewhere, e.g.
2206 * bgp_update_receive()
2207 * ->refcnt = 0 => set by a previous route-map
2209 if (!old_ecom
->refcnt
)
2210 ecommunity_free(&old_ecom
);
2212 new_ecom
= ecommunity_dup(ecom
);
2214 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
2215 path
->attr
->ecommunity
= new_ecom
;
2217 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
2222 /* Compile function for set community. */
2223 static void *route_set_ecommunity_rt_compile(const char *arg
)
2225 struct ecommunity
*ecom
;
2227 ecom
= ecommunity_str2com(arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
2230 return ecommunity_intern(ecom
);
2233 /* Free function for set community. Used by _rt and _soo */
2234 static void route_set_ecommunity_free(void *rule
)
2236 struct ecommunity
*ecom
= rule
;
2237 ecommunity_unintern(&ecom
);
2240 /* Set community rule structure. */
2241 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
= {
2242 "extcommunity rt", route_set_ecommunity
,
2243 route_set_ecommunity_rt_compile
, route_set_ecommunity_free
,
2246 /* `set extcommunity soo COMMUNITY' */
2248 /* Compile function for set community. */
2249 static void *route_set_ecommunity_soo_compile(const char *arg
)
2251 struct ecommunity
*ecom
;
2253 ecom
= ecommunity_str2com(arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
2257 return ecommunity_intern(ecom
);
2260 /* Set community rule structure. */
2261 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
= {
2262 "extcommunity soo", route_set_ecommunity
,
2263 route_set_ecommunity_soo_compile
, route_set_ecommunity_free
,
2266 /* `set origin ORIGIN' */
2268 /* For origin set. */
2269 static route_map_result_t
route_set_origin(void *rule
,
2270 const struct prefix
*prefix
,
2271 route_map_object_t type
,
2275 struct bgp_path_info
*path
;
2277 if (type
== RMAP_BGP
) {
2281 path
->attr
->origin
= *origin
;
2287 /* Compile function for origin set. */
2288 static void *route_set_origin_compile(const char *arg
)
2292 origin
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
2294 if (strcmp(arg
, "igp") == 0)
2296 else if (strcmp(arg
, "egp") == 0)
2304 /* Compile function for origin set. */
2305 static void route_set_origin_free(void *rule
)
2307 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2310 /* Set origin rule structure. */
2311 struct route_map_rule_cmd route_set_origin_cmd
= {
2312 "origin", route_set_origin
, route_set_origin_compile
,
2313 route_set_origin_free
,
2316 /* `set atomic-aggregate' */
2318 /* For atomic aggregate set. */
2319 static route_map_result_t
route_set_atomic_aggregate(void *rule
,
2320 const struct prefix
*pfx
,
2321 route_map_object_t type
,
2324 struct bgp_path_info
*path
;
2326 if (type
== RMAP_BGP
) {
2328 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
2334 /* Compile function for atomic aggregate. */
2335 static void *route_set_atomic_aggregate_compile(const char *arg
)
2340 /* Compile function for atomic aggregate. */
2341 static void route_set_atomic_aggregate_free(void *rule
)
2346 /* Set atomic aggregate rule structure. */
2347 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
= {
2348 "atomic-aggregate", route_set_atomic_aggregate
,
2349 route_set_atomic_aggregate_compile
, route_set_atomic_aggregate_free
,
2352 /* `set aggregator as AS A.B.C.D' */
2355 struct in_addr address
;
2358 static route_map_result_t
route_set_aggregator_as(void *rule
,
2359 const struct prefix
*prefix
,
2360 route_map_object_t type
,
2363 struct bgp_path_info
*path
;
2364 struct aggregator
*aggregator
;
2366 if (type
== RMAP_BGP
) {
2370 path
->attr
->aggregator_as
= aggregator
->as
;
2371 path
->attr
->aggregator_addr
= aggregator
->address
;
2372 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
);
2378 static void *route_set_aggregator_as_compile(const char *arg
)
2380 struct aggregator
*aggregator
;
2386 XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct aggregator
));
2387 if (sscanf(arg
, "%s %s", as
, address
) != 2) {
2388 XFREE(MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2392 aggregator
->as
= strtoul(as
, NULL
, 10);
2393 ret
= inet_aton(address
, &aggregator
->address
);
2395 XFREE(MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2401 static void route_set_aggregator_as_free(void *rule
)
2403 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2406 struct route_map_rule_cmd route_set_aggregator_as_cmd
= {
2407 "aggregator as", route_set_aggregator_as
,
2408 route_set_aggregator_as_compile
, route_set_aggregator_as_free
,
2411 /* Set tag to object. object must be pointer to struct bgp_path_info */
2412 static route_map_result_t
route_set_tag(void *rule
,
2413 const struct prefix
*prefix
,
2414 route_map_object_t type
, void *object
)
2417 struct bgp_path_info
*path
;
2419 if (type
== RMAP_BGP
) {
2424 path
->attr
->tag
= *tag
;
2430 /* Route map commands for tag set. */
2431 static struct route_map_rule_cmd route_set_tag_cmd
= {
2432 "tag", route_set_tag
, route_map_rule_tag_compile
,
2433 route_map_rule_tag_free
,
2436 /* Set label-index to object. object must be pointer to struct bgp_path_info */
2437 static route_map_result_t
route_set_label_index(void *rule
,
2438 const struct prefix
*prefix
,
2439 route_map_object_t type
,
2442 struct rmap_value
*rv
;
2443 struct bgp_path_info
*path
;
2444 uint32_t label_index
;
2446 if (type
== RMAP_BGP
) {
2447 /* Fetch routemap's rule information. */
2451 /* Set label-index value. */
2452 label_index
= rv
->value
;
2454 path
->attr
->label_index
= label_index
;
2455 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
2462 /* Route map commands for label-index set. */
2463 static struct route_map_rule_cmd route_set_label_index_cmd
= {
2464 "label-index", route_set_label_index
, route_value_compile
,
2468 /* `match ipv6 address IP_ACCESS_LIST' */
2470 static route_map_result_t
route_match_ipv6_address(void *rule
,
2471 const struct prefix
*prefix
,
2472 route_map_object_t type
,
2475 struct access_list
*alist
;
2477 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET6
) {
2478 alist
= access_list_lookup(AFI_IP6
, (char *)rule
);
2480 return RMAP_NOMATCH
;
2482 return (access_list_apply(alist
, prefix
) == FILTER_DENY
2486 return RMAP_NOMATCH
;
2489 static void *route_match_ipv6_address_compile(const char *arg
)
2491 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
2494 static void route_match_ipv6_address_free(void *rule
)
2496 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2499 /* Route map commands for ip address matching. */
2500 struct route_map_rule_cmd route_match_ipv6_address_cmd
= {
2501 "ipv6 address", route_match_ipv6_address
,
2502 route_match_ipv6_address_compile
, route_match_ipv6_address_free
};
2504 /* `match ipv6 next-hop IP_ADDRESS' */
2506 static route_map_result_t
route_match_ipv6_next_hop(void *rule
,
2507 const struct prefix
*prefix
,
2508 route_map_object_t type
,
2511 struct in6_addr
*addr
= rule
;
2512 struct bgp_path_info
*path
;
2514 if (type
== RMAP_BGP
) {
2517 if (IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_global
, addr
))
2520 if (path
->attr
->mp_nexthop_len
2521 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
2522 && IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_local
, rule
))
2525 return RMAP_NOMATCH
;
2528 return RMAP_NOMATCH
;
2531 static void *route_match_ipv6_next_hop_compile(const char *arg
)
2533 struct in6_addr
*address
;
2536 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2538 ret
= inet_pton(AF_INET6
, arg
, address
);
2540 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2547 static void route_match_ipv6_next_hop_free(void *rule
)
2549 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2552 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
= {
2553 "ipv6 next-hop", route_match_ipv6_next_hop
,
2554 route_match_ipv6_next_hop_compile
, route_match_ipv6_next_hop_free
};
2556 /* `match ipv6 address prefix-list PREFIX_LIST' */
2558 static route_map_result_t
2559 route_match_ipv6_address_prefix_list(void *rule
, const struct prefix
*prefix
,
2560 route_map_object_t type
, void *object
)
2562 struct prefix_list
*plist
;
2564 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET6
) {
2565 plist
= prefix_list_lookup(AFI_IP6
, (char *)rule
);
2567 return RMAP_NOMATCH
;
2569 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
2573 return RMAP_NOMATCH
;
2576 static void *route_match_ipv6_address_prefix_list_compile(const char *arg
)
2578 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
2581 static void route_match_ipv6_address_prefix_list_free(void *rule
)
2583 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2586 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
= {
2587 "ipv6 address prefix-list", route_match_ipv6_address_prefix_list
,
2588 route_match_ipv6_address_prefix_list_compile
,
2589 route_match_ipv6_address_prefix_list_free
};
2591 /* `match ipv6 next-hop type <TYPE>' */
2593 static route_map_result_t
2594 route_match_ipv6_next_hop_type(void *rule
, const struct prefix
*prefix
,
2595 route_map_object_t type
, void *object
)
2597 struct bgp_path_info
*path
;
2598 struct in6_addr
*addr
= rule
;
2600 if (type
== RMAP_BGP
&& prefix
->family
== AF_INET6
) {
2601 path
= (struct bgp_path_info
*)object
;
2602 if (!path
|| !path
->attr
)
2603 return RMAP_DENYMATCH
;
2605 if (IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_global
, addr
)
2606 && !path
->attr
->nh_ifindex
)
2609 return RMAP_NOMATCH
;
2612 static void *route_match_ipv6_next_hop_type_compile(const char *arg
)
2614 struct in6_addr
*address
;
2617 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2619 ret
= inet_pton(AF_INET6
, "::0", address
);
2621 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2628 static void route_match_ipv6_next_hop_type_free(void *rule
)
2630 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2633 struct route_map_rule_cmd route_match_ipv6_next_hop_type_cmd
= {
2634 "ipv6 next-hop type", route_match_ipv6_next_hop_type
,
2635 route_match_ipv6_next_hop_type_compile
,
2636 route_match_ipv6_next_hop_type_free
};
2638 /* `set ipv6 nexthop global IP_ADDRESS' */
2640 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2641 static route_map_result_t
route_set_ipv6_nexthop_global(void *rule
,
2642 const struct prefix
*p
,
2643 route_map_object_t type
,
2646 struct in6_addr
*address
;
2647 struct bgp_path_info
*path
;
2649 if (type
== RMAP_BGP
) {
2650 /* Fetch routemap's rule information. */
2654 /* Set next hop value. */
2655 path
->attr
->mp_nexthop_global
= *address
;
2657 /* Set nexthop length. */
2658 if (path
->attr
->mp_nexthop_len
== 0)
2659 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2661 SET_FLAG(path
->attr
->rmap_change_flags
,
2662 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2668 /* Route map `ip next-hop' compile function. Given string is converted
2669 to struct in_addr structure. */
2670 static void *route_set_ipv6_nexthop_global_compile(const char *arg
)
2673 struct in6_addr
*address
;
2675 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2677 ret
= inet_pton(AF_INET6
, arg
, address
);
2680 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2687 /* Free route map's compiled `ip next-hop' value. */
2688 static void route_set_ipv6_nexthop_global_free(void *rule
)
2690 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2693 /* Route map commands for ip nexthop set. */
2694 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
= {
2695 "ipv6 next-hop global", route_set_ipv6_nexthop_global
,
2696 route_set_ipv6_nexthop_global_compile
,
2697 route_set_ipv6_nexthop_global_free
};
2699 /* Set next-hop preference value. */
2700 static route_map_result_t
2701 route_set_ipv6_nexthop_prefer_global(void *rule
, const struct prefix
*prefix
,
2702 route_map_object_t type
, void *object
)
2704 struct bgp_path_info
*path
;
2707 if (type
== RMAP_BGP
) {
2708 /* Fetch routemap's rule information. */
2712 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
2713 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2715 && sockunion_family(peer
->su_remote
) == AF_INET6
) {
2716 /* Set next hop preference to global */
2717 path
->attr
->mp_nexthop_prefer_global
= TRUE
;
2718 SET_FLAG(path
->attr
->rmap_change_flags
,
2719 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2721 path
->attr
->mp_nexthop_prefer_global
= FALSE
;
2722 SET_FLAG(path
->attr
->rmap_change_flags
,
2723 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2729 static void *route_set_ipv6_nexthop_prefer_global_compile(const char *arg
)
2733 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
2739 /* Free route map's compiled `ip next-hop' value. */
2740 static void route_set_ipv6_nexthop_prefer_global_free(void *rule
)
2742 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2745 /* Route map commands for ip nexthop set preferred. */
2746 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
= {
2747 "ipv6 next-hop prefer-global", route_set_ipv6_nexthop_prefer_global
,
2748 route_set_ipv6_nexthop_prefer_global_compile
,
2749 route_set_ipv6_nexthop_prefer_global_free
};
2751 /* `set ipv6 nexthop local IP_ADDRESS' */
2753 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2754 static route_map_result_t
route_set_ipv6_nexthop_local(void *rule
,
2755 const struct prefix
*p
,
2756 route_map_object_t type
,
2759 struct in6_addr
*address
;
2760 struct bgp_path_info
*path
;
2762 if (type
== RMAP_BGP
) {
2763 /* Fetch routemap's rule information. */
2767 /* Set next hop value. */
2768 path
->attr
->mp_nexthop_local
= *address
;
2770 /* Set nexthop length. */
2771 if (path
->attr
->mp_nexthop_len
2772 != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2773 path
->attr
->mp_nexthop_len
=
2774 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2776 SET_FLAG(path
->attr
->rmap_change_flags
,
2777 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2783 /* Route map `ip nexthop' compile function. Given string is converted
2784 to struct in_addr structure. */
2785 static void *route_set_ipv6_nexthop_local_compile(const char *arg
)
2788 struct in6_addr
*address
;
2790 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2792 ret
= inet_pton(AF_INET6
, arg
, address
);
2795 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2802 /* Free route map's compiled `ip nexthop' value. */
2803 static void route_set_ipv6_nexthop_local_free(void *rule
)
2805 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2808 /* Route map commands for ip nexthop set. */
2809 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
= {
2810 "ipv6 next-hop local", route_set_ipv6_nexthop_local
,
2811 route_set_ipv6_nexthop_local_compile
,
2812 route_set_ipv6_nexthop_local_free
};
2814 /* `set ipv6 nexthop peer-address' */
2816 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2817 static route_map_result_t
route_set_ipv6_nexthop_peer(void *rule
,
2818 const struct prefix
*pfx
,
2819 route_map_object_t type
,
2822 struct in6_addr peer_address
;
2823 struct bgp_path_info
*path
;
2826 if (type
== RMAP_BGP
) {
2827 /* Fetch routemap's rule information. */
2831 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
2832 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2834 && sockunion_family(peer
->su_remote
) == AF_INET6
) {
2835 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
2836 /* Set next hop value and length in attribute. */
2837 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
)) {
2838 path
->attr
->mp_nexthop_local
= peer_address
;
2839 if (path
->attr
->mp_nexthop_len
!= 32)
2840 path
->attr
->mp_nexthop_len
= 32;
2842 path
->attr
->mp_nexthop_global
= peer_address
;
2843 if (path
->attr
->mp_nexthop_len
== 0)
2844 path
->attr
->mp_nexthop_len
= 16;
2847 } else if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
)) {
2848 /* The next hop value will be set as part of packet
2850 * Set the flags here to indicate that rewrite needs to
2852 * Also, clear the value - we clear both global and
2854 * nexthops, whether we send one or both is determined
2857 SET_FLAG(path
->attr
->rmap_change_flags
,
2858 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2859 /* clear next hop value. */
2860 memset(&(path
->attr
->mp_nexthop_global
), 0,
2861 sizeof(struct in6_addr
));
2862 memset(&(path
->attr
->mp_nexthop_local
), 0,
2863 sizeof(struct in6_addr
));
2870 /* Route map `ip next-hop' compile function. Given string is converted
2871 to struct in_addr structure. */
2872 static void *route_set_ipv6_nexthop_peer_compile(const char *arg
)
2876 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
2882 /* Free route map's compiled `ip next-hop' value. */
2883 static void route_set_ipv6_nexthop_peer_free(void *rule
)
2885 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2888 /* Route map commands for ip nexthop set. */
2889 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
= {
2890 "ipv6 next-hop peer-address", route_set_ipv6_nexthop_peer
,
2891 route_set_ipv6_nexthop_peer_compile
, route_set_ipv6_nexthop_peer_free
};
2893 /* `set ipv4 vpn next-hop A.B.C.D' */
2895 static route_map_result_t
route_set_vpnv4_nexthop(void *rule
,
2896 const struct prefix
*prefix
,
2897 route_map_object_t type
,
2900 struct in_addr
*address
;
2901 struct bgp_path_info
*path
;
2903 if (type
== RMAP_BGP
) {
2904 /* Fetch routemap's rule information. */
2908 /* Set next hop value. */
2909 path
->attr
->mp_nexthop_global_in
= *address
;
2910 path
->attr
->mp_nexthop_len
= 4;
2916 static void *route_set_vpnv4_nexthop_compile(const char *arg
)
2919 struct in_addr
*address
;
2921 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
2923 ret
= inet_aton(arg
, address
);
2926 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2933 /* `set ipv6 vpn next-hop A.B.C.D' */
2935 static route_map_result_t
route_set_vpnv6_nexthop(void *rule
,
2936 const struct prefix
*prefix
,
2937 route_map_object_t type
,
2940 struct in6_addr
*address
;
2941 struct bgp_path_info
*path
;
2943 if (type
== RMAP_BGP
) {
2944 /* Fetch routemap's rule information. */
2948 /* Set next hop value. */
2949 memcpy(&path
->attr
->mp_nexthop_global
, address
,
2950 sizeof(struct in6_addr
));
2951 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_VPNV6_GLOBAL
;
2957 static void *route_set_vpnv6_nexthop_compile(const char *arg
)
2960 struct in6_addr
*address
;
2962 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
2963 ret
= inet_pton(AF_INET6
, arg
, address
);
2966 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
2973 static void route_set_vpn_nexthop_free(void *rule
)
2975 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2978 /* Route map commands for ipv4 next-hop set. */
2979 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
= {
2980 "ipv4 vpn next-hop", route_set_vpnv4_nexthop
,
2981 route_set_vpnv4_nexthop_compile
, route_set_vpn_nexthop_free
};
2983 /* Route map commands for ipv6 next-hop set. */
2984 struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd
= {
2985 "ipv6 vpn next-hop", route_set_vpnv6_nexthop
,
2986 route_set_vpnv6_nexthop_compile
, route_set_vpn_nexthop_free
};
2988 /* `set originator-id' */
2990 /* For origin set. */
2991 static route_map_result_t
route_set_originator_id(void *rule
,
2992 const struct prefix
*prefix
,
2993 route_map_object_t type
,
2996 struct in_addr
*address
;
2997 struct bgp_path_info
*path
;
2999 if (type
== RMAP_BGP
) {
3003 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
);
3004 path
->attr
->originator_id
= *address
;
3010 /* Compile function for originator-id set. */
3011 static void *route_set_originator_id_compile(const char *arg
)
3014 struct in_addr
*address
;
3016 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
3018 ret
= inet_aton(arg
, address
);
3021 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3028 /* Compile function for originator_id set. */
3029 static void route_set_originator_id_free(void *rule
)
3031 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3034 /* Set originator-id rule structure. */
3035 struct route_map_rule_cmd route_set_originator_id_cmd
= {
3036 "originator-id", route_set_originator_id
,
3037 route_set_originator_id_compile
, route_set_originator_id_free
,
3040 /* Add bgp route map rule. */
3041 static int bgp_route_match_add(struct vty
*vty
, const char *command
,
3042 const char *arg
, route_map_event_t type
)
3044 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
3045 int retval
= CMD_SUCCESS
;
3048 ret
= route_map_add_match(index
, command
, arg
);
3050 case RMAP_RULE_MISSING
:
3051 vty_out(vty
, "%% BGP Can't find rule.\n");
3052 retval
= CMD_WARNING_CONFIG_FAILED
;
3054 case RMAP_COMPILE_ERROR
:
3055 vty_out(vty
, "%% BGP Argument is malformed.\n");
3056 retval
= CMD_WARNING_CONFIG_FAILED
;
3058 case RMAP_COMPILE_SUCCESS
:
3059 if (type
!= RMAP_EVENT_MATCH_ADDED
) {
3060 route_map_upd8_dependency(type
, arg
, index
->map
->name
);
3068 /* Delete bgp route map rule. */
3069 static int bgp_route_match_delete(struct vty
*vty
, const char *command
,
3070 const char *arg
, route_map_event_t type
)
3072 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
3074 int retval
= CMD_SUCCESS
;
3075 char *dep_name
= NULL
;
3077 char *rmap_name
= NULL
;
3079 if (type
!= RMAP_EVENT_MATCH_DELETED
) {
3080 /* ignore the mundane, the types without any dependency */
3082 if ((tmpstr
= route_map_get_match_arg(index
, command
))
3085 XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
3087 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
3089 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
3092 ret
= route_map_delete_match(index
, command
, dep_name
);
3094 case RMAP_RULE_MISSING
:
3095 vty_out(vty
, "%% BGP Can't find rule.\n");
3096 retval
= CMD_WARNING_CONFIG_FAILED
;
3098 case RMAP_COMPILE_ERROR
:
3099 vty_out(vty
, "%% BGP Argument is malformed.\n");
3100 retval
= CMD_WARNING_CONFIG_FAILED
;
3102 case RMAP_COMPILE_SUCCESS
:
3103 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
3104 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
3109 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
3111 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
3117 * This is the workhorse routine for processing in/out routemap
3120 static void bgp_route_map_process_peer(const char *rmap_name
,
3121 struct route_map
*map
, struct peer
*peer
,
3122 int afi
, int safi
, int route_update
)
3126 struct bgp_filter
*filter
;
3128 if (!peer
|| !rmap_name
)
3131 filter
= &peer
->filter
[afi
][safi
];
3133 * in is for non-route-server clients,
3134 * out is for all peers
3136 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
)) {
3137 if (filter
->map
[RMAP_IN
].name
3138 && (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0)) {
3139 filter
->map
[RMAP_IN
].map
= map
;
3141 if (route_update
&& peer
->status
== Established
) {
3142 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
3143 PEER_FLAG_SOFT_RECONFIG
)) {
3144 if (bgp_debug_update(peer
, NULL
, NULL
,
3147 "Processing route_map %s update on "
3148 "peer %s (inbound, soft-reconfig)",
3149 rmap_name
, peer
->host
);
3151 bgp_soft_reconfig_in(peer
, afi
, safi
);
3153 CHECK_FLAG(peer
->cap
,
3154 PEER_CAP_REFRESH_OLD_RCV
)
3157 PEER_CAP_REFRESH_NEW_RCV
)) {
3159 if (bgp_debug_update(peer
, NULL
, NULL
,
3162 "Processing route_map %s update on "
3163 "peer %s (inbound, route-refresh)",
3164 rmap_name
, peer
->host
);
3165 bgp_route_refresh_send(peer
, afi
, safi
,
3172 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
)) {
3175 if (update
&& route_update
&& peer
->status
== Established
) {
3176 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
3177 PEER_FLAG_SOFT_RECONFIG
)) {
3178 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
3180 "Processing route_map %s update on "
3181 "peer %s (import, soft-reconfig)",
3182 rmap_name
, peer
->host
);
3184 bgp_soft_reconfig_in(peer
, afi
, safi
);
3185 } else if (CHECK_FLAG(peer
->cap
,
3186 PEER_CAP_REFRESH_OLD_RCV
)
3187 || CHECK_FLAG(peer
->cap
,
3188 PEER_CAP_REFRESH_NEW_RCV
)) {
3189 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
3191 "Processing route_map %s update on "
3192 "peer %s (import, route-refresh)",
3193 rmap_name
, peer
->host
);
3194 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
3197 /* DD: Else, what else do we do ? Reset peer ? */
3202 * For outbound, unsuppress and default-originate map change (content or
3203 * map created), merely update the "config" here, the actual route
3204 * announcement happens at the group level.
3206 if (filter
->map
[RMAP_OUT
].name
3207 && (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
3208 filter
->map
[RMAP_OUT
].map
= map
;
3210 if (filter
->usmap
.name
&& (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3211 filter
->usmap
.map
= map
;
3213 if (peer
->default_rmap
[afi
][safi
].name
3214 && (strcmp(rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
3215 peer
->default_rmap
[afi
][safi
].map
= map
;
3218 static void bgp_route_map_update_peer_group(const char *rmap_name
,
3219 struct route_map
*map
,
3222 struct peer_group
*group
;
3223 struct listnode
*node
, *nnode
;
3224 struct bgp_filter
*filter
;
3231 /* All the peers have been updated correctly already. This is
3232 * just updating the placeholder data. No real update required.
3234 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
3235 FOREACH_AFI_SAFI (afi
, safi
) {
3236 filter
= &group
->conf
->filter
[afi
][safi
];
3238 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++) {
3239 if ((filter
->map
[direct
].name
)
3240 && (strcmp(rmap_name
,
3241 filter
->map
[direct
].name
)
3243 filter
->map
[direct
].map
= map
;
3246 if (filter
->usmap
.name
3247 && (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3248 filter
->usmap
.map
= map
;
3254 * Note that if an extreme number (tens of thousands) of route-maps are in use
3255 * and if bgp has an extreme number of peers, network statements, etc then this
3256 * function can consume a lot of cycles. This is due to this function being
3257 * called for each route-map and within this function we walk the list of peers,
3258 * network statements, etc looking to see if they use this route-map.
3260 static void bgp_route_map_process_update(struct bgp
*bgp
, const char *rmap_name
,
3267 struct bgp_node
*bn
;
3268 struct bgp_static
*bgp_static
;
3269 struct listnode
*node
, *nnode
;
3270 struct route_map
*map
;
3271 char buf
[INET6_ADDRSTRLEN
];
3273 map
= route_map_lookup_by_name(rmap_name
);
3275 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
3277 /* Ignore dummy peer-group structure */
3278 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3281 FOREACH_AFI_SAFI (afi
, safi
) {
3282 /* process in/out/import/export/default-orig
3284 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
,
3285 safi
, route_update
);
3289 /* for outbound/default-orig route-maps, process for groups */
3290 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
3293 /* update peer-group config (template) */
3294 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
3296 FOREACH_AFI_SAFI (afi
, safi
) {
3297 /* For table route-map updates. */
3298 if (!bgp_fibupd_safi(safi
))
3301 if (bgp
->table_map
[afi
][safi
].name
3302 && (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
)
3305 /* bgp->table_map[afi][safi].map is NULL.
3306 * i.e Route map creation event.
3307 * So update applied_counter.
3308 * If it is not NULL, i.e It may be routemap updation or
3309 * deletion. so no need to update the counter.
3311 if (!bgp
->table_map
[afi
][safi
].map
)
3312 route_map_counter_increment(map
);
3313 bgp
->table_map
[afi
][safi
].map
= map
;
3315 if (BGP_DEBUG(zebra
, ZEBRA
))
3317 "Processing route_map %s update on "
3321 bgp_zebra_announce_table(bgp
, afi
, safi
);
3324 /* For network route-map updates. */
3325 for (bn
= bgp_table_top(bgp
->route
[afi
][safi
]); bn
;
3326 bn
= bgp_route_next(bn
)) {
3327 bgp_static
= bgp_node_get_bgp_static_info(bn
);
3331 if (!bgp_static
->rmap
.name
3332 || (strcmp(rmap_name
, bgp_static
->rmap
.name
) != 0))
3335 if (!bgp_static
->rmap
.map
)
3336 route_map_counter_increment(map
);
3338 bgp_static
->rmap
.map
= map
;
3340 if (route_update
&& !bgp_static
->backdoor
) {
3341 if (bgp_debug_zebra(&bn
->p
))
3343 "Processing route_map %s update on static route %s",
3345 inet_ntop(bn
->p
.family
,
3346 &bn
->p
.u
.prefix
, buf
,
3348 bgp_static_update(bgp
, &bn
->p
, bgp_static
, afi
,
3354 /* For redistribute route-map updates. */
3355 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3356 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3357 struct list
*red_list
;
3358 struct bgp_redist
*red
;
3360 red_list
= bgp
->redist
[afi
][i
];
3364 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
)) {
3366 || (strcmp(rmap_name
, red
->rmap
.name
) != 0))
3370 route_map_counter_increment(map
);
3372 red
->rmap
.map
= map
;
3377 if (BGP_DEBUG(zebra
, ZEBRA
))
3379 "Processing route_map %s update on redistributed routes",
3382 bgp_redistribute_resend(bgp
, afi
, i
,
3387 /* for type5 command route-maps */
3388 FOREACH_AFI_SAFI (afi
, safi
) {
3389 if (!bgp
->adv_cmd_rmap
[afi
][safi
].name
3390 || strcmp(rmap_name
, bgp
->adv_cmd_rmap
[afi
][safi
].name
)
3394 /* Make sure the route-map is populated here if not already done */
3395 bgp
->adv_cmd_rmap
[afi
][safi
].map
= map
;
3397 if (BGP_DEBUG(zebra
, ZEBRA
))
3399 "Processing route_map %s update on advertise type5 route command",
3403 bgp_evpn_withdraw_type5_routes(bgp
, afi
, safi
);
3404 bgp_evpn_advertise_type5_routes(bgp
, afi
, safi
);
3409 static void bgp_route_map_process_update_cb(char *rmap_name
)
3411 struct listnode
*node
, *nnode
;
3414 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
3415 bgp_route_map_process_update(bgp
, rmap_name
, 1);
3418 /* zlog_debug("%s: calling vnc_routemap_update", __func__); */
3419 vnc_routemap_update(bgp
, __func__
);
3423 vpn_policy_routemap_event(rmap_name
);
3426 int bgp_route_map_update_timer(struct thread
*thread
)
3428 bm
->t_rmap_update
= NULL
;
3430 route_map_walk_update_list(bgp_route_map_process_update_cb
);
3435 static void bgp_route_map_mark_update(const char *rmap_name
)
3437 if (bm
->t_rmap_update
== NULL
) {
3438 struct listnode
*node
, *nnode
;
3441 /* rmap_update_timer of 0 means don't do route updates */
3442 if (bm
->rmap_update_timer
) {
3443 bm
->t_rmap_update
= NULL
;
3444 thread_add_timer(bm
->master
, bgp_route_map_update_timer
,
3445 NULL
, bm
->rmap_update_timer
,
3446 &bm
->t_rmap_update
);
3448 /* Signal the groups that a route-map update event has
3450 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3451 update_group_policy_update(bgp
,
3452 BGP_POLICY_ROUTE_MAP
,
3455 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3456 bgp_route_map_process_update(bgp
, rmap_name
, 0);
3458 zlog_debug("%s: calling vnc_routemap_update", __func__
);
3459 vnc_routemap_update(bgp
, __func__
);
3465 static void bgp_route_map_add(const char *rmap_name
)
3467 if (route_map_mark_updated(rmap_name
) == 0)
3468 bgp_route_map_mark_update(rmap_name
);
3470 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3473 static void bgp_route_map_delete(const char *rmap_name
)
3475 if (route_map_mark_updated(rmap_name
) == 0)
3476 bgp_route_map_mark_update(rmap_name
);
3478 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
3481 static void bgp_route_map_event(route_map_event_t event
, const char *rmap_name
)
3483 if (route_map_mark_updated(rmap_name
) == 0)
3484 bgp_route_map_mark_update(rmap_name
);
3486 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3489 DEFUN (match_mac_address
,
3490 match_mac_address_cmd
,
3491 "match mac address WORD",
3494 "Match address of route\n"
3495 "MAC Access-list name\n")
3497 return bgp_route_match_add(vty
, "mac address", argv
[3]->arg
,
3498 RMAP_EVENT_FILTER_ADDED
);
3501 DEFUN (no_match_mac_address
,
3502 no_match_mac_address_cmd
,
3503 "no match mac address WORD",
3507 "Match address of route\n"
3508 "MAC acess-list name\n")
3510 return bgp_route_match_delete(vty
, "mac address", argv
[4]->arg
,
3511 RMAP_EVENT_FILTER_DELETED
);
3514 DEFUN (match_evpn_route_type
,
3515 match_evpn_route_type_cmd
,
3516 "match evpn route-type <macip | multicast | prefix>",
3519 "Match route-type\n"
3524 return bgp_route_match_add(vty
, "evpn route-type", argv
[3]->arg
,
3525 RMAP_EVENT_MATCH_ADDED
);
3528 DEFUN (no_match_evpn_route_type
,
3529 no_match_evpn_route_type_cmd
,
3530 "no match evpn route-type <macip | multicast | prefix>",
3534 "Match route-type\n"
3539 return bgp_route_match_delete(vty
, "evpn route-type", argv
[4]->arg
,
3540 RMAP_EVENT_MATCH_DELETED
);
3544 DEFUN (match_evpn_vni
,
3546 "match evpn vni " CMD_VNI_RANGE
,
3552 return bgp_route_match_add(vty
, "evpn vni", argv
[3]->arg
,
3553 RMAP_EVENT_MATCH_ADDED
);
3556 DEFUN (no_match_evpn_vni
,
3557 no_match_evpn_vni_cmd
,
3558 "no match evpn vni " CMD_VNI_RANGE
,
3565 return bgp_route_match_delete(vty
, "evpn vni", argv
[4]->arg
,
3566 RMAP_EVENT_MATCH_DELETED
);
3569 DEFUN (match_evpn_default_route
,
3570 match_evpn_default_route_cmd
,
3571 "match evpn default-route",
3574 "default EVPN type-5 route\n")
3576 return bgp_route_match_add(vty
, "evpn default-route", NULL
,
3577 RMAP_EVENT_MATCH_ADDED
);
3580 DEFUN (no_match_evpn_default_route
,
3581 no_match_evpn_default_route_cmd
,
3582 "no match evpn default-route",
3586 "default EVPN type-5 route\n")
3588 return bgp_route_match_delete(vty
, "evpn default-route", NULL
,
3589 RMAP_EVENT_MATCH_DELETED
);
3592 DEFPY(match_vrl_source_vrf
,
3593 match_vrl_source_vrf_cmd
,
3594 "match source-vrf NAME$vrf_name",
3599 return bgp_route_match_add(vty
, "source-vrf", vrf_name
,
3600 RMAP_EVENT_MATCH_ADDED
);
3603 DEFPY(no_match_vrl_source_vrf
,
3604 no_match_vrl_source_vrf_cmd
,
3605 "no match source-vrf NAME$vrf_name",
3611 return bgp_route_match_delete(vty
, "source-vrf", vrf_name
,
3612 RMAP_EVENT_MATCH_DELETED
);
3617 "match peer <A.B.C.D|X:X::X:X|WORD>",
3619 "Match peer address\n"
3620 "IP address of peer\n"
3621 "IPv6 address of peer\n"
3622 "Interface name of peer\n")
3625 return bgp_route_match_add(vty
, "peer", argv
[idx_ip
]->arg
,
3626 RMAP_EVENT_MATCH_ADDED
);
3629 DEFUN (match_peer_local
,
3630 match_peer_local_cmd
,
3633 "Match peer address\n"
3634 "Static or Redistributed routes\n")
3636 return bgp_route_match_add(vty
, "peer", "local",
3637 RMAP_EVENT_MATCH_DELETED
);
3640 DEFUN (no_match_peer
,
3642 "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
3645 "Match peer address\n"
3646 "Static or Redistributed routes\n"
3647 "IP address of peer\n"
3648 "IPv6 address of peer\n"
3649 "Interface name of peer\n")
3653 if (argc
<= idx_peer
)
3654 return bgp_route_match_delete(vty
, "peer", NULL
,
3655 RMAP_EVENT_MATCH_DELETED
);
3656 return bgp_route_match_delete(vty
, "peer", argv
[idx_peer
]->arg
,
3657 RMAP_EVENT_MATCH_DELETED
);
3660 #if defined(HAVE_LUA)
3661 DEFUN (match_command
,
3663 "match command WORD",
3665 "Run a command to match\n"
3666 "The command to run\n")
3668 return bgp_route_match_add(vty
, "command", argv
[2]->arg
,
3669 RMAP_EVENT_FILTER_ADDED
);
3672 DEFUN (no_match_command
,
3673 no_match_command_cmd
,
3674 "no match command WORD",
3677 "Run a command to match\n"
3678 "The command to run\n")
3680 return bgp_route_match_delete(vty
, "command", argv
[3]->arg
,
3681 RMAP_EVENT_FILTER_DELETED
);
3685 /* match probability */
3686 DEFUN (match_probability
,
3687 match_probability_cmd
,
3688 "match probability (0-100)",
3690 "Match portion of routes defined by percentage value\n"
3691 "Percentage of routes\n")
3694 return bgp_route_match_add(vty
, "probability", argv
[idx_number
]->arg
,
3695 RMAP_EVENT_MATCH_ADDED
);
3699 DEFUN (no_match_probability
,
3700 no_match_probability_cmd
,
3701 "no match probability [(1-99)]",
3704 "Match portion of routes defined by percentage value\n"
3705 "Percentage of routes\n")
3708 if (argc
<= idx_number
)
3709 return bgp_route_match_delete(vty
, "probability", NULL
,
3710 RMAP_EVENT_MATCH_DELETED
);
3711 return bgp_route_match_delete(vty
, "probability", argv
[idx_number
]->arg
,
3712 RMAP_EVENT_MATCH_DELETED
);
3716 DEFUN (match_ip_route_source
,
3717 match_ip_route_source_cmd
,
3718 "match ip route-source <(1-199)|(1300-2699)|WORD>",
3721 "Match advertising source address of route\n"
3722 "IP access-list number\n"
3723 "IP access-list number (expanded range)\n"
3724 "IP standard access-list name\n")
3727 return bgp_route_match_add(vty
, "ip route-source", argv
[idx_acl
]->arg
,
3728 RMAP_EVENT_FILTER_ADDED
);
3732 DEFUN (no_match_ip_route_source
,
3733 no_match_ip_route_source_cmd
,
3734 "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
3738 "Match advertising source address of route\n"
3739 "IP access-list number\n"
3740 "IP access-list number (expanded range)\n"
3741 "IP standard access-list name\n")
3744 if (argc
<= idx_number
)
3745 return bgp_route_match_delete(vty
, "ip route-source", NULL
,
3746 RMAP_EVENT_FILTER_DELETED
);
3747 return bgp_route_match_delete(vty
, "ip route-source",
3748 argv
[idx_number
]->arg
,
3749 RMAP_EVENT_FILTER_DELETED
);
3753 DEFUN (match_ip_route_source_prefix_list
,
3754 match_ip_route_source_prefix_list_cmd
,
3755 "match ip route-source prefix-list WORD",
3758 "Match advertising source address of route\n"
3759 "Match entries of prefix-lists\n"
3760 "IP prefix-list name\n")
3763 return bgp_route_match_add(vty
, "ip route-source prefix-list",
3764 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3768 DEFUN (no_match_ip_route_source_prefix_list
,
3769 no_match_ip_route_source_prefix_list_cmd
,
3770 "no match ip route-source prefix-list [WORD]",
3774 "Match advertising source address of route\n"
3775 "Match entries of prefix-lists\n"
3776 "IP prefix-list name\n")
3779 if (argc
<= idx_word
)
3780 return bgp_route_match_delete(vty
,
3781 "ip route-source prefix-list",
3782 NULL
, RMAP_EVENT_PLIST_DELETED
);
3783 return bgp_route_match_delete(vty
, "ip route-source prefix-list",
3784 argv
[idx_word
]->arg
,
3785 RMAP_EVENT_PLIST_DELETED
);
3789 DEFUN (match_local_pref
,
3790 match_local_pref_cmd
,
3791 "match local-preference (0-4294967295)",
3793 "Match local-preference of route\n"
3797 return bgp_route_match_add(vty
, "local-preference",
3798 argv
[idx_number
]->arg
,
3799 RMAP_EVENT_MATCH_ADDED
);
3803 DEFUN (no_match_local_pref
,
3804 no_match_local_pref_cmd
,
3805 "no match local-preference [(0-4294967295)]",
3808 "Match local preference of route\n"
3809 "Local preference value\n")
3811 int idx_localpref
= 3;
3812 if (argc
<= idx_localpref
)
3813 return bgp_route_match_delete(vty
, "local-preference", NULL
,
3814 RMAP_EVENT_MATCH_DELETED
);
3815 return bgp_route_match_delete(vty
, "local-preference",
3816 argv
[idx_localpref
]->arg
,
3817 RMAP_EVENT_MATCH_DELETED
);
3821 DEFUN (match_community
,
3822 match_community_cmd
,
3823 "match community <(1-99)|(100-500)|WORD> [exact-match]",
3825 "Match BGP community list\n"
3826 "Community-list number (standard)\n"
3827 "Community-list number (expanded)\n"
3828 "Community-list name\n"
3829 "Do exact matching of communities\n")
3831 int idx_comm_list
= 2;
3836 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
3837 strlen(argv
[idx_comm_list
]->arg
)
3838 + strlen("exact-match") + 2);
3840 sprintf(argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3842 argstr
= argv
[idx_comm_list
]->arg
;
3844 ret
= bgp_route_match_add(vty
, "community", argstr
,
3845 RMAP_EVENT_CLIST_ADDED
);
3847 if (argstr
!= argv
[idx_comm_list
]->arg
)
3848 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3853 DEFUN (no_match_community
,
3854 no_match_community_cmd
,
3855 "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
3858 "Match BGP community list\n"
3859 "Community-list number (standard)\n"
3860 "Community-list number (expanded)\n"
3861 "Community-list name\n"
3862 "Do exact matching of communities\n")
3864 return bgp_route_match_delete(vty
, "community", NULL
,
3865 RMAP_EVENT_CLIST_DELETED
);
3868 DEFUN (match_lcommunity
,
3869 match_lcommunity_cmd
,
3870 "match large-community <(1-99)|(100-500)|WORD>",
3872 "Match BGP large community list\n"
3873 "Large Community-list number (standard)\n"
3874 "Large Community-list number (expanded)\n"
3875 "Large Community-list name\n")
3877 return bgp_route_match_add(vty
, "large-community", argv
[2]->arg
,
3878 RMAP_EVENT_LLIST_ADDED
);
3881 DEFUN (no_match_lcommunity
,
3882 no_match_lcommunity_cmd
,
3883 "no match large-community [<(1-99)|(100-500)|WORD>]",
3886 "Match BGP large community list\n"
3887 "Large Community-list number (standard)\n"
3888 "Large Community-list number (expanded)\n"
3889 "Large Community-list name\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 argstr
= XCALLOC(MTYPE_TMP
,
4297 strlen(str
) + strlen(" additive") + 1);
4298 strcpy(argstr
, str
);
4299 strcpy(argstr
+ strlen(str
), " additive");
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 str
= XCALLOC(MTYPE_TMP
,
4357 strlen(argv
[idx_comm_list
]->arg
) + strlen(" delete") + 1);
4358 strcpy(str
, argv
[idx_comm_list
]->arg
);
4359 strcpy(str
+ strlen(argv
[idx_comm_list
]->arg
), " delete");
4361 generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
), "comm-list",
4364 XFREE(MTYPE_TMP
, str
);
4368 DEFUN (no_set_community_delete
,
4369 no_set_community_delete_cmd
,
4370 "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
4373 "set BGP community list (for deletion)\n"
4374 "Community-list number (standard)\n"
4375 "Community-list number (expanded)\n"
4376 "Community-list name\n"
4377 "Delete matching communities\n")
4379 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4383 DEFUN (set_lcommunity
,
4385 "set large-community AA:BB:CC...",
4387 "BGP large community attribute\n"
4388 "Large Community number in aa:bb:cc format or additive\n")
4393 str
= argv_concat(argv
, argc
, 2);
4394 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4395 "large-community", str
);
4396 XFREE(MTYPE_TMP
, str
);
4401 DEFUN (set_lcommunity_none
,
4402 set_lcommunity_none_cmd
,
4403 "set large-community none",
4405 "BGP large community attribute\n"
4406 "No large community attribute\n")
4408 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4409 "large-community", "none");
4412 DEFUN (no_set_lcommunity
,
4413 no_set_lcommunity_cmd
,
4414 "no set large-community none",
4417 "BGP large community attribute\n"
4418 "No community attribute\n")
4420 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4421 "large-community", NULL
);
4424 DEFUN (no_set_lcommunity1
,
4425 no_set_lcommunity1_cmd
,
4426 "no set large-community AA:BB:CC...",
4429 "BGP large community attribute\n"
4430 "Large community in AA:BB:CC... format or additive\n")
4432 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4433 "large-community", NULL
);
4436 ALIAS (no_set_lcommunity1
,
4437 no_set_lcommunity1_short_cmd
,
4438 "no set large-community",
4441 "BGP large community attribute\n")
4443 DEFUN (set_lcommunity_delete
,
4444 set_lcommunity_delete_cmd
,
4445 "set large-comm-list <(1-99)|(100-500)|WORD> delete",
4447 "set BGP large community list (for deletion)\n"
4448 "Large Community-list number (standard)\n"
4449 "Large Communitly-list number (expanded)\n"
4450 "Large Community-list name\n"
4451 "Delete matching large communities\n")
4455 str
= XCALLOC(MTYPE_TMP
, strlen(argv
[2]->arg
) + strlen(" delete") + 1);
4456 strcpy(str
, argv
[2]->arg
);
4457 strcpy(str
+ strlen(argv
[2]->arg
), " delete");
4459 generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4460 "large-comm-list", str
);
4462 XFREE(MTYPE_TMP
, str
);
4466 DEFUN (no_set_lcommunity_delete
,
4467 no_set_lcommunity_delete_cmd
,
4468 "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
4471 "set BGP large community list (for deletion)\n"
4472 "Large Community-list number (standard)\n"
4473 "Large Communitly-list number (expanded)\n"
4474 "Large Community-list name\n"
4475 "Delete matching large communities\n")
4477 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4478 "large-comm-list", NULL
);
4481 ALIAS (no_set_lcommunity_delete
,
4482 no_set_lcommunity_delete_short_cmd
,
4483 "no set large-comm-list",
4486 "set BGP large community list (for deletion)\n")
4488 DEFUN (set_ecommunity_rt
,
4489 set_ecommunity_rt_cmd
,
4490 "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
4492 "BGP extended community attribute\n"
4493 "Route Target extended community\n"
4494 "VPN extended community\n")
4500 str
= argv_concat(argv
, argc
, idx_asn_nn
);
4501 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4502 "extcommunity rt", str
);
4503 XFREE(MTYPE_TMP
, str
);
4508 DEFUN (no_set_ecommunity_rt
,
4509 no_set_ecommunity_rt_cmd
,
4510 "no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
4513 "BGP extended community attribute\n"
4514 "Route Target extended community\n"
4515 "VPN extended community\n")
4517 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4518 "extcommunity rt", NULL
);
4521 ALIAS (no_set_ecommunity_rt
,
4522 no_set_ecommunity_rt_short_cmd
,
4523 "no set extcommunity rt",
4526 "BGP extended community attribute\n"
4527 "Route Target extended community\n")
4529 DEFUN (set_ecommunity_soo
,
4530 set_ecommunity_soo_cmd
,
4531 "set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
4533 "BGP extended community attribute\n"
4534 "Site-of-Origin extended community\n"
4535 "VPN extended community\n")
4541 str
= argv_concat(argv
, argc
, idx_asn_nn
);
4542 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4543 "extcommunity soo", str
);
4544 XFREE(MTYPE_TMP
, str
);
4549 DEFUN (no_set_ecommunity_soo
,
4550 no_set_ecommunity_soo_cmd
,
4551 "no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
4554 "BGP extended community attribute\n"
4555 "Site-of-Origin extended community\n"
4556 "VPN extended community\n")
4558 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4559 "extcommunity soo", NULL
);
4562 ALIAS (no_set_ecommunity_soo
,
4563 no_set_ecommunity_soo_short_cmd
,
4564 "no set extcommunity soo",
4567 "GP extended community attribute\n"
4568 "Site-of-Origin extended community\n")
4572 "set origin <egp|igp|incomplete>",
4577 "unknown heritage\n")
4580 if (strncmp(argv
[idx_origin
]->arg
, "igp", 2) == 0)
4581 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4583 if (strncmp(argv
[idx_origin
]->arg
, "egp", 1) == 0)
4584 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4586 if (strncmp(argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
4587 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4588 "origin", "incomplete");
4590 vty_out(vty
, "%% Invalid set origin type\n");
4591 return CMD_WARNING_CONFIG_FAILED
;
4595 DEFUN (no_set_origin
,
4597 "no set origin [<egp|igp|incomplete>]",
4603 "unknown heritage\n")
4605 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4610 DEFUN (set_atomic_aggregate
,
4611 set_atomic_aggregate_cmd
,
4612 "set atomic-aggregate",
4614 "BGP atomic aggregate attribute\n" )
4616 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4617 "atomic-aggregate", NULL
);
4620 DEFUN (no_set_atomic_aggregate
,
4621 no_set_atomic_aggregate_cmd
,
4622 "no set atomic-aggregate",
4625 "BGP atomic aggregate attribute\n" )
4627 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4628 "atomic-aggregate", NULL
);
4631 DEFUN (set_aggregator_as
,
4632 set_aggregator_as_cmd
,
4633 "set aggregator as (1-4294967295) A.B.C.D",
4635 "BGP aggregator attribute\n"
4636 "AS number of aggregator\n"
4638 "IP address of aggregator\n")
4643 struct in_addr address
;
4646 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &address
);
4648 vty_out(vty
, "Aggregator IP address is invalid\n");
4649 return CMD_WARNING_CONFIG_FAILED
;
4652 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
4653 strlen(argv
[idx_number
]->arg
)
4654 + strlen(argv
[idx_ipv4
]->arg
) + 2);
4656 sprintf(argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
4658 ret
= generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4659 "aggregator as", argstr
);
4661 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4667 DEFUN (no_set_aggregator_as
,
4668 no_set_aggregator_as_cmd
,
4669 "no set aggregator as [(1-4294967295) A.B.C.D]",
4672 "BGP aggregator attribute\n"
4673 "AS number of aggregator\n"
4675 "IP address of aggregator\n")
4680 struct in_addr address
;
4683 if (argc
<= idx_asn
)
4684 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4685 "aggregator as", NULL
);
4687 ret
= inet_aton(argv
[idx_ip
]->arg
, &address
);
4689 vty_out(vty
, "Aggregator IP address is invalid\n");
4690 return CMD_WARNING_CONFIG_FAILED
;
4693 argstr
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
4694 strlen(argv
[idx_asn
]->arg
) + strlen(argv
[idx_ip
]->arg
)
4697 sprintf(argstr
, "%s %s", argv
[idx_asn
]->arg
, argv
[idx_ip
]->arg
);
4699 ret
= generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4700 "aggregator as", argstr
);
4702 XFREE(MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4707 DEFUN (match_ipv6_next_hop
,
4708 match_ipv6_next_hop_cmd
,
4709 "match ipv6 next-hop X:X::X:X",
4712 "Match IPv6 next-hop address of route\n"
4713 "IPv6 address of next hop\n")
4716 return bgp_route_match_add(vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4717 RMAP_EVENT_MATCH_ADDED
);
4720 DEFUN (no_match_ipv6_next_hop
,
4721 no_match_ipv6_next_hop_cmd
,
4722 "no match ipv6 next-hop X:X::X:X",
4726 "Match IPv6 next-hop address of route\n"
4727 "IPv6 address of next hop\n")
4730 return bgp_route_match_delete(vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4731 RMAP_EVENT_MATCH_DELETED
);
4735 DEFUN (set_ipv6_nexthop_peer
,
4736 set_ipv6_nexthop_peer_cmd
,
4737 "set ipv6 next-hop peer-address",
4740 "Next hop address\n"
4741 "Use peer address (for BGP only)\n")
4743 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4744 "ipv6 next-hop peer-address", NULL
);
4747 DEFUN (no_set_ipv6_nexthop_peer
,
4748 no_set_ipv6_nexthop_peer_cmd
,
4749 "no set ipv6 next-hop peer-address",
4753 "IPv6 next-hop address\n"
4754 "Use peer address (for BGP only)\n")
4756 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4757 "ipv6 next-hop peer-address", NULL
);
4760 DEFUN (set_ipv6_nexthop_prefer_global
,
4761 set_ipv6_nexthop_prefer_global_cmd
,
4762 "set ipv6 next-hop prefer-global",
4765 "IPv6 next-hop address\n"
4766 "Prefer global over link-local if both exist\n")
4768 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4769 "ipv6 next-hop prefer-global", NULL
);
4773 DEFUN (no_set_ipv6_nexthop_prefer_global
,
4774 no_set_ipv6_nexthop_prefer_global_cmd
,
4775 "no set ipv6 next-hop prefer-global",
4779 "IPv6 next-hop address\n"
4780 "Prefer global over link-local if both exist\n")
4782 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4783 "ipv6 next-hop prefer-global", NULL
);
4786 DEFUN (set_ipv6_nexthop_global
,
4787 set_ipv6_nexthop_global_cmd
,
4788 "set ipv6 next-hop global X:X::X:X",
4791 "IPv6 next-hop address\n"
4792 "IPv6 global address\n"
4793 "IPv6 address of next hop\n")
4796 struct in6_addr addr
;
4799 ret
= inet_pton(AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
4801 vty_out(vty
, "%% Malformed nexthop address\n");
4802 return CMD_WARNING_CONFIG_FAILED
;
4804 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) || IN6_IS_ADDR_LOOPBACK(&addr
)
4805 || IN6_IS_ADDR_MULTICAST(&addr
) || IN6_IS_ADDR_LINKLOCAL(&addr
)) {
4806 vty_out(vty
, "%% Invalid global nexthop address\n");
4807 return CMD_WARNING_CONFIG_FAILED
;
4810 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4811 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4815 DEFUN (no_set_ipv6_nexthop_global
,
4816 no_set_ipv6_nexthop_global_cmd
,
4817 "no set ipv6 next-hop global X:X::X:X",
4821 "IPv6 next-hop address\n"
4822 "IPv6 global address\n"
4823 "IPv6 address of next hop\n")
4826 if (argc
<= idx_ipv6
)
4827 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4828 "ipv6 next-hop global", NULL
);
4829 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4830 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4833 #ifdef KEEP_OLD_VPN_COMMANDS
4834 DEFUN (set_vpn_nexthop
,
4835 set_vpn_nexthop_cmd
,
4836 "set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
4838 "VPNv4 information\n"
4839 "VPN next-hop address\n"
4840 "IP address of next hop\n"
4841 "VPNv6 information\n"
4842 "VPN next-hop address\n"
4843 "IPv6 address of next hop\n")
4849 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
4851 return generic_set_add(
4852 vty
, VTY_GET_CONTEXT(route_map_index
),
4853 "ipv4 vpn next-hop", argv
[idx_ip
]->arg
);
4855 return generic_set_add(
4856 vty
, VTY_GET_CONTEXT(route_map_index
),
4857 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4862 DEFUN (no_set_vpn_nexthop
,
4863 no_set_vpn_nexthop_cmd
,
4864 "no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
4867 "VPNv4 information\n"
4868 "VPN next-hop address\n"
4869 "IP address of next hop\n"
4870 "VPNv6 information\n"
4871 "VPN next-hop address\n"
4872 "IPv6 address of next hop\n")
4882 arg
= argv
[idx_ip
]->arg
;
4883 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
4885 return generic_set_delete(
4886 vty
, VTY_GET_CONTEXT(route_map_index
),
4887 "ipv4 vpn next-hop", arg
);
4889 return generic_set_delete(
4890 vty
, VTY_GET_CONTEXT(route_map_index
),
4891 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4895 #endif /* KEEP_OLD_VPN_COMMANDS */
4897 DEFUN (set_ipx_vpn_nexthop
,
4898 set_ipx_vpn_nexthop_cmd
,
4899 "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
4901 "IPv4 information\n"
4902 "IPv6 information\n"
4904 "VPN next-hop address\n"
4905 "IP address of next hop\n"
4906 "IPv6 address of next hop\n")
4912 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
4914 return generic_set_add(
4915 vty
, VTY_GET_CONTEXT(route_map_index
),
4916 "ipv4 vpn next-hop", argv
[idx_ip
]->arg
);
4918 return generic_set_add(
4919 vty
, VTY_GET_CONTEXT(route_map_index
),
4920 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4925 DEFUN (no_set_ipx_vpn_nexthop
,
4926 no_set_ipx_vpn_nexthop_cmd
,
4927 "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
4930 "IPv4 information\n"
4931 "IPv6 information\n"
4933 "VPN next-hop address\n"
4934 "IP address of next hop\n"
4935 "IPv6 address of next hop\n")
4945 arg
= argv
[idx_ip
]->arg
;
4946 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
4948 return generic_set_delete(
4949 vty
, VTY_GET_CONTEXT(route_map_index
),
4950 "ipv4 vpn next-hop", arg
);
4952 return generic_set_delete(
4953 vty
, VTY_GET_CONTEXT(route_map_index
),
4954 "ipv6 vpn next-hop", arg
);
4959 DEFUN (set_originator_id
,
4960 set_originator_id_cmd
,
4961 "set originator-id A.B.C.D",
4963 "BGP originator ID attribute\n"
4964 "IP address of originator\n")
4967 return generic_set_add(vty
, VTY_GET_CONTEXT(route_map_index
),
4968 "originator-id", argv
[idx_ipv4
]->arg
);
4972 DEFUN (no_set_originator_id
,
4973 no_set_originator_id_cmd
,
4974 "no set originator-id [A.B.C.D]",
4977 "BGP originator ID attribute\n"
4978 "IP address of originator\n")
4982 argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
4984 return generic_set_delete(vty
, VTY_GET_CONTEXT(route_map_index
),
4985 "originator-id", arg
);
4989 /* Initialization of route map. */
4990 void bgp_route_map_init(void)
4994 route_map_add_hook(bgp_route_map_add
);
4995 route_map_delete_hook(bgp_route_map_delete
);
4996 route_map_event_hook(bgp_route_map_event
);
4998 route_map_match_interface_hook(generic_match_add
);
4999 route_map_no_match_interface_hook(generic_match_delete
);
5001 route_map_match_ip_address_hook(generic_match_add
);
5002 route_map_no_match_ip_address_hook(generic_match_delete
);
5004 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
5005 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
5007 route_map_match_ip_next_hop_hook(generic_match_add
);
5008 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
5010 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
5011 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
5013 route_map_match_ip_next_hop_type_hook(generic_match_add
);
5014 route_map_no_match_ip_next_hop_type_hook(generic_match_delete
);
5016 route_map_match_ipv6_address_hook(generic_match_add
);
5017 route_map_no_match_ipv6_address_hook(generic_match_delete
);
5019 route_map_match_ipv6_address_prefix_list_hook(generic_match_add
);
5020 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete
);
5022 route_map_match_ipv6_next_hop_type_hook(generic_match_add
);
5023 route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete
);
5025 route_map_match_metric_hook(generic_match_add
);
5026 route_map_no_match_metric_hook(generic_match_delete
);
5028 route_map_match_tag_hook(generic_match_add
);
5029 route_map_no_match_tag_hook(generic_match_delete
);
5031 route_map_set_ip_nexthop_hook(generic_set_add
);
5032 route_map_no_set_ip_nexthop_hook(generic_set_delete
);
5034 route_map_set_ipv6_nexthop_local_hook(generic_set_add
);
5035 route_map_no_set_ipv6_nexthop_local_hook(generic_set_delete
);
5037 route_map_set_metric_hook(generic_set_add
);
5038 route_map_no_set_metric_hook(generic_set_delete
);
5040 route_map_set_tag_hook(generic_set_add
);
5041 route_map_no_set_tag_hook(generic_set_delete
);
5043 route_map_install_match(&route_match_peer_cmd
);
5044 route_map_install_match(&route_match_local_pref_cmd
);
5045 #if defined(HAVE_LUA)
5046 route_map_install_match(&route_match_command_cmd
);
5048 route_map_install_match(&route_match_ip_address_cmd
);
5049 route_map_install_match(&route_match_ip_next_hop_cmd
);
5050 route_map_install_match(&route_match_ip_route_source_cmd
);
5051 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
5052 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
5053 route_map_install_match(&route_match_ip_next_hop_type_cmd
);
5054 route_map_install_match(&route_match_ip_route_source_prefix_list_cmd
);
5055 route_map_install_match(&route_match_aspath_cmd
);
5056 route_map_install_match(&route_match_community_cmd
);
5057 route_map_install_match(&route_match_lcommunity_cmd
);
5058 route_map_install_match(&route_match_ecommunity_cmd
);
5059 route_map_install_match(&route_match_local_pref_cmd
);
5060 route_map_install_match(&route_match_metric_cmd
);
5061 route_map_install_match(&route_match_origin_cmd
);
5062 route_map_install_match(&route_match_probability_cmd
);
5063 route_map_install_match(&route_match_interface_cmd
);
5064 route_map_install_match(&route_match_tag_cmd
);
5065 route_map_install_match(&route_match_mac_address_cmd
);
5066 route_map_install_match(&route_match_evpn_vni_cmd
);
5067 route_map_install_match(&route_match_evpn_route_type_cmd
);
5068 route_map_install_match(&route_match_evpn_default_route_cmd
);
5069 route_map_install_match(&route_match_vrl_source_vrf_cmd
);
5071 route_map_install_set(&route_set_ip_nexthop_cmd
);
5072 route_map_install_set(&route_set_local_pref_cmd
);
5073 route_map_install_set(&route_set_weight_cmd
);
5074 route_map_install_set(&route_set_label_index_cmd
);
5075 route_map_install_set(&route_set_metric_cmd
);
5076 route_map_install_set(&route_set_aspath_prepend_cmd
);
5077 route_map_install_set(&route_set_aspath_exclude_cmd
);
5078 route_map_install_set(&route_set_origin_cmd
);
5079 route_map_install_set(&route_set_atomic_aggregate_cmd
);
5080 route_map_install_set(&route_set_aggregator_as_cmd
);
5081 route_map_install_set(&route_set_community_cmd
);
5082 route_map_install_set(&route_set_community_delete_cmd
);
5083 route_map_install_set(&route_set_lcommunity_cmd
);
5084 route_map_install_set(&route_set_lcommunity_delete_cmd
);
5085 route_map_install_set(&route_set_vpnv4_nexthop_cmd
);
5086 route_map_install_set(&route_set_vpnv6_nexthop_cmd
);
5087 route_map_install_set(&route_set_originator_id_cmd
);
5088 route_map_install_set(&route_set_ecommunity_rt_cmd
);
5089 route_map_install_set(&route_set_ecommunity_soo_cmd
);
5090 route_map_install_set(&route_set_tag_cmd
);
5091 route_map_install_set(&route_set_label_index_cmd
);
5093 install_element(RMAP_NODE
, &match_peer_cmd
);
5094 install_element(RMAP_NODE
, &match_peer_local_cmd
);
5095 install_element(RMAP_NODE
, &no_match_peer_cmd
);
5096 install_element(RMAP_NODE
, &match_ip_route_source_cmd
);
5097 install_element(RMAP_NODE
, &no_match_ip_route_source_cmd
);
5098 install_element(RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
5099 install_element(RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
5100 install_element(RMAP_NODE
, &match_mac_address_cmd
);
5101 install_element(RMAP_NODE
, &no_match_mac_address_cmd
);
5102 install_element(RMAP_NODE
, &match_evpn_vni_cmd
);
5103 install_element(RMAP_NODE
, &no_match_evpn_vni_cmd
);
5104 install_element(RMAP_NODE
, &match_evpn_route_type_cmd
);
5105 install_element(RMAP_NODE
, &no_match_evpn_route_type_cmd
);
5106 install_element(RMAP_NODE
, &match_evpn_default_route_cmd
);
5107 install_element(RMAP_NODE
, &no_match_evpn_default_route_cmd
);
5108 install_element(RMAP_NODE
, &match_vrl_source_vrf_cmd
);
5109 install_element(RMAP_NODE
, &no_match_vrl_source_vrf_cmd
);
5111 install_element(RMAP_NODE
, &match_aspath_cmd
);
5112 install_element(RMAP_NODE
, &no_match_aspath_cmd
);
5113 install_element(RMAP_NODE
, &match_local_pref_cmd
);
5114 install_element(RMAP_NODE
, &no_match_local_pref_cmd
);
5115 install_element(RMAP_NODE
, &match_community_cmd
);
5116 install_element(RMAP_NODE
, &no_match_community_cmd
);
5117 install_element(RMAP_NODE
, &match_lcommunity_cmd
);
5118 install_element(RMAP_NODE
, &no_match_lcommunity_cmd
);
5119 install_element(RMAP_NODE
, &match_ecommunity_cmd
);
5120 install_element(RMAP_NODE
, &no_match_ecommunity_cmd
);
5121 install_element(RMAP_NODE
, &match_origin_cmd
);
5122 install_element(RMAP_NODE
, &no_match_origin_cmd
);
5123 install_element(RMAP_NODE
, &match_probability_cmd
);
5124 install_element(RMAP_NODE
, &no_match_probability_cmd
);
5126 install_element(RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
5127 install_element(RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
5128 install_element(RMAP_NODE
, &set_local_pref_cmd
);
5129 install_element(RMAP_NODE
, &no_set_local_pref_cmd
);
5130 install_element(RMAP_NODE
, &set_weight_cmd
);
5131 install_element(RMAP_NODE
, &set_label_index_cmd
);
5132 install_element(RMAP_NODE
, &no_set_weight_cmd
);
5133 install_element(RMAP_NODE
, &no_set_label_index_cmd
);
5134 install_element(RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
5135 install_element(RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
5136 install_element(RMAP_NODE
, &set_aspath_exclude_cmd
);
5137 install_element(RMAP_NODE
, &no_set_aspath_prepend_cmd
);
5138 install_element(RMAP_NODE
, &no_set_aspath_exclude_cmd
);
5139 install_element(RMAP_NODE
, &no_set_aspath_exclude_all_cmd
);
5140 install_element(RMAP_NODE
, &set_origin_cmd
);
5141 install_element(RMAP_NODE
, &no_set_origin_cmd
);
5142 install_element(RMAP_NODE
, &set_atomic_aggregate_cmd
);
5143 install_element(RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
5144 install_element(RMAP_NODE
, &set_aggregator_as_cmd
);
5145 install_element(RMAP_NODE
, &no_set_aggregator_as_cmd
);
5146 install_element(RMAP_NODE
, &set_community_cmd
);
5147 install_element(RMAP_NODE
, &set_community_none_cmd
);
5148 install_element(RMAP_NODE
, &no_set_community_cmd
);
5149 install_element(RMAP_NODE
, &no_set_community_short_cmd
);
5150 install_element(RMAP_NODE
, &set_community_delete_cmd
);
5151 install_element(RMAP_NODE
, &no_set_community_delete_cmd
);
5152 install_element(RMAP_NODE
, &set_lcommunity_cmd
);
5153 install_element(RMAP_NODE
, &set_lcommunity_none_cmd
);
5154 install_element(RMAP_NODE
, &no_set_lcommunity_cmd
);
5155 install_element(RMAP_NODE
, &no_set_lcommunity1_cmd
);
5156 install_element(RMAP_NODE
, &no_set_lcommunity1_short_cmd
);
5157 install_element(RMAP_NODE
, &set_lcommunity_delete_cmd
);
5158 install_element(RMAP_NODE
, &no_set_lcommunity_delete_cmd
);
5159 install_element(RMAP_NODE
, &no_set_lcommunity_delete_short_cmd
);
5160 install_element(RMAP_NODE
, &set_ecommunity_rt_cmd
);
5161 install_element(RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
5162 install_element(RMAP_NODE
, &no_set_ecommunity_rt_short_cmd
);
5163 install_element(RMAP_NODE
, &set_ecommunity_soo_cmd
);
5164 install_element(RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
5165 install_element(RMAP_NODE
, &no_set_ecommunity_soo_short_cmd
);
5166 #ifdef KEEP_OLD_VPN_COMMANDS
5167 install_element(RMAP_NODE
, &set_vpn_nexthop_cmd
);
5168 install_element(RMAP_NODE
, &no_set_vpn_nexthop_cmd
);
5169 #endif /* KEEP_OLD_VPN_COMMANDS */
5170 install_element(RMAP_NODE
, &set_ipx_vpn_nexthop_cmd
);
5171 install_element(RMAP_NODE
, &no_set_ipx_vpn_nexthop_cmd
);
5172 install_element(RMAP_NODE
, &set_originator_id_cmd
);
5173 install_element(RMAP_NODE
, &no_set_originator_id_cmd
);
5175 route_map_install_match(&route_match_ipv6_address_cmd
);
5176 route_map_install_match(&route_match_ipv6_next_hop_cmd
);
5177 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd
);
5178 route_map_install_match(&route_match_ipv6_next_hop_type_cmd
);
5179 route_map_install_set(&route_set_ipv6_nexthop_global_cmd
);
5180 route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd
);
5181 route_map_install_set(&route_set_ipv6_nexthop_local_cmd
);
5182 route_map_install_set(&route_set_ipv6_nexthop_peer_cmd
);
5184 install_element(RMAP_NODE
, &match_ipv6_next_hop_cmd
);
5185 install_element(RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
5186 install_element(RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
5187 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
5188 install_element(RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
5189 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
5190 install_element(RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
5191 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
5192 #if defined(HAVE_LUA)
5193 install_element(RMAP_NODE
, &match_command_cmd
);
5194 install_element(RMAP_NODE
, &no_match_command_cmd
);
5198 void bgp_route_map_terminate(void)
5200 /* ToDo: Cleanup all the used memory */