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 #include "frrscript.h"
33 #ifdef HAVE_LIBPCREPOSIX
34 #include <pcreposix.h>
37 #endif /* HAVE_LIBPCREPOSIX */
39 #include "sockunion.h"
44 #include "lib/northbound_cli.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_aspath.h"
50 #include "bgpd/bgp_packet.h"
51 #include "bgpd/bgp_route.h"
52 #include "bgpd/bgp_zebra.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_clist.h"
57 #include "bgpd/bgp_filter.h"
58 #include "bgpd/bgp_mplsvpn.h"
59 #include "bgpd/bgp_ecommunity.h"
60 #include "bgpd/bgp_lcommunity.h"
61 #include "bgpd/bgp_vty.h"
62 #include "bgpd/bgp_debug.h"
63 #include "bgpd/bgp_evpn.h"
64 #include "bgpd/bgp_evpn_private.h"
65 #include "bgpd/bgp_evpn_vty.h"
66 #include "bgpd/bgp_mplsvpn.h"
67 #include "bgpd/bgp_pbr.h"
68 #include "bgpd/bgp_flowspec_util.h"
69 #include "bgpd/bgp_encap_types.h"
70 #include "bgpd/bgp_mpath.h"
71 #include "bgpd/bgp_script.h"
74 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
77 #ifndef VTYSH_EXTRACT_PL
78 #include "bgpd/bgp_routemap_clippy.c"
81 /* Memo of route-map commands.
90 ip route-source : Done
94 ipv6 route-source: (This will not be implemented by bgpd)
95 ipv6 prefix-list : Done
96 length : (This will not be implemented by bgpd)
98 route-type : (This will not be implemented by bgpd)
100 local-preference : Done
102 set as-path prepend : Done
103 as-path tag : Not yet
104 automatic-tag : (This will not be implemented by bgpd)
106 large-community : Done
107 large-comm-list : Done
110 default : (This will not be implemented by bgpd)
111 interface : (This will not be implemented by bgpd)
112 ip default : (This will not be implemented by bgpd)
114 ip precedence : (This will not be implemented by bgpd)
115 ip tos : (This will not be implemented by bgpd)
116 level : (This will not be implemented by bgpd)
117 local-preference : Done
119 metric-type : Not yet
127 set ipv6 next-hop global: Done
128 set ipv6 next-hop prefer-global: Done
129 set ipv6 next-hop local : Done
130 set as-path exclude : Done
134 /* generic value manipulation to be shared in multiple rules */
136 #define RMAP_VALUE_SET 0
137 #define RMAP_VALUE_ADD 1
138 #define RMAP_VALUE_SUB 2
146 static int route_value_match(struct rmap_value
*rv
, uint32_t value
)
148 if (rv
->variable
== 0 && value
== rv
->value
)
154 static uint32_t route_value_adjust(struct rmap_value
*rv
, uint32_t current
,
159 switch (rv
->variable
) {
168 switch (rv
->action
) {
170 if (current
> UINT32_MAX
- value
)
172 return current
+ value
;
174 if (current
<= value
)
176 return current
- value
;
182 static void *route_value_compile(const char *arg
)
184 uint8_t action
= RMAP_VALUE_SET
, var
= 0;
185 unsigned long larg
= 0;
187 struct rmap_value
*rv
;
190 action
= RMAP_VALUE_ADD
;
192 } else if (arg
[0] == '-') {
193 action
= RMAP_VALUE_SUB
;
197 if (all_digit(arg
)) {
199 larg
= strtoul(arg
, &endptr
, 10);
200 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
203 if (strcmp(arg
, "rtt") == 0)
209 rv
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_value
));
217 static void route_value_free(void *rule
)
219 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
222 /* generic as path object to be shared in multiple rules */
224 static void *route_aspath_compile(const char *arg
)
226 struct aspath
*aspath
;
228 aspath
= aspath_str2aspath(arg
);
234 static void route_aspath_free(void *rule
)
236 struct aspath
*aspath
= rule
;
240 struct bgp_match_peer_compiled
{
245 /* 'match peer (A.B.C.D|X:X::X:X|WORD)' */
247 /* Compares the peer specified in the 'match peer' clause with the peer
248 received in bgp_path_info->peer. If it is the same, or if the peer structure
249 received is a peer_group containing it, returns RMAP_MATCH. */
250 static enum route_map_cmd_result_t
251 route_match_peer(void *rule
, const struct prefix
*prefix
, void *object
)
253 struct bgp_match_peer_compiled
*pc
;
255 union sockunion su_def
= {
256 .sin
= {.sin_family
= AF_INET
, .sin_addr
.s_addr
= INADDR_ANY
}};
257 struct peer_group
*group
;
259 struct listnode
*node
, *nnode
;
263 peer
= ((struct bgp_path_info
*)object
)->peer
;
269 if (strcmp(peer
->conf_if
, pc
->interface
) == 0)
275 /* If su='0.0.0.0' (command 'match peer local'), and it's a
277 REDISTRIBUTE, AGGREGATE-ADDRESS or DEFAULT_GENERATED route
280 if (sockunion_same(su
, &su_def
)) {
282 if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_NETWORK
)
283 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
)
284 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_AGGREGATE
)
285 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_DEFAULT
))
292 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
293 if (sockunion_same(su
, &peer
->su
))
299 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
300 if (sockunion_same(su
, &peer
->su
))
309 static void *route_match_peer_compile(const char *arg
)
311 struct bgp_match_peer_compiled
*pc
;
314 pc
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
,
315 sizeof(struct bgp_match_peer_compiled
));
317 ret
= str2sockunion(strcmp(arg
, "local") ? arg
: "0.0.0.0", &pc
->su
);
319 pc
->interface
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
326 /* Free route map's compiled `ip address' value. */
327 static void route_match_peer_free(void *rule
)
329 struct bgp_match_peer_compiled
*pc
= rule
;
331 XFREE(MTYPE_ROUTE_MAP_COMPILED
, pc
->interface
);
333 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
336 /* Route map commands for ip address matching. */
337 static const struct route_map_rule_cmd route_match_peer_cmd
= {
340 route_match_peer_compile
,
341 route_match_peer_free
344 #ifdef HAVE_SCRIPTING
346 enum frrlua_rm_status
{
348 * Script function run failure. This will translate into a deny
352 * No Match was found for the route map function
356 * Match was found but no changes were made to the incoming data.
360 * Match was found and data was modified, so figure out what changed
362 LUA_RM_MATCH_AND_CHANGE
,
365 static enum route_map_cmd_result_t
366 route_match_script(void *rule
, const struct prefix
*prefix
, void *object
)
368 const char *scriptname
= rule
;
369 const char *routematch_function
= "route_match";
370 struct bgp_path_info
*path
= (struct bgp_path_info
*)object
;
372 struct frrscript
*fs
= frrscript_new(scriptname
);
374 if (frrscript_load(fs
, routematch_function
, NULL
)) {
376 "Issue loading script or function; defaulting to no match");
380 struct attr newattr
= *path
->attr
;
382 int result
= frrscript_call(
383 fs
, routematch_function
, ("prefix", prefix
),
384 ("attributes", &newattr
), ("peer", path
->peer
),
385 ("RM_FAILURE", LUA_RM_FAILURE
), ("RM_NOMATCH", LUA_RM_NOMATCH
),
386 ("RM_MATCH", LUA_RM_MATCH
),
387 ("RM_MATCH_AND_CHANGE", LUA_RM_MATCH_AND_CHANGE
));
390 zlog_err("Issue running script rule; defaulting to no match");
394 long long *action
= frrscript_get_result(fs
, routematch_function
,
395 "action", lua_tointegerp
);
397 int status
= RMAP_NOMATCH
;
402 "Executing route-map match script '%s' failed; defaulting to no match",
404 status
= RMAP_NOMATCH
;
407 status
= RMAP_NOMATCH
;
409 case LUA_RM_MATCH_AND_CHANGE
:
411 zlog_debug("Updating attribute based on script's values");
413 uint32_t locpref
= 0;
415 path
->attr
->med
= newattr
.med
;
417 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
418 locpref
= path
->attr
->local_pref
;
419 if (locpref
!= newattr
.local_pref
) {
420 SET_FLAG(path
->attr
->flag
,
421 ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
));
422 path
->attr
->local_pref
= newattr
.local_pref
;
430 XFREE(MTYPE_SCRIPT_RES
, action
);
432 frrscript_delete(fs
);
437 static void *route_match_script_compile(const char *arg
)
441 scriptname
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
446 static void route_match_script_free(void *rule
)
448 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
451 static const struct route_map_rule_cmd route_match_script_cmd
= {
454 route_match_script_compile
,
455 route_match_script_free
458 #endif /* HAVE_SCRIPTING */
460 /* `match ip address IP_ACCESS_LIST' */
462 /* Match function should return 1 if match is success else return
464 static enum route_map_cmd_result_t
465 route_match_ip_address(void *rule
, const struct prefix
*prefix
, void *object
)
467 struct access_list
*alist
;
469 if (prefix
->family
== AF_INET
) {
470 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
474 return (access_list_apply(alist
, prefix
) == FILTER_DENY
481 /* Route map `ip address' match statement. `arg' should be
483 static void *route_match_ip_address_compile(const char *arg
)
485 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
488 /* Free route map's compiled `ip address' value. */
489 static void route_match_ip_address_free(void *rule
)
491 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
494 /* Route map commands for ip address matching. */
495 static const struct route_map_rule_cmd route_match_ip_address_cmd
= {
497 route_match_ip_address
,
498 route_match_ip_address_compile
,
499 route_match_ip_address_free
502 /* `match ip next-hop IP_ADDRESS' */
504 /* Match function return 1 if match is success else return zero. */
505 static enum route_map_cmd_result_t
506 route_match_ip_next_hop(void *rule
, const struct prefix
*prefix
, void *object
)
508 struct access_list
*alist
;
509 struct bgp_path_info
*path
;
510 struct prefix_ipv4 p
;
512 if (prefix
->family
== AF_INET
) {
515 p
.prefix
= path
->attr
->nexthop
;
516 p
.prefixlen
= IPV4_MAX_BITLEN
;
518 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
522 return (access_list_apply(alist
, &p
) == FILTER_DENY
529 /* Route map `ip next-hop' match statement. `arg' is
531 static void *route_match_ip_next_hop_compile(const char *arg
)
533 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
536 /* Free route map's compiled `ip address' value. */
537 static void route_match_ip_next_hop_free(void *rule
)
539 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
542 /* Route map commands for ip next-hop matching. */
543 static const struct route_map_rule_cmd route_match_ip_next_hop_cmd
= {
545 route_match_ip_next_hop
,
546 route_match_ip_next_hop_compile
,
547 route_match_ip_next_hop_free
550 /* `match ip route-source ACCESS-LIST' */
552 /* Match function return 1 if match is success else return zero. */
553 static enum route_map_cmd_result_t
554 route_match_ip_route_source(void *rule
, const struct prefix
*pfx
, void *object
)
556 struct access_list
*alist
;
557 struct bgp_path_info
*path
;
559 struct prefix_ipv4 p
;
561 if (pfx
->family
== AF_INET
) {
565 if (!peer
|| sockunion_family(&peer
->su
) != AF_INET
)
569 p
.prefix
= peer
->su
.sin
.sin_addr
;
570 p
.prefixlen
= IPV4_MAX_BITLEN
;
572 alist
= access_list_lookup(AFI_IP
, (char *)rule
);
576 return (access_list_apply(alist
, &p
) == FILTER_DENY
583 /* Route map `ip route-source' match statement. `arg' is
585 static void *route_match_ip_route_source_compile(const char *arg
)
587 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
590 /* Free route map's compiled `ip address' value. */
591 static void route_match_ip_route_source_free(void *rule
)
593 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
596 /* Route map commands for ip route-source matching. */
597 static const struct route_map_rule_cmd route_match_ip_route_source_cmd
= {
599 route_match_ip_route_source
,
600 route_match_ip_route_source_compile
,
601 route_match_ip_route_source_free
604 static enum route_map_cmd_result_t
605 route_match_prefix_list_flowspec(afi_t afi
, struct prefix_list
*plist
,
606 const struct prefix
*p
)
609 struct bgp_pbr_entry_main api
;
611 memset(&api
, 0, sizeof(api
));
613 if (family2afi(p
->u
.prefix_flowspec
.family
) != afi
)
616 /* extract match from flowspec entries */
617 ret
= bgp_flowspec_match_rules_fill(
618 (uint8_t *)p
->u
.prefix_flowspec
.ptr
,
619 p
->u
.prefix_flowspec
.prefixlen
, &api
,
623 if (api
.match_bitmask
& PREFIX_DST_PRESENT
||
624 api
.match_bitmask_iprule
& PREFIX_DST_PRESENT
) {
625 if (family2afi((&api
.dst_prefix
)->family
) != afi
)
627 return prefix_list_apply(plist
, &api
.dst_prefix
) == PREFIX_DENY
630 } else if (api
.match_bitmask
& PREFIX_SRC_PRESENT
||
631 api
.match_bitmask_iprule
& PREFIX_SRC_PRESENT
) {
632 if (family2afi((&api
.src_prefix
)->family
) != afi
)
634 return (prefix_list_apply(plist
, &api
.src_prefix
) == PREFIX_DENY
641 static enum route_map_cmd_result_t
642 route_match_address_prefix_list(void *rule
, afi_t afi
,
643 const struct prefix
*prefix
, void *object
)
645 struct prefix_list
*plist
;
647 plist
= prefix_list_lookup(afi
, (char *)rule
);
651 if (prefix
->family
== AF_FLOWSPEC
)
652 return route_match_prefix_list_flowspec(afi
, plist
,
654 return (prefix_list_apply(plist
, prefix
) == PREFIX_DENY
? RMAP_NOMATCH
658 static enum route_map_cmd_result_t
659 route_match_ip_address_prefix_list(void *rule
, const struct prefix
*prefix
,
662 return route_match_address_prefix_list(rule
, AFI_IP
, prefix
, object
);
665 static void *route_match_ip_address_prefix_list_compile(const char *arg
)
667 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
670 static void route_match_ip_address_prefix_list_free(void *rule
)
672 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
675 static const struct route_map_rule_cmd
676 route_match_ip_address_prefix_list_cmd
= {
677 "ip address prefix-list",
678 route_match_ip_address_prefix_list
,
679 route_match_ip_address_prefix_list_compile
,
680 route_match_ip_address_prefix_list_free
683 /* `match ip next-hop prefix-list PREFIX_LIST' */
685 static enum route_map_cmd_result_t
686 route_match_ip_next_hop_prefix_list(void *rule
, const struct prefix
*prefix
,
689 struct prefix_list
*plist
;
690 struct bgp_path_info
*path
;
691 struct prefix_ipv4 p
;
693 if (prefix
->family
== AF_INET
) {
696 p
.prefix
= path
->attr
->nexthop
;
697 p
.prefixlen
= IPV4_MAX_BITLEN
;
699 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
703 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
710 static void *route_match_ip_next_hop_prefix_list_compile(const char *arg
)
712 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
715 static void route_match_ip_next_hop_prefix_list_free(void *rule
)
717 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
720 static const struct route_map_rule_cmd
721 route_match_ip_next_hop_prefix_list_cmd
= {
722 "ip next-hop prefix-list",
723 route_match_ip_next_hop_prefix_list
,
724 route_match_ip_next_hop_prefix_list_compile
,
725 route_match_ip_next_hop_prefix_list_free
728 /* `match ip next-hop type <blackhole>' */
730 static enum route_map_cmd_result_t
731 route_match_ip_next_hop_type(void *rule
, const struct prefix
*prefix
,
734 struct bgp_path_info
*path
;
736 if (prefix
->family
== AF_INET
) {
737 path
= (struct bgp_path_info
*)object
;
741 /* If nexthop interface's index can't be resolved and nexthop is
742 set to any address then mark it as type `blackhole`.
743 This logic works for matching kernel/static routes like:
744 `ip route add blackhole 10.0.0.1`. */
745 if (path
->attr
->nexthop
.s_addr
== INADDR_ANY
746 && !path
->attr
->nh_ifindex
)
752 static void *route_match_ip_next_hop_type_compile(const char *arg
)
754 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
757 static void route_match_ip_next_hop_type_free(void *rule
)
759 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
762 static const struct route_map_rule_cmd
763 route_match_ip_next_hop_type_cmd
= {
765 route_match_ip_next_hop_type
,
766 route_match_ip_next_hop_type_compile
,
767 route_match_ip_next_hop_type_free
770 /* `match ip route-source prefix-list PREFIX_LIST' */
772 static enum route_map_cmd_result_t
773 route_match_ip_route_source_prefix_list(void *rule
, const struct prefix
*prefix
,
776 struct prefix_list
*plist
;
777 struct bgp_path_info
*path
;
779 struct prefix_ipv4 p
;
781 if (prefix
->family
== AF_INET
) {
785 if (!peer
|| sockunion_family(&peer
->su
) != AF_INET
)
789 p
.prefix
= peer
->su
.sin
.sin_addr
;
790 p
.prefixlen
= IPV4_MAX_BITLEN
;
792 plist
= prefix_list_lookup(AFI_IP
, (char *)rule
);
796 return (prefix_list_apply(plist
, &p
) == PREFIX_DENY
803 static void *route_match_ip_route_source_prefix_list_compile(const char *arg
)
805 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
808 static void route_match_ip_route_source_prefix_list_free(void *rule
)
810 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
813 static const struct route_map_rule_cmd
814 route_match_ip_route_source_prefix_list_cmd
= {
815 "ip route-source prefix-list",
816 route_match_ip_route_source_prefix_list
,
817 route_match_ip_route_source_prefix_list_compile
,
818 route_match_ip_route_source_prefix_list_free
821 /* `match evpn default-route' */
823 /* Match function should return 1 if match is success else 0 */
824 static enum route_map_cmd_result_t
825 route_match_evpn_default_route(void *rule
, const struct prefix
*p
, void *object
)
827 if (is_evpn_prefix_default(p
))
833 /* Route map commands for default-route matching. */
834 static const struct route_map_rule_cmd
835 route_match_evpn_default_route_cmd
= {
836 "evpn default-route",
837 route_match_evpn_default_route
,
842 /* `match mac address MAC_ACCESS_LIST' */
844 /* Match function should return 1 if match is success else return
846 static enum route_map_cmd_result_t
847 route_match_mac_address(void *rule
, const struct prefix
*prefix
, void *object
)
849 struct access_list
*alist
;
852 alist
= access_list_lookup(AFI_L2VPN
, (char *)rule
);
856 if (prefix
->u
.prefix_evpn
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
859 p
.family
= AF_ETHERNET
;
860 p
.prefixlen
= ETH_ALEN
* 8;
861 p
.u
.prefix_eth
= prefix
->u
.prefix_evpn
.macip_addr
.mac
;
863 return (access_list_apply(alist
, &p
) == FILTER_DENY
? RMAP_NOMATCH
867 /* Route map `mac address' match statement. `arg' should be
869 static void *route_match_mac_address_compile(const char *arg
)
871 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
874 /* Free route map's compiled `ip address' value. */
875 static void route_match_mac_address_free(void *rule
)
877 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
880 /* Route map commands for mac address matching. */
881 static const struct route_map_rule_cmd route_match_mac_address_cmd
= {
883 route_match_mac_address
,
884 route_match_mac_address_compile
,
885 route_match_mac_address_free
889 * Match function returns:
890 * ...RMAP_MATCH if match is found.
891 * ...RMAP_NOMATCH if match is not found.
892 * ...RMAP_NOOP to ignore this match check.
894 static enum route_map_cmd_result_t
895 route_match_vni(void *rule
, const struct prefix
*prefix
, void *object
)
898 unsigned int label_cnt
= 0;
899 struct bgp_path_info
*path
= NULL
;
900 struct prefix_evpn
*evp
= (struct prefix_evpn
*) prefix
;
902 vni
= *((vni_t
*)rule
);
903 path
= (struct bgp_path_info
*)object
;
906 * This rmap filter is valid for vxlan tunnel type only.
907 * For any other tunnel type, return noop to ignore
910 if (path
->attr
->encap_tunneltype
!= BGP_ENCAP_TYPE_VXLAN
)
914 * Apply filter to type 1, 2, 5 routes only.
915 * Other route types do not have vni label.
918 && (evp
->prefix
.route_type
!= BGP_EVPN_AD_ROUTE
919 && evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
920 && evp
->prefix
.route_type
!= BGP_EVPN_IP_PREFIX_ROUTE
))
923 if (path
->extra
== NULL
)
927 label_cnt
< BGP_MAX_LABELS
&& label_cnt
< path
->extra
->num_labels
;
929 if (vni
== label2vni(&path
->extra
->label
[label_cnt
]))
936 /* Route map `vni' match statement. */
937 static void *route_match_vni_compile(const char *arg
)
942 vni
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(vni_t
));
944 *vni
= strtoul(arg
, &end
, 10);
946 XFREE(MTYPE_ROUTE_MAP_COMPILED
, vni
);
953 /* Free route map's compiled `vni' value. */
954 static void route_match_vni_free(void *rule
)
956 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
959 /* Route map commands for vni matching. */
960 static const struct route_map_rule_cmd route_match_evpn_vni_cmd
= {
963 route_match_vni_compile
,
967 /* `match evpn route-type' */
969 /* Match function should return 1 if match is success else return
971 static enum route_map_cmd_result_t
972 route_match_evpn_route_type(void *rule
, const struct prefix
*pfx
, void *object
)
974 uint8_t route_type
= 0;
976 route_type
= *((uint8_t *)rule
);
978 if (route_type
== pfx
->u
.prefix_evpn
.route_type
)
984 /* Route map `route-type' match statement. */
985 static void *route_match_evpn_route_type_compile(const char *arg
)
987 uint8_t *route_type
= NULL
;
989 route_type
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
991 if (strncmp(arg
, "ma", 2) == 0)
992 *route_type
= BGP_EVPN_MAC_IP_ROUTE
;
993 else if (strncmp(arg
, "mu", 2) == 0)
994 *route_type
= BGP_EVPN_IMET_ROUTE
;
996 *route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
1001 /* Free route map's compiled `route-type' value. */
1002 static void route_match_evpn_route_type_free(void *rule
)
1004 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1007 /* Route map commands for evpn route-type matching. */
1008 static const struct route_map_rule_cmd route_match_evpn_route_type_cmd
= {
1010 route_match_evpn_route_type
,
1011 route_match_evpn_route_type_compile
,
1012 route_match_evpn_route_type_free
1017 /* Match function should return 1 if match is success else return zero. */
1018 static enum route_map_cmd_result_t
1019 route_match_rd(void *rule
, const struct prefix
*prefix
, void *object
)
1021 struct prefix_rd
*prd_rule
= NULL
;
1022 const struct prefix_rd
*prd_route
= NULL
;
1023 struct bgp_path_info
*path
= NULL
;
1025 if (prefix
->family
!= AF_EVPN
)
1026 return RMAP_NOMATCH
;
1028 prd_rule
= (struct prefix_rd
*)rule
;
1029 path
= (struct bgp_path_info
*)object
;
1031 if (path
->net
== NULL
|| path
->net
->pdest
== NULL
)
1032 return RMAP_NOMATCH
;
1034 prd_route
= (struct prefix_rd
*)bgp_dest_get_prefix(path
->net
->pdest
);
1035 if (memcmp(prd_route
->val
, prd_rule
->val
, ECOMMUNITY_SIZE
) == 0)
1038 return RMAP_NOMATCH
;
1041 /* Route map `rd' match statement. */
1042 static void *route_match_rd_compile(const char *arg
)
1044 struct prefix_rd
*prd
;
1047 prd
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct prefix_rd
));
1049 ret
= str2prefix_rd(arg
, prd
);
1051 XFREE(MTYPE_ROUTE_MAP_COMPILED
, prd
);
1058 /* Free route map's compiled `rd' value. */
1059 static void route_match_rd_free(void *rule
)
1061 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1064 /* Route map commands for rd matching. */
1065 static const struct route_map_rule_cmd route_match_evpn_rd_cmd
= {
1068 route_match_rd_compile
,
1072 static enum route_map_cmd_result_t
1073 route_set_evpn_gateway_ip(void *rule
, const struct prefix
*prefix
, void *object
)
1075 struct ipaddr
*gw_ip
= rule
;
1076 struct bgp_path_info
*path
;
1077 struct prefix_evpn
*evp
;
1079 if (prefix
->family
!= AF_EVPN
)
1082 evp
= (struct prefix_evpn
*)prefix
;
1083 if (evp
->prefix
.route_type
!= BGP_EVPN_IP_PREFIX_ROUTE
)
1086 if ((is_evpn_prefix_ipaddr_v4(evp
) && IPADDRSZ(gw_ip
) != 4)
1087 || (is_evpn_prefix_ipaddr_v6(evp
) && IPADDRSZ(gw_ip
) != 16))
1092 /* Set gateway-ip value. */
1093 path
->attr
->evpn_overlay
.type
= OVERLAY_INDEX_GATEWAY_IP
;
1094 memcpy(&path
->attr
->evpn_overlay
.gw_ip
, &gw_ip
->ip
.addr
,
1101 * Route map `evpn gateway-ip' compile function.
1102 * Given string is converted to struct ipaddr structure
1104 static void *route_set_evpn_gateway_ip_compile(const char *arg
)
1106 struct ipaddr
*gw_ip
= NULL
;
1109 gw_ip
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct ipaddr
));
1111 ret
= str2ipaddr(arg
, gw_ip
);
1113 XFREE(MTYPE_ROUTE_MAP_COMPILED
, gw_ip
);
1119 /* Free route map's compiled `evpn gateway_ip' value. */
1120 static void route_set_evpn_gateway_ip_free(void *rule
)
1122 struct ipaddr
*gw_ip
= rule
;
1124 XFREE(MTYPE_ROUTE_MAP_COMPILED
, gw_ip
);
1127 /* Route map commands for set evpn gateway-ip ipv4. */
1128 struct route_map_rule_cmd route_set_evpn_gateway_ip_ipv4_cmd
= {
1129 "evpn gateway-ip ipv4", route_set_evpn_gateway_ip
,
1130 route_set_evpn_gateway_ip_compile
, route_set_evpn_gateway_ip_free
};
1132 /* Route map commands for set evpn gateway-ip ipv6. */
1133 struct route_map_rule_cmd route_set_evpn_gateway_ip_ipv6_cmd
= {
1134 "evpn gateway-ip ipv6", route_set_evpn_gateway_ip
,
1135 route_set_evpn_gateway_ip_compile
, route_set_evpn_gateway_ip_free
};
1137 /* Route map commands for VRF route leak with source vrf matching */
1138 static enum route_map_cmd_result_t
1139 route_match_vrl_source_vrf(void *rule
, const struct prefix
*prefix
,
1142 struct bgp_path_info
*path
;
1146 path
= (struct bgp_path_info
*)object
;
1148 if (strncmp(vrf_name
, "n/a", VRF_NAMSIZ
) == 0)
1149 return RMAP_NOMATCH
;
1151 if (path
->extra
== NULL
)
1152 return RMAP_NOMATCH
;
1154 if (strncmp(vrf_name
, vrf_id_to_name(path
->extra
->bgp_orig
->vrf_id
),
1159 return RMAP_NOMATCH
;
1162 static void *route_match_vrl_source_vrf_compile(const char *arg
)
1164 uint8_t *vrf_name
= NULL
;
1166 vrf_name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1171 /* Free route map's compiled `route-type' value. */
1172 static void route_match_vrl_source_vrf_free(void *rule
)
1174 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1177 static const struct route_map_rule_cmd route_match_vrl_source_vrf_cmd
= {
1179 route_match_vrl_source_vrf
,
1180 route_match_vrl_source_vrf_compile
,
1181 route_match_vrl_source_vrf_free
1185 static enum route_map_cmd_result_t
1186 route_match_alias(void *rule
, const struct prefix
*prefix
, void *object
)
1189 struct bgp_path_info
*path
= object
;
1194 if (path
->attr
->community
) {
1196 frrstr_split(path
->attr
->community
->str
, " ", &communities
,
1198 for (int i
= 0; i
< num
; i
++) {
1199 const char *com2alias
=
1200 bgp_community2alias(communities
[i
]);
1201 if (!found
&& strcmp(alias
, com2alias
) == 0)
1203 XFREE(MTYPE_TMP
, communities
[i
]);
1205 XFREE(MTYPE_TMP
, communities
);
1210 if (path
->attr
->lcommunity
) {
1212 frrstr_split(path
->attr
->lcommunity
->str
, " ", &communities
,
1214 for (int i
= 0; i
< num
; i
++) {
1215 const char *com2alias
=
1216 bgp_community2alias(communities
[i
]);
1217 if (!found
&& strcmp(alias
, com2alias
) == 0)
1219 XFREE(MTYPE_TMP
, communities
[i
]);
1221 XFREE(MTYPE_TMP
, communities
);
1226 return RMAP_NOMATCH
;
1229 static void *route_match_alias_compile(const char *arg
)
1232 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1235 static void route_match_alias_free(void *rule
)
1237 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1240 static const struct route_map_rule_cmd route_match_alias_cmd
= {
1241 "alias", route_match_alias
, route_match_alias_compile
,
1242 route_match_alias_free
};
1244 /* `match local-preference LOCAL-PREF' */
1246 /* Match function return 1 if match is success else return zero. */
1247 static enum route_map_cmd_result_t
1248 route_match_local_pref(void *rule
, const struct prefix
*prefix
, void *object
)
1250 uint32_t *local_pref
;
1251 struct bgp_path_info
*path
;
1256 if (path
->attr
->local_pref
== *local_pref
)
1259 return RMAP_NOMATCH
;
1263 * Route map `match local-preference' match statement.
1264 * `arg' is local-pref value
1266 static void *route_match_local_pref_compile(const char *arg
)
1268 uint32_t *local_pref
;
1269 char *endptr
= NULL
;
1270 unsigned long tmpval
;
1272 /* Locpref value shoud be integer. */
1273 if (!all_digit(arg
))
1277 tmpval
= strtoul(arg
, &endptr
, 10);
1278 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
1281 local_pref
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1283 *local_pref
= tmpval
;
1287 /* Free route map's compiled `match local-preference' value. */
1288 static void route_match_local_pref_free(void *rule
)
1290 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1293 /* Route map commands for metric matching. */
1294 static const struct route_map_rule_cmd route_match_local_pref_cmd
= {
1296 route_match_local_pref
,
1297 route_match_local_pref_compile
,
1298 route_match_local_pref_free
1301 /* `match metric METRIC' */
1303 /* Match function return 1 if match is success else return zero. */
1304 static enum route_map_cmd_result_t
1305 route_match_metric(void *rule
, const struct prefix
*prefix
, void *object
)
1307 struct rmap_value
*rv
;
1308 struct bgp_path_info
*path
;
1312 return route_value_match(rv
, path
->attr
->med
);
1315 /* Route map commands for metric matching. */
1316 static const struct route_map_rule_cmd route_match_metric_cmd
= {
1319 route_value_compile
,
1323 /* `match as-path ASPATH' */
1325 /* Match function for as-path match. I assume given object is */
1326 static enum route_map_cmd_result_t
1327 route_match_aspath(void *rule
, const struct prefix
*prefix
, void *object
)
1330 struct as_list
*as_list
;
1331 struct bgp_path_info
*path
;
1333 as_list
= as_list_lookup((char *)rule
);
1334 if (as_list
== NULL
)
1335 return RMAP_NOMATCH
;
1339 /* Perform match. */
1340 return ((as_list_apply(as_list
, path
->attr
->aspath
) == AS_FILTER_DENY
)
1345 /* Compile function for as-path match. */
1346 static void *route_match_aspath_compile(const char *arg
)
1348 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1351 /* Compile function for as-path match. */
1352 static void route_match_aspath_free(void *rule
)
1354 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1357 /* Route map commands for aspath matching. */
1358 static const struct route_map_rule_cmd route_match_aspath_cmd
= {
1361 route_match_aspath_compile
,
1362 route_match_aspath_free
1365 /* `match community COMMUNIY' */
1366 struct rmap_community
{
1372 /* Match function for community match. */
1373 static enum route_map_cmd_result_t
1374 route_match_community(void *rule
, const struct prefix
*prefix
, void *object
)
1376 struct community_list
*list
;
1377 struct bgp_path_info
*path
;
1378 struct rmap_community
*rcom
= rule
;
1383 list
= community_list_lookup(bgp_clist
, rcom
->name
, rcom
->name_hash
,
1384 COMMUNITY_LIST_MASTER
);
1386 return RMAP_NOMATCH
;
1389 if (community_list_exact_match(path
->attr
->community
, list
))
1392 if (community_list_match(path
->attr
->community
, list
))
1396 return RMAP_NOMATCH
;
1399 /* Compile function for community match. */
1400 static void *route_match_community_compile(const char *arg
)
1402 struct rmap_community
*rcom
;
1406 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1408 p
= strchr(arg
, ' ');
1411 rcom
->name
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1412 memcpy(rcom
->name
, arg
, len
);
1415 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1419 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1423 /* Compile function for community match. */
1424 static void route_match_community_free(void *rule
)
1426 struct rmap_community
*rcom
= rule
;
1428 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1429 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1433 * In routemap processing there is a need to add the
1434 * name as a rule_key in the dependency table. Routemap
1435 * lib is unaware of rule_key when exact-match clause
1436 * is in use. routemap lib uses the compiled output to
1437 * get the rule_key value.
1439 static void *route_match_get_community_key(void *rule
)
1441 struct rmap_community
*rcom
;
1448 /* Route map commands for community matching. */
1449 static const struct route_map_rule_cmd route_match_community_cmd
= {
1451 route_match_community
,
1452 route_match_community_compile
,
1453 route_match_community_free
,
1454 route_match_get_community_key
1457 /* Match function for lcommunity match. */
1458 static enum route_map_cmd_result_t
1459 route_match_lcommunity(void *rule
, const struct prefix
*prefix
, void *object
)
1461 struct community_list
*list
;
1462 struct bgp_path_info
*path
;
1463 struct rmap_community
*rcom
= rule
;
1467 list
= community_list_lookup(bgp_clist
, rcom
->name
, rcom
->name_hash
,
1468 LARGE_COMMUNITY_LIST_MASTER
);
1470 return RMAP_NOMATCH
;
1473 if (lcommunity_list_exact_match(path
->attr
->lcommunity
, list
))
1476 if (lcommunity_list_match(path
->attr
->lcommunity
, list
))
1480 return RMAP_NOMATCH
;
1483 /* Compile function for community match. */
1484 static void *route_match_lcommunity_compile(const char *arg
)
1486 struct rmap_community
*rcom
;
1490 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1492 p
= strchr(arg
, ' ');
1495 rcom
->name
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1496 memcpy(rcom
->name
, arg
, len
);
1499 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1503 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1507 /* Compile function for community match. */
1508 static void route_match_lcommunity_free(void *rule
)
1510 struct rmap_community
*rcom
= rule
;
1512 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1513 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1516 /* Route map commands for community matching. */
1517 static const struct route_map_rule_cmd route_match_lcommunity_cmd
= {
1519 route_match_lcommunity
,
1520 route_match_lcommunity_compile
,
1521 route_match_lcommunity_free
,
1522 route_match_get_community_key
1526 /* Match function for extcommunity match. */
1527 static enum route_map_cmd_result_t
1528 route_match_ecommunity(void *rule
, const struct prefix
*prefix
, void *object
)
1530 struct community_list
*list
;
1531 struct bgp_path_info
*path
;
1532 struct rmap_community
*rcom
= rule
;
1536 list
= community_list_lookup(bgp_clist
, rcom
->name
, rcom
->name_hash
,
1537 EXTCOMMUNITY_LIST_MASTER
);
1539 return RMAP_NOMATCH
;
1541 if (ecommunity_list_match(path
->attr
->ecommunity
, list
))
1544 return RMAP_NOMATCH
;
1547 /* Compile function for extcommunity match. */
1548 static void *route_match_ecommunity_compile(const char *arg
)
1550 struct rmap_community
*rcom
;
1552 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
1553 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1554 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
1559 /* Compile function for extcommunity match. */
1560 static void route_match_ecommunity_free(void *rule
)
1562 struct rmap_community
*rcom
= rule
;
1564 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
1565 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
1568 /* Route map commands for community matching. */
1569 static const struct route_map_rule_cmd route_match_ecommunity_cmd
= {
1571 route_match_ecommunity
,
1572 route_match_ecommunity_compile
,
1573 route_match_ecommunity_free
1576 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
1577 and `address-family vpnv4'. */
1579 /* `match origin' */
1580 static enum route_map_cmd_result_t
1581 route_match_origin(void *rule
, const struct prefix
*prefix
, void *object
)
1584 struct bgp_path_info
*path
;
1589 if (path
->attr
->origin
== *origin
)
1592 return RMAP_NOMATCH
;
1595 static void *route_match_origin_compile(const char *arg
)
1599 origin
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
1601 if (strcmp(arg
, "igp") == 0)
1603 else if (strcmp(arg
, "egp") == 0)
1611 /* Free route map's compiled `ip address' value. */
1612 static void route_match_origin_free(void *rule
)
1614 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1617 /* Route map commands for origin matching. */
1618 static const struct route_map_rule_cmd route_match_origin_cmd
= {
1621 route_match_origin_compile
,
1622 route_match_origin_free
1625 /* match probability { */
1627 static enum route_map_cmd_result_t
1628 route_match_probability(void *rule
, const struct prefix
*prefix
, void *object
)
1630 long r
= frr_weak_random();
1632 switch (*(long *)rule
) {
1638 if (r
< *(long *)rule
) {
1643 return RMAP_NOMATCH
;
1646 static void *route_match_probability_compile(const char *arg
)
1652 lobule
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(long));
1662 *lobule
= RAND_MAX
/ 100 * perc
;
1668 static void route_match_probability_free(void *rule
)
1670 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1673 static const struct route_map_rule_cmd route_match_probability_cmd
= {
1675 route_match_probability
,
1676 route_match_probability_compile
,
1677 route_match_probability_free
1680 /* `match interface IFNAME' */
1681 /* Match function should return 1 if match is success else return
1683 static enum route_map_cmd_result_t
1684 route_match_interface(void *rule
, const struct prefix
*prefix
, void *object
)
1686 struct interface
*ifp
;
1687 struct bgp_path_info
*path
;
1691 if (!path
|| !path
->peer
|| !path
->peer
->bgp
)
1692 return RMAP_NOMATCH
;
1694 ifp
= if_lookup_by_name((char *)rule
, path
->peer
->bgp
->vrf_id
);
1696 if (ifp
== NULL
|| ifp
->ifindex
!= path
->attr
->nh_ifindex
)
1697 return RMAP_NOMATCH
;
1702 /* Route map `interface' match statement. `arg' should be
1704 static void *route_match_interface_compile(const char *arg
)
1706 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
1709 /* Free route map's compiled `interface' value. */
1710 static void route_match_interface_free(void *rule
)
1712 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1715 /* Route map commands for ip address matching. */
1716 static const struct route_map_rule_cmd route_match_interface_cmd
= {
1718 route_match_interface
,
1719 route_match_interface_compile
,
1720 route_match_interface_free
1725 /* `set ip next-hop IP_ADDRESS' */
1727 /* Match function return 1 if match is success else return zero. */
1728 static enum route_map_cmd_result_t
1729 route_match_tag(void *rule
, const struct prefix
*prefix
, void *object
)
1732 struct bgp_path_info
*path
;
1737 return ((path
->attr
->tag
== *tag
) ? RMAP_MATCH
: RMAP_NOMATCH
);
1741 /* Route map commands for tag matching. */
1742 static const struct route_map_rule_cmd route_match_tag_cmd
= {
1745 route_map_rule_tag_compile
,
1746 route_map_rule_tag_free
,
1749 static enum route_map_cmd_result_t
1750 route_set_srte_color(void *rule
, const struct prefix
*prefix
, void *object
)
1752 uint32_t *srte_color
= rule
;
1753 struct bgp_path_info
*path
;
1757 path
->attr
->srte_color
= *srte_color
;
1758 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR
);
1763 /* Route map `sr-te color' compile function */
1764 static void *route_set_srte_color_compile(const char *arg
)
1768 color
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint32_t));
1774 /* Free route map's compiled `sr-te color' value. */
1775 static void route_set_srte_color_free(void *rule
)
1777 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
1780 /* Route map commands for sr-te color set. */
1781 struct route_map_rule_cmd route_set_srte_color_cmd
= {
1782 "sr-te color", route_set_srte_color
, route_set_srte_color_compile
,
1783 route_set_srte_color_free
};
1785 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1786 struct rmap_ip_nexthop_set
{
1787 struct in_addr
*address
;
1792 static enum route_map_cmd_result_t
1793 route_set_ip_nexthop(void *rule
, const struct prefix
*prefix
, void *object
)
1795 struct rmap_ip_nexthop_set
*rins
= rule
;
1796 struct bgp_path_info
*path
;
1799 if (prefix
->family
== AF_INET6
)
1805 if (rins
->unchanged
) {
1806 SET_FLAG(path
->attr
->rmap_change_flags
,
1807 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1808 } else if (rins
->peer_address
) {
1809 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
1810 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1812 && sockunion_family(peer
->su_remote
) == AF_INET
) {
1813 path
->attr
->nexthop
.s_addr
=
1814 sockunion2ip(peer
->su_remote
);
1815 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1816 } else if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
)) {
1817 /* The next hop value will be set as part of
1818 * packet rewrite. Set the flags here to indicate
1819 * that rewrite needs to be done.
1820 * Also, clear the value.
1822 SET_FLAG(path
->attr
->rmap_change_flags
,
1823 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1824 path
->attr
->nexthop
.s_addr
= INADDR_ANY
;
1827 /* Set next hop value. */
1828 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
1829 path
->attr
->nexthop
= *rins
->address
;
1830 SET_FLAG(path
->attr
->rmap_change_flags
,
1831 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1832 /* case for MP-BGP : MPLS VPN */
1833 path
->attr
->mp_nexthop_global_in
= *rins
->address
;
1834 path
->attr
->mp_nexthop_len
= sizeof(*rins
->address
);
1840 /* Route map `ip nexthop' compile function. Given string is converted
1841 to struct in_addr structure. */
1842 static void *route_set_ip_nexthop_compile(const char *arg
)
1844 struct rmap_ip_nexthop_set
*rins
;
1845 struct in_addr
*address
= NULL
;
1846 int peer_address
= 0;
1850 if (strcmp(arg
, "peer-address") == 0)
1852 else if (strcmp(arg
, "unchanged") == 0)
1855 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
,
1856 sizeof(struct in_addr
));
1857 ret
= inet_aton(arg
, address
);
1860 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
1865 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
,
1866 sizeof(struct rmap_ip_nexthop_set
));
1868 rins
->address
= address
;
1869 rins
->peer_address
= peer_address
;
1870 rins
->unchanged
= unchanged
;
1875 /* Free route map's compiled `ip nexthop' value. */
1876 static void route_set_ip_nexthop_free(void *rule
)
1878 struct rmap_ip_nexthop_set
*rins
= rule
;
1880 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1882 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rins
);
1885 /* Route map commands for ip nexthop set. */
1886 static const struct route_map_rule_cmd route_set_ip_nexthop_cmd
= {
1888 route_set_ip_nexthop
,
1889 route_set_ip_nexthop_compile
,
1890 route_set_ip_nexthop_free
1893 /* `set local-preference LOCAL_PREF' */
1895 /* Set local preference. */
1896 static enum route_map_cmd_result_t
1897 route_set_local_pref(void *rule
, const struct prefix
*prefix
, void *object
)
1899 struct rmap_value
*rv
;
1900 struct bgp_path_info
*path
;
1901 uint32_t locpref
= 0;
1903 /* Fetch routemap's rule information. */
1907 /* Set local preference value. */
1908 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1909 locpref
= path
->attr
->local_pref
;
1911 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1912 path
->attr
->local_pref
= route_value_adjust(rv
, locpref
, path
->peer
);
1917 /* Set local preference rule structure. */
1918 static const struct route_map_rule_cmd route_set_local_pref_cmd
= {
1920 route_set_local_pref
,
1921 route_value_compile
,
1925 /* `set weight WEIGHT' */
1928 static enum route_map_cmd_result_t
1929 route_set_weight(void *rule
, const struct prefix
*prefix
, void *object
)
1931 struct rmap_value
*rv
;
1932 struct bgp_path_info
*path
;
1934 /* Fetch routemap's rule information. */
1938 /* Set weight value. */
1939 path
->attr
->weight
= route_value_adjust(rv
, 0, path
->peer
);
1944 /* Set local preference rule structure. */
1945 static const struct route_map_rule_cmd route_set_weight_cmd
= {
1948 route_value_compile
,
1952 /* `set distance DISTANCE */
1953 static enum route_map_cmd_result_t
1954 route_set_distance(void *rule
, const struct prefix
*prefix
, void *object
)
1956 struct bgp_path_info
*path
= object
;
1957 struct rmap_value
*rv
= rule
;
1959 path
->attr
->distance
= rv
->value
;
1964 /* set distance rule structure */
1965 static const struct route_map_rule_cmd route_set_distance_cmd
= {
1968 route_value_compile
,
1972 /* `set metric METRIC' */
1974 /* Set metric to attribute. */
1975 static enum route_map_cmd_result_t
1976 route_set_metric(void *rule
, const struct prefix
*prefix
, void *object
)
1978 struct rmap_value
*rv
;
1979 struct bgp_path_info
*path
;
1982 /* Fetch routemap's rule information. */
1986 if (path
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
1987 med
= path
->attr
->med
;
1989 path
->attr
->med
= route_value_adjust(rv
, med
, path
->peer
);
1990 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
1995 /* Set metric rule structure. */
1996 static const struct route_map_rule_cmd route_set_metric_cmd
= {
1999 route_value_compile
,
2003 /* `set table (1-4294967295)' */
2005 static enum route_map_cmd_result_t
2006 route_set_table_id(void *rule
, const struct prefix
*prefix
,
2010 struct rmap_value
*rv
;
2011 struct bgp_path_info
*path
;
2013 /* Fetch routemap's rule information. */
2017 path
->attr
->rmap_table_id
= rv
->value
;
2022 /* Set table_id rule structure. */
2023 static const struct route_map_rule_cmd route_set_table_id_cmd
= {
2026 route_value_compile
,
2030 /* `set as-path prepend ASPATH' */
2032 /* For AS path prepend mechanism. */
2033 static enum route_map_cmd_result_t
2034 route_set_aspath_prepend(void *rule
, const struct prefix
*prefix
, void *object
)
2036 struct aspath
*aspath
;
2038 struct bgp_path_info
*path
;
2042 if (path
->attr
->aspath
->refcnt
)
2043 new = aspath_dup(path
->attr
->aspath
);
2045 new = path
->attr
->aspath
;
2047 if ((uintptr_t)rule
> 10) {
2049 aspath_prepend(aspath
, new);
2051 as_t as
= aspath_leftmost(new);
2053 new = aspath_add_seq_n(new, as
, (uintptr_t)rule
);
2056 path
->attr
->aspath
= new;
2061 static void *route_set_aspath_prepend_compile(const char *arg
)
2065 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
<= 10)
2066 return (void *)(uintptr_t)num
;
2068 return route_aspath_compile(arg
);
2071 static void route_set_aspath_prepend_free(void *rule
)
2073 if ((uintptr_t)rule
> 10)
2074 route_aspath_free(rule
);
2078 /* Set as-path prepend rule structure. */
2079 static const struct route_map_rule_cmd route_set_aspath_prepend_cmd
= {
2081 route_set_aspath_prepend
,
2082 route_set_aspath_prepend_compile
,
2083 route_set_aspath_prepend_free
,
2086 /* `set as-path exclude ASn' */
2088 /* For ASN exclude mechanism.
2089 * Iterate over ASns requested and filter them from the given AS_PATH one by
2091 * Make a deep copy of existing AS_PATH, but for the first ASn only.
2093 static enum route_map_cmd_result_t
2094 route_set_aspath_exclude(void *rule
, const struct prefix
*dummy
, void *object
)
2096 struct aspath
*new_path
, *exclude_path
;
2097 struct bgp_path_info
*path
;
2099 exclude_path
= rule
;
2101 if (path
->attr
->aspath
->refcnt
)
2102 new_path
= aspath_dup(path
->attr
->aspath
);
2104 new_path
= path
->attr
->aspath
;
2105 path
->attr
->aspath
= aspath_filter_exclude(new_path
, exclude_path
);
2110 /* Set ASn exlude rule structure. */
2111 static const struct route_map_rule_cmd route_set_aspath_exclude_cmd
= {
2113 route_set_aspath_exclude
,
2114 route_aspath_compile
,
2118 /* `set community COMMUNITY' */
2119 struct rmap_com_set
{
2120 struct community
*com
;
2125 /* For community set mechanism. */
2126 static enum route_map_cmd_result_t
2127 route_set_community(void *rule
, const struct prefix
*prefix
, void *object
)
2129 struct rmap_com_set
*rcs
;
2130 struct bgp_path_info
*path
;
2132 struct community
*new = NULL
;
2133 struct community
*old
;
2134 struct community
*merge
;
2139 old
= attr
->community
;
2143 attr
->flag
&= ~(ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
));
2144 attr
->community
= NULL
;
2145 /* See the longer comment down below. */
2146 if (old
&& old
->refcnt
== 0)
2147 community_free(&old
);
2151 /* "additive" case. */
2152 if (rcs
->additive
&& old
) {
2153 merge
= community_merge(community_dup(old
), rcs
->com
);
2155 new = community_uniq_sort(merge
);
2156 community_free(&merge
);
2158 new = community_dup(rcs
->com
);
2160 /* HACK: if the old community is not intern'd,
2161 * we should free it here, or all reference to it may be
2163 * Really need to cleanup attribute caching sometime.
2165 if (old
&& old
->refcnt
== 0)
2166 community_free(&old
);
2168 /* will be interned by caller if required */
2169 attr
->community
= new;
2171 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2176 /* Compile function for set community. */
2177 static void *route_set_community_compile(const char *arg
)
2179 struct rmap_com_set
*rcs
;
2180 struct community
*com
= NULL
;
2185 if (strcmp(arg
, "none") == 0)
2188 sp
= strstr(arg
, "additive");
2190 if (sp
&& sp
> arg
) {
2191 /* "additive" keyword is included. */
2196 com
= community_str2com(arg
);
2205 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_com_set
));
2207 rcs
->additive
= additive
;
2213 /* Free function for set community. */
2214 static void route_set_community_free(void *rule
)
2216 struct rmap_com_set
*rcs
= rule
;
2219 community_free(&rcs
->com
);
2220 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
2223 /* Set community rule structure. */
2224 static const struct route_map_rule_cmd route_set_community_cmd
= {
2226 route_set_community
,
2227 route_set_community_compile
,
2228 route_set_community_free
,
2231 /* `set community COMMUNITY' */
2232 struct rmap_lcom_set
{
2233 struct lcommunity
*lcom
;
2239 /* For lcommunity set mechanism. */
2240 static enum route_map_cmd_result_t
2241 route_set_lcommunity(void *rule
, const struct prefix
*prefix
, void *object
)
2243 struct rmap_lcom_set
*rcs
;
2244 struct bgp_path_info
*path
;
2246 struct lcommunity
*new = NULL
;
2247 struct lcommunity
*old
;
2248 struct lcommunity
*merge
;
2253 old
= attr
->lcommunity
;
2257 attr
->flag
&= ~(ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
));
2258 attr
->lcommunity
= NULL
;
2260 /* See the longer comment down below. */
2261 if (old
&& old
->refcnt
== 0)
2262 lcommunity_free(&old
);
2266 if (rcs
->additive
&& old
) {
2267 merge
= lcommunity_merge(lcommunity_dup(old
), rcs
->lcom
);
2269 new = lcommunity_uniq_sort(merge
);
2270 lcommunity_free(&merge
);
2272 new = lcommunity_dup(rcs
->lcom
);
2274 /* HACK: if the old large-community is not intern'd,
2275 * we should free it here, or all reference to it may be
2277 * Really need to cleanup attribute caching sometime.
2279 if (old
&& old
->refcnt
== 0)
2280 lcommunity_free(&old
);
2282 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
2283 attr
->lcommunity
= new;
2285 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
);
2290 /* Compile function for set community. */
2291 static void *route_set_lcommunity_compile(const char *arg
)
2293 struct rmap_lcom_set
*rcs
;
2294 struct lcommunity
*lcom
= NULL
;
2299 if (strcmp(arg
, "none") == 0)
2302 sp
= strstr(arg
, "additive");
2304 if (sp
&& sp
> arg
) {
2305 /* "additive" keyworkd is included. */
2310 lcom
= lcommunity_str2com(arg
);
2319 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_com_set
));
2321 rcs
->additive
= additive
;
2327 /* Free function for set lcommunity. */
2328 static void route_set_lcommunity_free(void *rule
)
2330 struct rmap_lcom_set
*rcs
= rule
;
2333 lcommunity_free(&rcs
->lcom
);
2335 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
2338 /* Set community rule structure. */
2339 static const struct route_map_rule_cmd route_set_lcommunity_cmd
= {
2341 route_set_lcommunity
,
2342 route_set_lcommunity_compile
,
2343 route_set_lcommunity_free
,
2346 /* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
2348 /* For large community set mechanism. */
2349 static enum route_map_cmd_result_t
2350 route_set_lcommunity_delete(void *rule
, const struct prefix
*pfx
, void *object
)
2352 struct community_list
*list
;
2353 struct lcommunity
*merge
;
2354 struct lcommunity
*new;
2355 struct lcommunity
*old
;
2356 struct bgp_path_info
*path
;
2357 struct rmap_community
*rcom
= rule
;
2363 list
= community_list_lookup(bgp_clist
, rcom
->name
, rcom
->name_hash
,
2364 LARGE_COMMUNITY_LIST_MASTER
);
2365 old
= path
->attr
->lcommunity
;
2368 merge
= lcommunity_list_match_delete(lcommunity_dup(old
), list
);
2369 new = lcommunity_uniq_sort(merge
);
2370 lcommunity_free(&merge
);
2372 /* HACK: if the old community is not intern'd,
2373 * we should free it here, or all reference to it may be
2375 * Really need to cleanup attribute caching sometime.
2377 if (old
->refcnt
== 0)
2378 lcommunity_free(&old
);
2380 if (new->size
== 0) {
2381 path
->attr
->lcommunity
= NULL
;
2383 ~ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
);
2384 lcommunity_free(&new);
2386 path
->attr
->lcommunity
= new;
2388 ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
);
2395 /* Compile function for set lcommunity. */
2396 static void *route_set_lcommunity_delete_compile(const char *arg
)
2398 struct rmap_community
*rcom
;
2402 frrstr_split(arg
, " ", &splits
, &num
);
2404 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
2405 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, splits
[0]);
2406 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
2408 for (int i
= 0; i
< num
; i
++)
2409 XFREE(MTYPE_TMP
, splits
[i
]);
2410 XFREE(MTYPE_TMP
, splits
);
2415 /* Free function for set lcommunity. */
2416 static void route_set_lcommunity_delete_free(void *rule
)
2418 struct rmap_community
*rcom
= rule
;
2420 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
2421 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
2424 /* Set lcommunity rule structure. */
2425 static const struct route_map_rule_cmd route_set_lcommunity_delete_cmd
= {
2427 route_set_lcommunity_delete
,
2428 route_set_lcommunity_delete_compile
,
2429 route_set_lcommunity_delete_free
,
2433 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
2435 /* For community set mechanism. */
2436 static enum route_map_cmd_result_t
2437 route_set_community_delete(void *rule
, const struct prefix
*prefix
,
2440 struct community_list
*list
;
2441 struct community
*merge
;
2442 struct community
*new;
2443 struct community
*old
;
2444 struct bgp_path_info
*path
;
2445 struct rmap_community
*rcom
= rule
;
2451 list
= community_list_lookup(bgp_clist
, rcom
->name
, rcom
->name_hash
,
2452 COMMUNITY_LIST_MASTER
);
2453 old
= path
->attr
->community
;
2456 merge
= community_list_match_delete(community_dup(old
), list
);
2457 new = community_uniq_sort(merge
);
2458 community_free(&merge
);
2460 /* HACK: if the old community is not intern'd,
2461 * we should free it here, or all reference to it may be
2463 * Really need to cleanup attribute caching sometime.
2465 if (old
->refcnt
== 0)
2466 community_free(&old
);
2468 if (new->size
== 0) {
2469 path
->attr
->community
= NULL
;
2471 ~ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2472 community_free(&new);
2474 path
->attr
->community
= new;
2475 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
2482 /* Compile function for set community. */
2483 static void *route_set_community_delete_compile(const char *arg
)
2485 struct rmap_community
*rcom
;
2489 frrstr_split(arg
, " ", &splits
, &num
);
2491 rcom
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_community
));
2492 rcom
->name
= XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, splits
[0]);
2493 rcom
->name_hash
= bgp_clist_hash_key(rcom
->name
);
2495 for (int i
= 0; i
< num
; i
++)
2496 XFREE(MTYPE_TMP
, splits
[i
]);
2497 XFREE(MTYPE_TMP
, splits
);
2502 /* Free function for set community. */
2503 static void route_set_community_delete_free(void *rule
)
2505 struct rmap_community
*rcom
= rule
;
2507 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
2508 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcom
);
2511 /* Set community rule structure. */
2512 static const struct route_map_rule_cmd route_set_community_delete_cmd
= {
2514 route_set_community_delete
,
2515 route_set_community_delete_compile
,
2516 route_set_community_delete_free
,
2519 /* `set extcommunity rt COMMUNITY' */
2521 struct rmap_ecom_set
{
2522 struct ecommunity
*ecom
;
2526 /* For community set mechanism. Used by _rt and _soo. */
2527 static enum route_map_cmd_result_t
2528 route_set_ecommunity(void *rule
, const struct prefix
*prefix
, void *object
)
2530 struct rmap_ecom_set
*rcs
;
2531 struct ecommunity
*new_ecom
;
2532 struct ecommunity
*old_ecom
;
2533 struct bgp_path_info
*path
;
2541 attr
->flag
&= ~(ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
));
2542 attr
->ecommunity
= NULL
;
2549 /* We assume additive for Extended Community. */
2550 old_ecom
= path
->attr
->ecommunity
;
2554 ecommunity_merge(ecommunity_dup(old_ecom
), rcs
->ecom
);
2556 /* old_ecom->refcnt = 1 => owned elsewhere, e.g.
2557 * bgp_update_receive()
2558 * ->refcnt = 0 => set by a previous route-map
2560 if (!old_ecom
->refcnt
)
2561 ecommunity_free(&old_ecom
);
2563 new_ecom
= ecommunity_dup(rcs
->ecom
);
2565 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
2566 path
->attr
->ecommunity
= new_ecom
;
2568 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
2573 static void *route_set_ecommunity_none_compile(const char *arg
)
2575 struct rmap_ecom_set
*rcs
;
2578 if (strncmp(arg
, "none", 4) == 0)
2581 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_ecom_set
));
2588 static void *route_set_ecommunity_rt_compile(const char *arg
)
2590 struct rmap_ecom_set
*rcs
;
2591 struct ecommunity
*ecom
;
2593 ecom
= ecommunity_str2com(arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
2597 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_ecom_set
));
2598 rcs
->ecom
= ecommunity_intern(ecom
);
2604 /* Free function for set community. Used by _rt and _soo */
2605 static void route_set_ecommunity_free(void *rule
)
2607 struct rmap_ecom_set
*rcs
= rule
;
2610 ecommunity_unintern(&rcs
->ecom
);
2612 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rcs
);
2615 static const struct route_map_rule_cmd route_set_ecommunity_none_cmd
= {
2617 route_set_ecommunity
,
2618 route_set_ecommunity_none_compile
,
2619 route_set_ecommunity_free
,
2622 /* Set community rule structure. */
2623 static const struct route_map_rule_cmd route_set_ecommunity_rt_cmd
= {
2625 route_set_ecommunity
,
2626 route_set_ecommunity_rt_compile
,
2627 route_set_ecommunity_free
,
2630 /* `set extcommunity soo COMMUNITY' */
2632 /* Compile function for set community. */
2633 static void *route_set_ecommunity_soo_compile(const char *arg
)
2635 struct rmap_ecom_set
*rcs
;
2636 struct ecommunity
*ecom
;
2638 ecom
= ecommunity_str2com(arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
2642 rcs
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_ecom_set
));
2643 rcs
->ecom
= ecommunity_intern(ecom
);
2649 /* Set community rule structure. */
2650 static const struct route_map_rule_cmd route_set_ecommunity_soo_cmd
= {
2652 route_set_ecommunity
,
2653 route_set_ecommunity_soo_compile
,
2654 route_set_ecommunity_free
,
2657 /* `set extcommunity bandwidth' */
2659 struct rmap_ecomm_lb_set
{
2661 #define RMAP_ECOMM_LB_SET_VALUE 1
2662 #define RMAP_ECOMM_LB_SET_CUMUL 2
2663 #define RMAP_ECOMM_LB_SET_NUM_MPATH 3
2668 static enum route_map_cmd_result_t
2669 route_set_ecommunity_lb(void *rule
, const struct prefix
*prefix
, void *object
)
2671 struct rmap_ecomm_lb_set
*rels
= rule
;
2672 struct bgp_path_info
*path
;
2674 struct ecommunity ecom_lb
= {0};
2675 struct ecommunity_val lb_eval
;
2676 uint32_t bw_bytes
= 0;
2677 uint16_t mpath_count
= 0;
2678 struct ecommunity
*new_ecom
;
2679 struct ecommunity
*old_ecom
;
2684 if (!peer
|| !peer
->bgp
)
2687 /* Build link bandwidth extended community */
2688 as
= (peer
->bgp
->as
> BGP_AS_MAX
) ? BGP_AS_TRANS
: peer
->bgp
->as
;
2689 if (rels
->lb_type
== RMAP_ECOMM_LB_SET_VALUE
) {
2690 bw_bytes
= ((uint64_t)rels
->bw
* 1000 * 1000) / 8;
2691 } else if (rels
->lb_type
== RMAP_ECOMM_LB_SET_CUMUL
) {
2692 /* process this only for the best path. */
2693 if (!CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
2696 bw_bytes
= (uint32_t)bgp_path_info_mpath_cumbw(path
);
2700 } else if (rels
->lb_type
== RMAP_ECOMM_LB_SET_NUM_MPATH
) {
2702 /* process this only for the best path. */
2703 if (!CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
2706 bw_bytes
= ((uint64_t)peer
->bgp
->lb_ref_bw
* 1000 * 1000) / 8;
2707 mpath_count
= bgp_path_info_mpath_count(path
) + 1;
2708 bw_bytes
*= mpath_count
;
2711 encode_lb_extcomm(as
, bw_bytes
, rels
->non_trans
, &lb_eval
,
2712 CHECK_FLAG(peer
->flags
,
2713 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE
));
2715 /* add to route or merge with existing */
2716 old_ecom
= path
->attr
->ecommunity
;
2718 new_ecom
= ecommunity_dup(old_ecom
);
2719 ecommunity_add_val(new_ecom
, &lb_eval
, true, true);
2720 if (!old_ecom
->refcnt
)
2721 ecommunity_free(&old_ecom
);
2724 ecom_lb
.unit_size
= ECOMMUNITY_SIZE
;
2725 ecom_lb
.val
= (uint8_t *)lb_eval
.val
;
2726 new_ecom
= ecommunity_dup(&ecom_lb
);
2729 /* new_ecom will be intern()'d or attr_flush()'d in call stack */
2730 path
->attr
->ecommunity
= new_ecom
;
2731 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
2733 /* Mark that route-map has set link bandwidth; used in attribute
2734 * setting decisions.
2736 SET_FLAG(path
->attr
->rmap_change_flags
, BATTR_RMAP_LINK_BW_SET
);
2741 static void *route_set_ecommunity_lb_compile(const char *arg
)
2743 struct rmap_ecomm_lb_set
*rels
;
2746 char bw_str
[40] = {0};
2748 bool non_trans
= false;
2751 p
= strchr(arg
, ' ');
2756 memcpy(bw_str
, arg
, len
);
2761 if (strcmp(str
, "cumulative") == 0)
2762 lb_type
= RMAP_ECOMM_LB_SET_CUMUL
;
2763 else if (strcmp(str
, "num-multipaths") == 0)
2764 lb_type
= RMAP_ECOMM_LB_SET_NUM_MPATH
;
2768 bw
= strtoul(str
, &end
, 10);
2771 lb_type
= RMAP_ECOMM_LB_SET_VALUE
;
2774 rels
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
,
2775 sizeof(struct rmap_ecomm_lb_set
));
2776 rels
->lb_type
= lb_type
;
2778 rels
->non_trans
= non_trans
;
2783 static void route_set_ecommunity_lb_free(void *rule
)
2785 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2788 /* Set community rule structure. */
2789 struct route_map_rule_cmd route_set_ecommunity_lb_cmd
= {
2790 "extcommunity bandwidth",
2791 route_set_ecommunity_lb
,
2792 route_set_ecommunity_lb_compile
,
2793 route_set_ecommunity_lb_free
,
2796 /* `set origin ORIGIN' */
2798 /* For origin set. */
2799 static enum route_map_cmd_result_t
2800 route_set_origin(void *rule
, const struct prefix
*prefix
, void *object
)
2803 struct bgp_path_info
*path
;
2808 path
->attr
->origin
= *origin
;
2813 /* Compile function for origin set. */
2814 static void *route_set_origin_compile(const char *arg
)
2818 origin
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
2820 if (strcmp(arg
, "igp") == 0)
2822 else if (strcmp(arg
, "egp") == 0)
2830 /* Compile function for origin set. */
2831 static void route_set_origin_free(void *rule
)
2833 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2836 /* Set origin rule structure. */
2837 static const struct route_map_rule_cmd route_set_origin_cmd
= {
2840 route_set_origin_compile
,
2841 route_set_origin_free
,
2844 /* `set atomic-aggregate' */
2846 /* For atomic aggregate set. */
2847 static enum route_map_cmd_result_t
2848 route_set_atomic_aggregate(void *rule
, const struct prefix
*pfx
, void *object
)
2850 struct bgp_path_info
*path
;
2853 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
2858 /* Compile function for atomic aggregate. */
2859 static void *route_set_atomic_aggregate_compile(const char *arg
)
2864 /* Compile function for atomic aggregate. */
2865 static void route_set_atomic_aggregate_free(void *rule
)
2870 /* Set atomic aggregate rule structure. */
2871 static const struct route_map_rule_cmd route_set_atomic_aggregate_cmd
= {
2873 route_set_atomic_aggregate
,
2874 route_set_atomic_aggregate_compile
,
2875 route_set_atomic_aggregate_free
,
2878 /* `set aggregator as AS A.B.C.D' */
2881 struct in_addr address
;
2884 static enum route_map_cmd_result_t
2885 route_set_aggregator_as(void *rule
, const struct prefix
*prefix
, void *object
)
2887 struct bgp_path_info
*path
;
2888 struct aggregator
*aggregator
;
2893 path
->attr
->aggregator_as
= aggregator
->as
;
2894 path
->attr
->aggregator_addr
= aggregator
->address
;
2895 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
);
2900 static void *route_set_aggregator_as_compile(const char *arg
)
2902 struct aggregator
*aggregator
;
2908 XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct aggregator
));
2909 if (sscanf(arg
, "%s %s", as
, address
) != 2) {
2910 XFREE(MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2914 aggregator
->as
= strtoul(as
, NULL
, 10);
2915 ret
= inet_aton(address
, &aggregator
->address
);
2917 XFREE(MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2923 static void route_set_aggregator_as_free(void *rule
)
2925 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
2928 static const struct route_map_rule_cmd route_set_aggregator_as_cmd
= {
2930 route_set_aggregator_as
,
2931 route_set_aggregator_as_compile
,
2932 route_set_aggregator_as_free
,
2935 /* Set tag to object. object must be pointer to struct bgp_path_info */
2936 static enum route_map_cmd_result_t
2937 route_set_tag(void *rule
, const struct prefix
*prefix
, void *object
)
2940 struct bgp_path_info
*path
;
2946 path
->attr
->tag
= *tag
;
2951 /* Route map commands for tag set. */
2952 static const struct route_map_rule_cmd route_set_tag_cmd
= {
2955 route_map_rule_tag_compile
,
2956 route_map_rule_tag_free
,
2959 /* Set label-index to object. object must be pointer to struct bgp_path_info */
2960 static enum route_map_cmd_result_t
2961 route_set_label_index(void *rule
, const struct prefix
*prefix
, void *object
)
2963 struct rmap_value
*rv
;
2964 struct bgp_path_info
*path
;
2965 uint32_t label_index
;
2967 /* Fetch routemap's rule information. */
2971 /* Set label-index value. */
2972 label_index
= rv
->value
;
2974 path
->attr
->label_index
= label_index
;
2975 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
2981 /* Route map commands for label-index set. */
2982 static const struct route_map_rule_cmd route_set_label_index_cmd
= {
2984 route_set_label_index
,
2985 route_value_compile
,
2989 /* `match ipv6 address IP_ACCESS_LIST' */
2991 static enum route_map_cmd_result_t
2992 route_match_ipv6_address(void *rule
, const struct prefix
*prefix
, void *object
)
2994 struct access_list
*alist
;
2996 if (prefix
->family
== AF_INET6
) {
2997 alist
= access_list_lookup(AFI_IP6
, (char *)rule
);
2999 return RMAP_NOMATCH
;
3001 return (access_list_apply(alist
, prefix
) == FILTER_DENY
3005 return RMAP_NOMATCH
;
3008 static void *route_match_ipv6_address_compile(const char *arg
)
3010 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
3013 static void route_match_ipv6_address_free(void *rule
)
3015 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3018 /* Route map commands for ip address matching. */
3019 static const struct route_map_rule_cmd route_match_ipv6_address_cmd
= {
3021 route_match_ipv6_address
,
3022 route_match_ipv6_address_compile
,
3023 route_match_ipv6_address_free
3026 /* `match ipv6 next-hop IP_ADDRESS' */
3028 static enum route_map_cmd_result_t
3029 route_match_ipv6_next_hop(void *rule
, const struct prefix
*prefix
, void *object
)
3031 struct in6_addr
*addr
= rule
;
3032 struct bgp_path_info
*path
;
3036 if (IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_global
, addr
))
3039 if (path
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
3040 && IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_local
, rule
))
3043 return RMAP_NOMATCH
;
3046 static void *route_match_ipv6_next_hop_compile(const char *arg
)
3048 struct in6_addr
*address
;
3051 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
3053 ret
= inet_pton(AF_INET6
, arg
, address
);
3055 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3062 static void route_match_ipv6_next_hop_free(void *rule
)
3064 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3067 static const struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
= {
3069 route_match_ipv6_next_hop
,
3070 route_match_ipv6_next_hop_compile
,
3071 route_match_ipv6_next_hop_free
3074 /* `match ip next-hop IP_ADDRESS' */
3076 static enum route_map_cmd_result_t
3077 route_match_ipv4_next_hop(void *rule
, const struct prefix
*prefix
, void *object
)
3079 struct in_addr
*addr
= rule
;
3080 struct bgp_path_info
*path
;
3084 if (path
->attr
->nexthop
.s_addr
== addr
->s_addr
3085 || (path
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV4
3086 && IPV4_ADDR_SAME(&path
->attr
->mp_nexthop_global_in
, addr
)))
3089 return RMAP_NOMATCH
;
3092 static void *route_match_ipv4_next_hop_compile(const char *arg
)
3094 struct in_addr
*address
;
3097 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
3099 ret
= inet_pton(AF_INET
, arg
, address
);
3101 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3108 static void route_match_ipv4_next_hop_free(void *rule
)
3110 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3113 static const struct route_map_rule_cmd route_match_ipv4_next_hop_cmd
= {
3114 "ip next-hop address",
3115 route_match_ipv4_next_hop
,
3116 route_match_ipv4_next_hop_compile
,
3117 route_match_ipv4_next_hop_free
3120 /* `match ipv6 address prefix-list PREFIX_LIST' */
3122 static enum route_map_cmd_result_t
3123 route_match_ipv6_address_prefix_list(void *rule
, const struct prefix
*prefix
,
3126 return route_match_address_prefix_list(rule
, AFI_IP6
, prefix
, object
);
3129 static void *route_match_ipv6_address_prefix_list_compile(const char *arg
)
3131 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED
, arg
);
3134 static void route_match_ipv6_address_prefix_list_free(void *rule
)
3136 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3139 static const struct route_map_rule_cmd
3140 route_match_ipv6_address_prefix_list_cmd
= {
3141 "ipv6 address prefix-list",
3142 route_match_ipv6_address_prefix_list
,
3143 route_match_ipv6_address_prefix_list_compile
,
3144 route_match_ipv6_address_prefix_list_free
3147 /* `match ipv6 next-hop type <TYPE>' */
3149 static enum route_map_cmd_result_t
3150 route_match_ipv6_next_hop_type(void *rule
, const struct prefix
*prefix
,
3153 struct bgp_path_info
*path
;
3154 struct in6_addr
*addr
= rule
;
3156 if (prefix
->family
== AF_INET6
) {
3157 path
= (struct bgp_path_info
*)object
;
3159 return RMAP_NOMATCH
;
3161 if (IPV6_ADDR_SAME(&path
->attr
->mp_nexthop_global
, addr
)
3162 && !path
->attr
->nh_ifindex
)
3166 return RMAP_NOMATCH
;
3169 static void *route_match_ipv6_next_hop_type_compile(const char *arg
)
3171 struct in6_addr
*address
;
3174 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
3176 ret
= inet_pton(AF_INET6
, "::0", address
);
3178 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3185 static void route_match_ipv6_next_hop_type_free(void *rule
)
3187 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3190 static const struct route_map_rule_cmd
3191 route_match_ipv6_next_hop_type_cmd
= {
3192 "ipv6 next-hop type",
3193 route_match_ipv6_next_hop_type
,
3194 route_match_ipv6_next_hop_type_compile
,
3195 route_match_ipv6_next_hop_type_free
3198 /* `set ipv6 nexthop global IP_ADDRESS' */
3200 /* Set nexthop to object. ojbect must be pointer to struct attr. */
3201 static enum route_map_cmd_result_t
3202 route_set_ipv6_nexthop_global(void *rule
, const struct prefix
*p
, void *object
)
3204 struct in6_addr
*address
;
3205 struct bgp_path_info
*path
;
3207 /* Fetch routemap's rule information. */
3211 /* Set next hop value. */
3212 path
->attr
->mp_nexthop_global
= *address
;
3214 /* Set nexthop length. */
3215 if (path
->attr
->mp_nexthop_len
== 0)
3216 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
3218 SET_FLAG(path
->attr
->rmap_change_flags
,
3219 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
3224 /* Route map `ip next-hop' compile function. Given string is converted
3225 to struct in_addr structure. */
3226 static void *route_set_ipv6_nexthop_global_compile(const char *arg
)
3229 struct in6_addr
*address
;
3231 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
3233 ret
= inet_pton(AF_INET6
, arg
, address
);
3236 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3243 /* Free route map's compiled `ip next-hop' value. */
3244 static void route_set_ipv6_nexthop_global_free(void *rule
)
3246 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3249 /* Route map commands for ip nexthop set. */
3250 static const struct route_map_rule_cmd
3251 route_set_ipv6_nexthop_global_cmd
= {
3252 "ipv6 next-hop global",
3253 route_set_ipv6_nexthop_global
,
3254 route_set_ipv6_nexthop_global_compile
,
3255 route_set_ipv6_nexthop_global_free
3258 /* Set next-hop preference value. */
3259 static enum route_map_cmd_result_t
3260 route_set_ipv6_nexthop_prefer_global(void *rule
, const struct prefix
*prefix
,
3263 struct bgp_path_info
*path
;
3266 /* Fetch routemap's rule information. */
3270 if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
3271 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
)) {
3272 /* Set next hop preference to global */
3273 path
->attr
->mp_nexthop_prefer_global
= true;
3274 SET_FLAG(path
->attr
->rmap_change_flags
,
3275 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
3277 path
->attr
->mp_nexthop_prefer_global
= false;
3278 SET_FLAG(path
->attr
->rmap_change_flags
,
3279 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
3285 static void *route_set_ipv6_nexthop_prefer_global_compile(const char *arg
)
3289 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
3295 /* Free route map's compiled `ip next-hop' value. */
3296 static void route_set_ipv6_nexthop_prefer_global_free(void *rule
)
3298 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3301 /* Route map commands for ip nexthop set preferred. */
3302 static const struct route_map_rule_cmd
3303 route_set_ipv6_nexthop_prefer_global_cmd
= {
3304 "ipv6 next-hop prefer-global",
3305 route_set_ipv6_nexthop_prefer_global
,
3306 route_set_ipv6_nexthop_prefer_global_compile
,
3307 route_set_ipv6_nexthop_prefer_global_free
3310 /* `set ipv6 nexthop local IP_ADDRESS' */
3312 /* Set nexthop to object. ojbect must be pointer to struct attr. */
3313 static enum route_map_cmd_result_t
3314 route_set_ipv6_nexthop_local(void *rule
, const struct prefix
*p
, void *object
)
3316 struct in6_addr
*address
;
3317 struct bgp_path_info
*path
;
3319 /* Fetch routemap's rule information. */
3323 /* Set next hop value. */
3324 path
->attr
->mp_nexthop_local
= *address
;
3326 /* Set nexthop length. */
3327 if (path
->attr
->mp_nexthop_len
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
3328 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
3330 SET_FLAG(path
->attr
->rmap_change_flags
,
3331 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
3336 /* Route map `ip nexthop' compile function. Given string is converted
3337 to struct in_addr structure. */
3338 static void *route_set_ipv6_nexthop_local_compile(const char *arg
)
3341 struct in6_addr
*address
;
3343 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
3345 ret
= inet_pton(AF_INET6
, arg
, address
);
3348 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3355 /* Free route map's compiled `ip nexthop' value. */
3356 static void route_set_ipv6_nexthop_local_free(void *rule
)
3358 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3361 /* Route map commands for ip nexthop set. */
3362 static const struct route_map_rule_cmd
3363 route_set_ipv6_nexthop_local_cmd
= {
3364 "ipv6 next-hop local",
3365 route_set_ipv6_nexthop_local
,
3366 route_set_ipv6_nexthop_local_compile
,
3367 route_set_ipv6_nexthop_local_free
3370 /* `set ipv6 nexthop peer-address' */
3372 /* Set nexthop to object. ojbect must be pointer to struct attr. */
3373 static enum route_map_cmd_result_t
3374 route_set_ipv6_nexthop_peer(void *rule
, const struct prefix
*pfx
, void *object
)
3376 struct in6_addr peer_address
;
3377 struct bgp_path_info
*path
;
3380 /* Fetch routemap's rule information. */
3384 if ((CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
)
3385 || CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
3387 && sockunion_family(peer
->su_remote
) == AF_INET6
) {
3388 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
3389 /* Set next hop value and length in attribute. */
3390 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
)) {
3391 path
->attr
->mp_nexthop_local
= peer_address
;
3392 if (path
->attr
->mp_nexthop_len
3393 != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
3394 path
->attr
->mp_nexthop_len
=
3395 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
3397 path
->attr
->mp_nexthop_global
= peer_address
;
3398 if (path
->attr
->mp_nexthop_len
== 0)
3399 path
->attr
->mp_nexthop_len
=
3400 BGP_ATTR_NHLEN_IPV6_GLOBAL
;
3403 } else if (CHECK_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
)) {
3404 /* The next hop value will be set as part of packet
3406 * Set the flags here to indicate that rewrite needs to
3408 * Also, clear the value - we clear both global and
3410 * nexthops, whether we send one or both is determined
3413 SET_FLAG(path
->attr
->rmap_change_flags
,
3414 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
3415 /* clear next hop value. */
3416 memset(&(path
->attr
->mp_nexthop_global
), 0,
3417 sizeof(struct in6_addr
));
3418 memset(&(path
->attr
->mp_nexthop_local
), 0,
3419 sizeof(struct in6_addr
));
3425 /* Route map `ip next-hop' compile function. Given string is converted
3426 to struct in_addr structure. */
3427 static void *route_set_ipv6_nexthop_peer_compile(const char *arg
)
3431 rins
= XCALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
3437 /* Free route map's compiled `ip next-hop' value. */
3438 static void route_set_ipv6_nexthop_peer_free(void *rule
)
3440 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3443 /* Route map commands for ip nexthop set. */
3444 static const struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
= {
3445 "ipv6 next-hop peer-address",
3446 route_set_ipv6_nexthop_peer
,
3447 route_set_ipv6_nexthop_peer_compile
,
3448 route_set_ipv6_nexthop_peer_free
3451 /* `set ipv4 vpn next-hop A.B.C.D' */
3453 static enum route_map_cmd_result_t
3454 route_set_vpnv4_nexthop(void *rule
, const struct prefix
*prefix
, void *object
)
3456 struct in_addr
*address
;
3457 struct bgp_path_info
*path
;
3459 /* Fetch routemap's rule information. */
3463 /* Set next hop value. */
3464 path
->attr
->mp_nexthop_global_in
= *address
;
3465 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
3470 static void *route_set_vpnv4_nexthop_compile(const char *arg
)
3473 struct in_addr
*address
;
3475 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
3477 ret
= inet_aton(arg
, address
);
3480 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3487 /* `set ipv6 vpn next-hop A.B.C.D' */
3489 static enum route_map_cmd_result_t
3490 route_set_vpnv6_nexthop(void *rule
, const struct prefix
*prefix
, void *object
)
3492 struct in6_addr
*address
;
3493 struct bgp_path_info
*path
;
3495 /* Fetch routemap's rule information. */
3499 /* Set next hop value. */
3500 memcpy(&path
->attr
->mp_nexthop_global
, address
,
3501 sizeof(struct in6_addr
));
3502 path
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_VPNV6_GLOBAL
;
3507 static void *route_set_vpnv6_nexthop_compile(const char *arg
)
3510 struct in6_addr
*address
;
3512 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in6_addr
));
3513 ret
= inet_pton(AF_INET6
, arg
, address
);
3516 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3523 static void route_set_vpn_nexthop_free(void *rule
)
3525 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3528 /* Route map commands for ipv4 next-hop set. */
3529 static const struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
= {
3530 "ipv4 vpn next-hop",
3531 route_set_vpnv4_nexthop
,
3532 route_set_vpnv4_nexthop_compile
,
3533 route_set_vpn_nexthop_free
3536 /* Route map commands for ipv6 next-hop set. */
3537 static const struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd
= {
3538 "ipv6 vpn next-hop",
3539 route_set_vpnv6_nexthop
,
3540 route_set_vpnv6_nexthop_compile
,
3541 route_set_vpn_nexthop_free
3544 /* `set originator-id' */
3546 /* For origin set. */
3547 static enum route_map_cmd_result_t
3548 route_set_originator_id(void *rule
, const struct prefix
*prefix
, void *object
)
3550 struct in_addr
*address
;
3551 struct bgp_path_info
*path
;
3556 path
->attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
);
3557 path
->attr
->originator_id
= *address
;
3562 /* Compile function for originator-id set. */
3563 static void *route_set_originator_id_compile(const char *arg
)
3566 struct in_addr
*address
;
3568 address
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct in_addr
));
3570 ret
= inet_aton(arg
, address
);
3573 XFREE(MTYPE_ROUTE_MAP_COMPILED
, address
);
3580 /* Compile function for originator_id set. */
3581 static void route_set_originator_id_free(void *rule
)
3583 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
3586 /* Set originator-id rule structure. */
3587 static const struct route_map_rule_cmd route_set_originator_id_cmd
= {
3589 route_set_originator_id
,
3590 route_set_originator_id_compile
,
3591 route_set_originator_id_free
,
3595 * This is the workhorse routine for processing in/out routemap
3598 static void bgp_route_map_process_peer(const char *rmap_name
,
3599 struct route_map
*map
, struct peer
*peer
,
3600 int afi
, int safi
, int route_update
)
3602 struct bgp_filter
*filter
;
3604 if (!peer
|| !rmap_name
)
3607 filter
= &peer
->filter
[afi
][safi
];
3609 * in is for non-route-server clients,
3610 * out is for all peers
3612 if (filter
->map
[RMAP_IN
].name
3613 && (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0)) {
3614 filter
->map
[RMAP_IN
].map
= map
;
3616 if (route_update
&& peer_established(peer
)) {
3617 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
3618 PEER_FLAG_SOFT_RECONFIG
)) {
3619 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
3621 "Processing route_map %s(%s:%s) update on peer %s (inbound, soft-reconfig)",
3622 rmap_name
, afi2str(afi
),
3623 safi2str(safi
), peer
->host
);
3625 bgp_soft_reconfig_in(peer
, afi
, safi
);
3626 } else if (CHECK_FLAG(peer
->cap
,
3627 PEER_CAP_REFRESH_OLD_RCV
)
3628 || CHECK_FLAG(peer
->cap
,
3629 PEER_CAP_REFRESH_NEW_RCV
)) {
3630 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
3632 "Processing route_map %s(%s:%s) update on peer %s (inbound, route-refresh)",
3633 rmap_name
, afi2str(afi
),
3634 safi2str(safi
), peer
->host
);
3635 bgp_route_refresh_send(
3636 peer
, afi
, safi
, 0, 0, 0,
3637 BGP_ROUTE_REFRESH_NORMAL
);
3643 * For outbound, unsuppress and default-originate map change (content or
3644 * map created), merely update the "config" here, the actual route
3645 * announcement happens at the group level.
3647 if (filter
->map
[RMAP_OUT
].name
3648 && (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
3649 filter
->map
[RMAP_OUT
].map
= map
;
3651 if (filter
->usmap
.name
&& (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3652 filter
->usmap
.map
= map
;
3654 if (filter
->advmap
.aname
3655 && (strcmp(rmap_name
, filter
->advmap
.aname
) == 0)) {
3656 filter
->advmap
.amap
= map
;
3659 if (filter
->advmap
.cname
3660 && (strcmp(rmap_name
, filter
->advmap
.cname
) == 0)) {
3661 filter
->advmap
.cmap
= map
;
3664 if (peer
->default_rmap
[afi
][safi
].name
3665 && (strcmp(rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
3666 peer
->default_rmap
[afi
][safi
].map
= map
;
3668 /* Notify BGP conditional advertisement scanner percess */
3669 peer
->advmap_config_change
[afi
][safi
] = true;
3672 static void bgp_route_map_update_peer_group(const char *rmap_name
,
3673 struct route_map
*map
,
3676 struct peer_group
*group
;
3677 struct listnode
*node
, *nnode
;
3678 struct bgp_filter
*filter
;
3685 /* All the peers have been updated correctly already. This is
3686 * just updating the placeholder data. No real update required.
3688 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
3689 FOREACH_AFI_SAFI (afi
, safi
) {
3690 filter
= &group
->conf
->filter
[afi
][safi
];
3692 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++) {
3693 if ((filter
->map
[direct
].name
)
3694 && (strcmp(rmap_name
,
3695 filter
->map
[direct
].name
)
3697 filter
->map
[direct
].map
= map
;
3700 if (filter
->usmap
.name
3701 && (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3702 filter
->usmap
.map
= map
;
3708 * Note that if an extreme number (tens of thousands) of route-maps are in use
3709 * and if bgp has an extreme number of peers, network statements, etc then this
3710 * function can consume a lot of cycles. This is due to this function being
3711 * called for each route-map and within this function we walk the list of peers,
3712 * network statements, etc looking to see if they use this route-map.
3714 static void bgp_route_map_process_update(struct bgp
*bgp
, const char *rmap_name
,
3722 struct bgp_dest
*bn
;
3723 struct bgp_static
*bgp_static
;
3724 struct bgp_aggregate
*aggregate
;
3725 struct listnode
*node
, *nnode
;
3726 struct route_map
*map
;
3727 char buf
[INET6_ADDRSTRLEN
];
3729 map
= route_map_lookup_by_name(rmap_name
);
3731 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
3733 /* Ignore dummy peer-group structure */
3734 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3737 FOREACH_AFI_SAFI (afi
, safi
) {
3738 /* process in/out/import/export/default-orig
3740 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
,
3741 safi
, route_update
);
3745 /* for outbound/default-orig route-maps, process for groups */
3746 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
3749 /* update peer-group config (template) */
3750 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
3752 FOREACH_AFI_SAFI (afi
, safi
) {
3753 /* For table route-map updates. */
3754 if (!bgp_fibupd_safi(safi
))
3757 if (bgp
->table_map
[afi
][safi
].name
3758 && (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
)
3761 /* bgp->table_map[afi][safi].map is NULL.
3762 * i.e Route map creation event.
3763 * So update applied_counter.
3764 * If it is not NULL, i.e It may be routemap updation or
3765 * deletion. so no need to update the counter.
3767 if (!bgp
->table_map
[afi
][safi
].map
)
3768 route_map_counter_increment(map
);
3769 bgp
->table_map
[afi
][safi
].map
= map
;
3771 if (BGP_DEBUG(zebra
, ZEBRA
))
3773 "Processing route_map %s(%s:%s) update on table map",
3774 rmap_name
, afi2str(afi
),
3777 bgp_zebra_announce_table(bgp
, afi
, safi
);
3780 /* For network route-map updates. */
3781 for (bn
= bgp_table_top(bgp
->route
[afi
][safi
]); bn
;
3782 bn
= bgp_route_next(bn
)) {
3783 bgp_static
= bgp_dest_get_bgp_static_info(bn
);
3787 if (!bgp_static
->rmap
.name
3788 || (strcmp(rmap_name
, bgp_static
->rmap
.name
) != 0))
3791 if (!bgp_static
->rmap
.map
)
3792 route_map_counter_increment(map
);
3794 bgp_static
->rmap
.map
= map
;
3796 if (route_update
&& !bgp_static
->backdoor
) {
3797 const struct prefix
*bn_p
=
3798 bgp_dest_get_prefix(bn
);
3800 if (bgp_debug_zebra(bn_p
))
3802 "Processing route_map %s(%s:%s) update on static route %s",
3803 rmap_name
, afi2str(afi
),
3805 inet_ntop(bn_p
->family
,
3806 &bn_p
->u
.prefix
, buf
,
3808 bgp_static_update(bgp
, bn_p
, bgp_static
, afi
,
3813 /* For aggregate-address route-map updates. */
3814 for (bn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); bn
;
3815 bn
= bgp_route_next(bn
)) {
3816 aggregate
= bgp_dest_get_bgp_aggregate_info(bn
);
3822 /* Update suppress map pointer. */
3823 if (aggregate
->suppress_map_name
3824 && strmatch(aggregate
->suppress_map_name
,
3826 if (aggregate
->rmap
.map
== NULL
)
3827 route_map_counter_increment(map
);
3829 aggregate
->suppress_map
= map
;
3831 bgp_aggregate_toggle_suppressed(
3832 aggregate
, bgp
, bgp_dest_get_prefix(bn
),
3838 if (aggregate
->rmap
.name
3839 && strmatch(rmap_name
, aggregate
->rmap
.name
)) {
3840 if (aggregate
->rmap
.map
== NULL
)
3841 route_map_counter_increment(map
);
3843 aggregate
->rmap
.map
= map
;
3848 if (matched
&& route_update
) {
3849 const struct prefix
*bn_p
=
3850 bgp_dest_get_prefix(bn
);
3852 if (bgp_debug_zebra(bn_p
))
3854 "Processing route_map %s(%s:%s) update on aggregate-address route %s",
3855 rmap_name
, afi2str(afi
),
3857 inet_ntop(bn_p
->family
,
3858 &bn_p
->u
.prefix
, buf
,
3860 bgp_aggregate_route(bgp
, bn_p
, afi
, safi
,
3866 /* For redistribute route-map updates. */
3867 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3868 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
3869 struct list
*red_list
;
3870 struct bgp_redist
*red
;
3872 red_list
= bgp
->redist
[afi
][i
];
3876 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
)) {
3878 || (strcmp(rmap_name
, red
->rmap
.name
) != 0))
3882 route_map_counter_increment(map
);
3884 red
->rmap
.map
= map
;
3889 if (BGP_DEBUG(zebra
, ZEBRA
))
3891 "Processing route_map %s(%s:%s) update on redistributed routes",
3892 rmap_name
, afi2str(afi
),
3895 bgp_redistribute_resend(bgp
, afi
, i
,
3900 /* for type5 command route-maps */
3901 FOREACH_AFI_SAFI (afi
, safi
) {
3902 if (!bgp
->adv_cmd_rmap
[afi
][safi
].name
3903 || strcmp(rmap_name
, bgp
->adv_cmd_rmap
[afi
][safi
].name
)
3907 /* Make sure the route-map is populated here if not already done */
3908 bgp
->adv_cmd_rmap
[afi
][safi
].map
= map
;
3910 if (BGP_DEBUG(zebra
, ZEBRA
))
3912 "Processing route_map %s(%s:%s) update on advertise type5 route command",
3913 rmap_name
, afi2str(afi
), safi2str(safi
));
3915 if (route_update
&& advertise_type5_routes(bgp
, afi
)) {
3916 bgp_evpn_withdraw_type5_routes(bgp
, afi
, safi
);
3917 bgp_evpn_advertise_type5_routes(bgp
, afi
, safi
);
3922 static void bgp_route_map_process_update_cb(char *rmap_name
)
3924 struct listnode
*node
, *nnode
;
3927 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
3928 bgp_route_map_process_update(bgp
, rmap_name
, 1);
3930 #ifdef ENABLE_BGP_VNC
3931 vnc_routemap_update(bgp
, __func__
);
3935 vpn_policy_routemap_event(rmap_name
);
3938 int bgp_route_map_update_timer(struct thread
*thread
)
3940 bm
->t_rmap_update
= NULL
;
3942 route_map_walk_update_list(bgp_route_map_process_update_cb
);
3947 static void bgp_route_map_mark_update(const char *rmap_name
)
3949 struct listnode
*node
, *nnode
;
3952 /* If new update is received before the current timer timed out,
3953 * turn it off and start a new timer.
3955 THREAD_OFF(bm
->t_rmap_update
);
3957 /* rmap_update_timer of 0 means don't do route updates */
3958 if (bm
->rmap_update_timer
) {
3959 thread_add_timer(bm
->master
, bgp_route_map_update_timer
,
3960 NULL
, bm
->rmap_update_timer
,
3961 &bm
->t_rmap_update
);
3963 /* Signal the groups that a route-map update event has
3965 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3966 update_group_policy_update(bgp
,
3967 BGP_POLICY_ROUTE_MAP
,
3970 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
3971 bgp_route_map_process_update(bgp
, rmap_name
, 0);
3972 #ifdef ENABLE_BGP_VNC
3973 vnc_routemap_update(bgp
, __func__
);
3977 vpn_policy_routemap_event(rmap_name
);
3981 static void bgp_route_map_add(const char *rmap_name
)
3983 if (route_map_mark_updated(rmap_name
) == 0)
3984 bgp_route_map_mark_update(rmap_name
);
3986 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3989 static void bgp_route_map_delete(const char *rmap_name
)
3991 if (route_map_mark_updated(rmap_name
) == 0)
3992 bgp_route_map_mark_update(rmap_name
);
3994 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
3997 static void bgp_route_map_event(const char *rmap_name
)
3999 if (route_map_mark_updated(rmap_name
) == 0)
4000 bgp_route_map_mark_update(rmap_name
);
4002 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
4005 DEFUN_YANG (match_mac_address
,
4006 match_mac_address_cmd
,
4007 "match mac address WORD",
4010 "Match address of route\n"
4011 "MAC Access-list name\n")
4014 "./match-condition[condition='frr-bgp-route-map:mac-address-list']";
4015 char xpath_value
[XPATH_MAXLEN
];
4017 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4018 snprintf(xpath_value
, sizeof(xpath_value
),
4019 "%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath
);
4020 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[3]->arg
);
4022 return nb_cli_apply_changes(vty
, NULL
);
4025 DEFUN_YANG (no_match_mac_address
,
4026 no_match_mac_address_cmd
,
4027 "no match mac address WORD",
4031 "Match address of route\n"
4032 "MAC acess-list name\n")
4035 "./match-condition[condition='frr-bgp-route-map:mac-address-list']";
4037 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4038 return nb_cli_apply_changes(vty
, NULL
);
4042 * Helper to handle the case of the user passing in a number or type string
4044 static const char *parse_evpn_rt_type(const char *num_rt_type
)
4046 switch (num_rt_type
[0]) {
4061 /* Was already full type string */
4065 DEFUN_YANG (match_evpn_route_type
,
4066 match_evpn_route_type_cmd
,
4067 "match evpn route-type <macip|2|multicast|3|prefix|5>",
4071 EVPN_TYPE_2_HELP_STR
4072 EVPN_TYPE_2_HELP_STR
4073 EVPN_TYPE_3_HELP_STR
4074 EVPN_TYPE_3_HELP_STR
4075 EVPN_TYPE_5_HELP_STR
4076 EVPN_TYPE_5_HELP_STR
)
4079 "./match-condition[condition='frr-bgp-route-map:evpn-route-type']";
4080 char xpath_value
[XPATH_MAXLEN
];
4082 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4083 snprintf(xpath_value
, sizeof(xpath_value
),
4084 "%s/rmap-match-condition/frr-bgp-route-map:evpn-route-type",
4086 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4087 parse_evpn_rt_type(argv
[3]->arg
));
4089 return nb_cli_apply_changes(vty
, NULL
);
4092 DEFUN_YANG (no_match_evpn_route_type
,
4093 no_match_evpn_route_type_cmd
,
4094 "no match evpn route-type <macip|2|multicast|3|prefix|5>",
4099 EVPN_TYPE_2_HELP_STR
4100 EVPN_TYPE_2_HELP_STR
4101 EVPN_TYPE_3_HELP_STR
4102 EVPN_TYPE_3_HELP_STR
4103 EVPN_TYPE_5_HELP_STR
4104 EVPN_TYPE_5_HELP_STR
)
4107 "./match-condition[condition='frr-bgp-route-map:evpn-route-type']";
4109 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4111 return nb_cli_apply_changes(vty
, NULL
);
4115 DEFUN_YANG (match_evpn_vni
,
4117 "match evpn vni " CMD_VNI_RANGE
,
4124 "./match-condition[condition='frr-bgp-route-map:evpn-vni']";
4125 char xpath_value
[XPATH_MAXLEN
];
4127 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4128 snprintf(xpath_value
, sizeof(xpath_value
),
4129 "%s/rmap-match-condition/frr-bgp-route-map:evpn-vni", xpath
);
4130 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[3]->arg
);
4132 return nb_cli_apply_changes(vty
, NULL
);
4135 DEFUN_YANG (no_match_evpn_vni
,
4136 no_match_evpn_vni_cmd
,
4137 "no match evpn vni " CMD_VNI_RANGE
,
4145 "./match-condition[condition='frr-bgp-route-map:evpn-vni']";
4146 char xpath_value
[XPATH_MAXLEN
];
4148 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4149 snprintf(xpath_value
, sizeof(xpath_value
),
4150 "%s/rmap-match-condition/frr-bgp-route-map:evpn-vni", xpath
);
4151 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, argv
[3]->arg
);
4153 return nb_cli_apply_changes(vty
, NULL
);
4156 DEFUN_YANG (match_evpn_default_route
,
4157 match_evpn_default_route_cmd
,
4158 "match evpn default-route",
4161 "default EVPN type-5 route\n")
4164 "./match-condition[condition='frr-bgp-route-map:evpn-default-route']";
4165 char xpath_value
[XPATH_MAXLEN
];
4167 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4169 snprintf(xpath_value
, sizeof(xpath_value
),
4170 "%s/rmap-match-condition/frr-bgp-route-map:evpn-default-route",
4172 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, NULL
);
4174 return nb_cli_apply_changes(vty
, NULL
);
4177 DEFUN_YANG (no_match_evpn_default_route
,
4178 no_match_evpn_default_route_cmd
,
4179 "no match evpn default-route",
4183 "default EVPN type-5 route\n")
4186 "./match-condition[condition='frr-bgp-route-map:evpn-default-route']";
4188 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4190 return nb_cli_apply_changes(vty
, NULL
);
4193 DEFUN_YANG (match_evpn_rd
,
4195 "match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
4198 "Route Distinguisher\n"
4199 "ASN:XX or A.B.C.D:XX\n")
4202 "./match-condition[condition='frr-bgp-route-map:evpn-rd']";
4203 char xpath_value
[XPATH_MAXLEN
];
4205 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4207 xpath_value
, sizeof(xpath_value
),
4208 "%s/rmap-match-condition/frr-bgp-route-map:route-distinguisher",
4210 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[3]->arg
);
4212 return nb_cli_apply_changes(vty
, NULL
);
4215 DEFUN_YANG (no_match_evpn_rd
,
4216 no_match_evpn_rd_cmd
,
4217 "no match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
4221 "Route Distinguisher\n"
4222 "ASN:XX or A.B.C.D:XX\n")
4225 "./match-condition[condition='frr-bgp-route-map:evpn-rd']";
4227 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4228 return nb_cli_apply_changes(vty
, NULL
);
4231 DEFUN_YANG (set_evpn_gw_ip_ipv4
,
4232 set_evpn_gw_ip_ipv4_cmd
,
4233 "set evpn gateway-ip ipv4 A.B.C.D",
4236 "Set gateway IP for prefix advertisement route\n"
4238 "Gateway IP address in IPv4 format\n")
4243 "./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv4']";
4244 char xpath_value
[XPATH_MAXLEN
];
4246 ret
= str2sockunion(argv
[4]->arg
, &su
);
4248 vty_out(vty
, "%% Malformed gateway IP\n");
4249 return CMD_WARNING_CONFIG_FAILED
;
4252 if (su
.sin
.sin_addr
.s_addr
== 0
4253 || IPV4_CLASS_DE(ntohl(su
.sin
.sin_addr
.s_addr
))) {
4255 "%% Gateway IP cannot be 0.0.0.0, multicast or reserved\n");
4256 return CMD_WARNING_CONFIG_FAILED
;
4259 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4261 snprintf(xpath_value
, sizeof(xpath_value
),
4262 "%s/rmap-set-action/frr-bgp-route-map:evpn-gateway-ip-ipv4",
4265 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[4]->arg
);
4266 return nb_cli_apply_changes(vty
, NULL
);
4269 DEFUN_YANG (no_set_evpn_gw_ip_ipv4
,
4270 no_set_evpn_gw_ip_ipv4_cmd
,
4271 "no set evpn gateway-ip ipv4 A.B.C.D",
4275 "Set gateway IP for prefix advertisement route\n"
4277 "Gateway IP address in IPv4 format\n")
4282 "./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv4']";
4284 ret
= str2sockunion(argv
[5]->arg
, &su
);
4286 vty_out(vty
, "%% Malformed gateway IP\n");
4287 return CMD_WARNING_CONFIG_FAILED
;
4290 if (su
.sin
.sin_addr
.s_addr
== 0
4291 || IPV4_CLASS_DE(ntohl(su
.sin
.sin_addr
.s_addr
))) {
4293 "%% Gateway IP cannot be 0.0.0.0, multicast or reserved\n");
4294 return CMD_WARNING_CONFIG_FAILED
;
4297 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4299 return nb_cli_apply_changes(vty
, NULL
);
4302 DEFUN_YANG (set_evpn_gw_ip_ipv6
,
4303 set_evpn_gw_ip_ipv6_cmd
,
4304 "set evpn gateway-ip ipv6 X:X::X:X",
4307 "Set gateway IP for prefix advertisement route\n"
4309 "Gateway IP address in IPv6 format\n")
4314 "./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv6']";
4315 char xpath_value
[XPATH_MAXLEN
];
4317 ret
= str2sockunion(argv
[4]->arg
, &su
);
4319 vty_out(vty
, "%% Malformed gateway IP\n");
4320 return CMD_WARNING_CONFIG_FAILED
;
4323 if (IN6_IS_ADDR_LINKLOCAL(&su
.sin6
.sin6_addr
)
4324 || IN6_IS_ADDR_MULTICAST(&su
.sin6
.sin6_addr
)) {
4326 "%% Gateway IP cannot be a linklocal or multicast address\n");
4327 return CMD_WARNING_CONFIG_FAILED
;
4330 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4332 snprintf(xpath_value
, sizeof(xpath_value
),
4333 "%s/rmap-set-action/frr-bgp-route-map:evpn-gateway-ip-ipv6",
4336 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[4]->arg
);
4337 return nb_cli_apply_changes(vty
, NULL
);
4340 DEFUN_YANG (no_set_evpn_gw_ip_ipv6
,
4341 no_set_evpn_gw_ip_ipv6_cmd
,
4342 "no set evpn gateway-ip ipv6 X:X::X:X",
4346 "Set gateway IP for prefix advertisement route\n"
4348 "Gateway IP address in IPv4 format\n")
4353 "./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv6']";
4355 ret
= str2sockunion(argv
[5]->arg
, &su
);
4357 vty_out(vty
, "%% Malformed gateway IP\n");
4358 return CMD_WARNING_CONFIG_FAILED
;
4361 if (IN6_IS_ADDR_LINKLOCAL(&su
.sin6
.sin6_addr
)
4362 || IN6_IS_ADDR_MULTICAST(&su
.sin6
.sin6_addr
)) {
4364 "%% Gateway IP cannot be a linklocal or multicast address\n");
4365 return CMD_WARNING_CONFIG_FAILED
;
4368 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4370 return nb_cli_apply_changes(vty
, NULL
);
4373 DEFPY_YANG(match_vrl_source_vrf
,
4374 match_vrl_source_vrf_cmd
,
4375 "match source-vrf NAME$vrf_name",
4381 "./match-condition[condition='frr-bgp-route-map:source-vrf']";
4382 char xpath_value
[XPATH_MAXLEN
];
4384 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4385 snprintf(xpath_value
, sizeof(xpath_value
),
4386 "%s/rmap-match-condition/frr-bgp-route-map:source-vrf", xpath
);
4387 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, vrf_name
);
4389 return nb_cli_apply_changes(vty
, NULL
);
4392 DEFPY_YANG(no_match_vrl_source_vrf
,
4393 no_match_vrl_source_vrf_cmd
,
4394 "no match source-vrf NAME$vrf_name",
4400 "./match-condition[condition='frr-bgp-route-map:source-vrf']";
4402 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4403 return nb_cli_apply_changes(vty
, NULL
);
4406 DEFPY_YANG (match_peer
,
4408 "match peer <A.B.C.D$addrv4|X:X::X:X$addrv6|WORD$intf>",
4410 "Match peer address\n"
4411 "IP address of peer\n"
4412 "IPv6 address of peer\n"
4413 "Interface name of peer\n")
4416 "./match-condition[condition='frr-bgp-route-map:peer']";
4417 char xpath_value
[XPATH_MAXLEN
];
4419 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4423 xpath_value
, sizeof(xpath_value
),
4424 "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address",
4426 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4428 } else if (addrv6_str
) {
4430 xpath_value
, sizeof(xpath_value
),
4431 "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address",
4433 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4437 xpath_value
, sizeof(xpath_value
),
4438 "%s/rmap-match-condition/frr-bgp-route-map:peer-interface",
4440 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, intf
);
4443 return nb_cli_apply_changes(vty
, NULL
);
4446 DEFUN_YANG (match_peer_local
,
4447 match_peer_local_cmd
,
4450 "Match peer address\n"
4451 "Static or Redistributed routes\n")
4454 "./match-condition[condition='frr-bgp-route-map:peer']";
4455 char xpath_value
[XPATH_MAXLEN
];
4457 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4459 snprintf(xpath_value
, sizeof(xpath_value
),
4460 "%s/rmap-match-condition/frr-bgp-route-map:peer-local", xpath
);
4461 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, "true");
4463 return nb_cli_apply_changes(vty
, NULL
);
4466 DEFUN_YANG (no_match_peer
,
4468 "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
4471 "Match peer address\n"
4472 "Static or Redistributed routes\n"
4473 "IP address of peer\n"
4474 "IPv6 address of peer\n"
4475 "Interface name of peer\n")
4478 "./match-condition[condition='frr-bgp-route-map:peer']";
4480 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4482 return nb_cli_apply_changes(vty
, NULL
);
4485 #ifdef HAVE_SCRIPTING
4486 DEFUN_YANG (match_script
,
4488 "[no] match script WORD",
4491 "Execute script to determine match\n"
4492 "The script name to run, without .lua; e.g. 'myroutemap' to run myroutemap.lua\n")
4494 bool no
= strmatch(argv
[0]->text
, "no");
4496 argv_find(argv
, argc
, "WORD", &i
);
4497 const char *script
= argv
[i
]->arg
;
4499 "./match-condition[condition='frr-bgp-route-map:match-script']";
4500 char xpath_value
[XPATH_MAXLEN
];
4503 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4504 snprintf(xpath_value
, sizeof(xpath_value
),
4505 "%s/rmap-match-condition/frr-bgp-route-map:script",
4507 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
,
4510 return nb_cli_apply_changes(vty
, NULL
);
4513 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4514 snprintf(xpath_value
, sizeof(xpath_value
),
4515 "%s/rmap-match-condition/frr-bgp-route-map:script",
4517 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4520 return nb_cli_apply_changes(vty
, NULL
);
4522 #endif /* HAVE_SCRIPTING */
4524 /* match probability */
4525 DEFUN_YANG (match_probability
,
4526 match_probability_cmd
,
4527 "match probability (0-100)",
4529 "Match portion of routes defined by percentage value\n"
4530 "Percentage of routes\n")
4535 "./match-condition[condition='frr-bgp-route-map:probability']";
4536 char xpath_value
[XPATH_MAXLEN
];
4538 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4539 snprintf(xpath_value
, sizeof(xpath_value
),
4540 "%s/rmap-match-condition/frr-bgp-route-map:probability",
4542 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4543 argv
[idx_number
]->arg
);
4545 return nb_cli_apply_changes(vty
, NULL
);
4549 DEFUN_YANG (no_match_probability
,
4550 no_match_probability_cmd
,
4551 "no match probability [(1-99)]",
4554 "Match portion of routes defined by percentage value\n"
4555 "Percentage of routes\n")
4559 "./match-condition[condition='frr-bgp-route-map:probability']";
4560 char xpath_value
[XPATH_MAXLEN
];
4562 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4564 if (argc
<= idx_number
)
4565 return nb_cli_apply_changes(vty
, NULL
);
4567 snprintf(xpath_value
, sizeof(xpath_value
),
4568 "%s/rmap-match-condition/frr-bgp-route-map:probability",
4570 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
,
4571 argv
[idx_number
]->arg
);
4573 return nb_cli_apply_changes(vty
, NULL
);
4577 DEFPY_YANG (match_ip_route_source
,
4578 match_ip_route_source_cmd
,
4579 "match ip route-source WORD",
4582 "Match advertising source address of route\n"
4583 "IP Access-list name\n")
4586 "./match-condition[condition='frr-bgp-route-map:ip-route-source']";
4587 char xpath_value
[XPATH_MAXLEN
+ 32];
4590 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4591 snprintf(xpath_value
, sizeof(xpath_value
),
4592 "%s/rmap-match-condition/frr-bgp-route-map:list-name",
4594 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4595 argv
[idx_acl
]->arg
);
4597 return nb_cli_apply_changes(vty
, NULL
);
4601 DEFUN_YANG (no_match_ip_route_source
,
4602 no_match_ip_route_source_cmd
,
4603 "no match ip route-source [WORD]",
4607 "Match advertising source address of route\n"
4608 "IP Access-list name\n")
4611 "./match-condition[condition='frr-bgp-route-map:ip-route-source']";
4613 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4614 return nb_cli_apply_changes(vty
, NULL
);
4617 DEFUN_YANG (match_ip_route_source_prefix_list
,
4618 match_ip_route_source_prefix_list_cmd
,
4619 "match ip route-source prefix-list WORD",
4622 "Match advertising source address of route\n"
4623 "Match entries of prefix-lists\n"
4624 "IP prefix-list name\n")
4628 "./match-condition[condition='frr-bgp-route-map:ip-route-source-prefix-list']";
4629 char xpath_value
[XPATH_MAXLEN
+ 32];
4631 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4632 snprintf(xpath_value
, sizeof(xpath_value
),
4633 "%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath
);
4634 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4635 argv
[idx_word
]->arg
);
4637 return nb_cli_apply_changes(vty
, NULL
);
4641 DEFUN_YANG (no_match_ip_route_source_prefix_list
,
4642 no_match_ip_route_source_prefix_list_cmd
,
4643 "no match ip route-source prefix-list [WORD]",
4647 "Match advertising source address of route\n"
4648 "Match entries of prefix-lists\n"
4649 "IP prefix-list name\n")
4652 "./match-condition[condition='frr-bgp-route-map:ip-route-source-prefix-list']";
4654 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4655 return nb_cli_apply_changes(vty
, NULL
);
4658 DEFUN_YANG (match_local_pref
,
4659 match_local_pref_cmd
,
4660 "match local-preference (0-4294967295)",
4662 "Match local-preference of route\n"
4668 "./match-condition[condition='frr-bgp-route-map:match-local-preference']";
4669 char xpath_value
[XPATH_MAXLEN
];
4671 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4672 snprintf(xpath_value
, sizeof(xpath_value
),
4673 "%s/rmap-match-condition/frr-bgp-route-map:local-preference",
4675 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4676 argv
[idx_number
]->arg
);
4678 return nb_cli_apply_changes(vty
, NULL
);
4682 DEFUN_YANG (no_match_local_pref
,
4683 no_match_local_pref_cmd
,
4684 "no match local-preference [(0-4294967295)]",
4687 "Match local preference of route\n"
4688 "Local preference value\n")
4690 int idx_localpref
= 3;
4692 "./match-condition[condition='frr-bgp-route-map:match-local-preference']";
4693 char xpath_value
[XPATH_MAXLEN
];
4695 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4697 if (argc
<= idx_localpref
)
4698 return nb_cli_apply_changes(vty
, NULL
);
4700 snprintf(xpath_value
, sizeof(xpath_value
),
4701 "%s/rmap-match-condition/frr-bgp-route-map:local-preference",
4703 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
,
4704 argv
[idx_localpref
]->arg
);
4706 return nb_cli_apply_changes(vty
, NULL
);
4709 DEFUN_YANG(match_alias
, match_alias_cmd
, "match alias ALIAS_NAME",
4711 "Match BGP community alias name\n"
4712 "BGP community alias name\n")
4714 const char *alias
= argv
[2]->arg
;
4715 struct community_alias ca1
;
4716 struct community_alias
*lookup_alias
;
4719 "./match-condition[condition='frr-bgp-route-map:match-alias']";
4720 char xpath_value
[XPATH_MAXLEN
];
4722 memset(&ca1
, 0, sizeof(ca1
));
4723 strlcpy(ca1
.alias
, alias
, sizeof(ca1
.alias
));
4724 lookup_alias
= bgp_ca_alias_lookup(&ca1
);
4725 if (!lookup_alias
) {
4726 vty_out(vty
, "%% BGP alias name '%s' does not exist\n", alias
);
4727 return CMD_WARNING_CONFIG_FAILED
;
4730 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4731 snprintf(xpath_value
, sizeof(xpath_value
),
4732 "%s/rmap-match-condition/frr-bgp-route-map:alias", xpath
);
4733 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, alias
);
4735 return nb_cli_apply_changes(vty
, NULL
);
4739 DEFUN_YANG(no_match_alias
, no_match_alias_cmd
, "no match alias [ALIAS_NAME]",
4741 "Match BGP community alias name\n"
4742 "BGP community alias name\n")
4746 "./match-condition[condition='frr-bgp-route-map:match-alias']";
4747 char xpath_value
[XPATH_MAXLEN
];
4749 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4751 if (argc
<= idx_alias
)
4752 return nb_cli_apply_changes(vty
, NULL
);
4754 snprintf(xpath_value
, sizeof(xpath_value
),
4755 "%s/rmap-match-condition/frr-bgp-route-map:alias", xpath
);
4756 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
,
4757 argv
[idx_alias
]->arg
);
4759 return nb_cli_apply_changes(vty
, NULL
);
4762 DEFPY_YANG (match_community
,
4763 match_community_cmd
,
4764 "match community <(1-99)|(100-500)|COMMUNITY_LIST_NAME> [exact-match]",
4766 "Match BGP community list\n"
4767 "Community-list number (standard)\n"
4768 "Community-list number (expanded)\n"
4769 "Community-list name\n"
4770 "Do exact matching of communities\n")
4773 "./match-condition[condition='frr-bgp-route-map:match-community']";
4774 char xpath_value
[XPATH_MAXLEN
];
4775 char xpath_match
[XPATH_MAXLEN
];
4776 int idx_comm_list
= 2;
4778 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4781 xpath_value
, sizeof(xpath_value
),
4782 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
4784 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[idx_comm_list
]->arg
);
4788 xpath_match
, sizeof(xpath_match
),
4789 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
4791 nb_cli_enqueue_change(vty
, xpath_match
, NB_OP_MODIFY
,
4795 xpath_match
, sizeof(xpath_match
),
4796 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
4798 nb_cli_enqueue_change(vty
, xpath_match
, NB_OP_MODIFY
,
4802 return nb_cli_apply_changes(vty
, NULL
);
4805 DEFUN_YANG (no_match_community
,
4806 no_match_community_cmd
,
4807 "no match community [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> [exact-match]]",
4810 "Match BGP community list\n"
4811 "Community-list number (standard)\n"
4812 "Community-list number (expanded)\n"
4813 "Community-list name\n"
4814 "Do exact matching of communities\n")
4817 "./match-condition[condition='frr-bgp-route-map:match-community']";
4819 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4820 return nb_cli_apply_changes(vty
, NULL
);
4823 DEFPY_YANG (match_lcommunity
,
4824 match_lcommunity_cmd
,
4825 "match large-community <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [exact-match]",
4827 "Match BGP large community list\n"
4828 "Large Community-list number (standard)\n"
4829 "Large Community-list number (expanded)\n"
4830 "Large Community-list name\n"
4831 "Do exact matching of communities\n")
4834 "./match-condition[condition='frr-bgp-route-map:match-large-community']";
4835 char xpath_value
[XPATH_MAXLEN
];
4836 char xpath_match
[XPATH_MAXLEN
];
4837 int idx_lcomm_list
= 2;
4839 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4842 xpath_value
, sizeof(xpath_value
),
4843 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
4845 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[idx_lcomm_list
]->arg
);
4849 xpath_match
, sizeof(xpath_match
),
4850 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
4852 nb_cli_enqueue_change(vty
, xpath_match
, NB_OP_MODIFY
,
4856 xpath_match
, sizeof(xpath_match
),
4857 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
4859 nb_cli_enqueue_change(vty
, xpath_match
, NB_OP_MODIFY
,
4863 return nb_cli_apply_changes(vty
, NULL
);
4866 DEFUN_YANG (no_match_lcommunity
,
4867 no_match_lcommunity_cmd
,
4868 "no match large-community [<(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [exact-match]]",
4871 "Match BGP large community list\n"
4872 "Large Community-list number (standard)\n"
4873 "Large Community-list number (expanded)\n"
4874 "Large Community-list name\n"
4875 "Do exact matching of communities\n")
4878 "./match-condition[condition='frr-bgp-route-map:match-large-community']";
4880 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4881 return nb_cli_apply_changes(vty
, NULL
);
4884 DEFPY_YANG (match_ecommunity
,
4885 match_ecommunity_cmd
,
4886 "match extcommunity <(1-99)|(100-500)|EXTCOMMUNITY_LIST_NAME>",
4888 "Match BGP/VPN extended community list\n"
4889 "Extended community-list number (standard)\n"
4890 "Extended community-list number (expanded)\n"
4891 "Extended community-list name\n")
4894 "./match-condition[condition='frr-bgp-route-map:match-extcommunity']";
4895 char xpath_value
[XPATH_MAXLEN
];
4896 int idx_comm_list
= 2;
4898 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4901 xpath_value
, sizeof(xpath_value
),
4902 "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
4904 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[idx_comm_list
]->arg
);
4906 return nb_cli_apply_changes(vty
, NULL
);
4910 DEFUN_YANG (no_match_ecommunity
,
4911 no_match_ecommunity_cmd
,
4912 "no match extcommunity [<(1-99)|(100-500)|EXTCOMMUNITY_LIST_NAME>]",
4915 "Match BGP/VPN extended community list\n"
4916 "Extended community-list number (standard)\n"
4917 "Extended community-list number (expanded)\n"
4918 "Extended community-list name\n")
4921 "./match-condition[condition='frr-bgp-route-map:match-extcommunity']";
4923 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4924 return nb_cli_apply_changes(vty
, NULL
);
4928 DEFUN_YANG (match_aspath
,
4930 "match as-path AS_PATH_FILTER_NAME",
4932 "Match BGP AS path list\n"
4933 "AS path access-list name\n")
4938 "./match-condition[condition='frr-bgp-route-map:as-path-list']";
4939 char xpath_value
[XPATH_MAXLEN
];
4941 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4942 snprintf(xpath_value
, sizeof(xpath_value
),
4943 "%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath
);
4944 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
4945 argv
[idx_word
]->arg
);
4947 return nb_cli_apply_changes(vty
, NULL
);
4951 DEFUN_YANG (no_match_aspath
,
4952 no_match_aspath_cmd
,
4953 "no match as-path [AS_PATH_FILTER_NAME]",
4956 "Match BGP AS path list\n"
4957 "AS path access-list name\n")
4960 "./match-condition[condition='frr-bgp-route-map:as-path-list']";
4962 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
4964 return nb_cli_apply_changes(vty
, NULL
);
4967 DEFUN_YANG (match_origin
,
4969 "match origin <egp|igp|incomplete>",
4974 "unknown heritage\n")
4977 const char *origin_type
;
4979 "./match-condition[condition='frr-bgp-route-map:match-origin']";
4980 char xpath_value
[XPATH_MAXLEN
];
4982 if (strncmp(argv
[idx_origin
]->arg
, "igp", 2) == 0)
4983 origin_type
= "igp";
4984 else if (strncmp(argv
[idx_origin
]->arg
, "egp", 1) == 0)
4985 origin_type
= "egp";
4986 else if (strncmp(argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
4987 origin_type
= "incomplete";
4989 vty_out(vty
, "%% Invalid match origin type\n");
4990 return CMD_WARNING_CONFIG_FAILED
;
4993 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
4994 snprintf(xpath_value
, sizeof(xpath_value
),
4995 "%s/rmap-match-condition/frr-bgp-route-map:origin", xpath
);
4996 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, origin_type
);
4998 return nb_cli_apply_changes(vty
, NULL
);
5002 DEFUN_YANG (no_match_origin
,
5003 no_match_origin_cmd
,
5004 "no match origin [<egp|igp|incomplete>]",
5010 "unknown heritage\n")
5013 "./match-condition[condition='frr-bgp-route-map:match-origin']";
5014 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5015 return nb_cli_apply_changes(vty
, NULL
);
5018 DEFUN_YANG (set_table_id
,
5020 "set table (1-4294967295)",
5022 "export route to non-main kernel table\n"
5023 "Kernel routing table id\n")
5026 const char *xpath
= "./set-action[action='frr-bgp-route-map:table']";
5027 char xpath_value
[XPATH_MAXLEN
];
5029 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5030 snprintf(xpath_value
, sizeof(xpath_value
),
5031 "%s/rmap-set-action/frr-bgp-route-map:table", xpath
);
5032 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5033 argv
[idx_number
]->arg
);
5034 return nb_cli_apply_changes(vty
, NULL
);
5037 DEFUN_YANG (no_set_table_id
,
5038 no_set_table_id_cmd
,
5042 "export route to non-main kernel table\n")
5044 const char *xpath
= "./set-action[action='frr-bgp-route-map:table']";
5045 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5046 return nb_cli_apply_changes(vty
, NULL
);
5049 DEFUN_YANG (set_ip_nexthop_peer
,
5050 set_ip_nexthop_peer_cmd
,
5051 "[no] set ip next-hop peer-address",
5055 "Next hop address\n"
5056 "Use peer address (for BGP only)\n")
5058 char xpath_value
[XPATH_MAXLEN
];
5060 "./set-action[action='frr-bgp-route-map:set-ipv4-nexthop']";
5062 if (strmatch(argv
[0]->text
, "no"))
5063 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5065 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5066 snprintf(xpath_value
, sizeof(xpath_value
),
5067 "%s/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
5069 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5072 return nb_cli_apply_changes(vty
, NULL
);
5075 DEFUN_YANG (set_ip_nexthop_unchanged
,
5076 set_ip_nexthop_unchanged_cmd
,
5077 "[no] set ip next-hop unchanged",
5081 "Next hop address\n"
5082 "Don't modify existing Next hop address\n")
5084 char xpath_value
[XPATH_MAXLEN
];
5086 "./set-action[action='frr-bgp-route-map:set-ipv4-nexthop']";
5088 if (strmatch(argv
[0]->text
, "no"))
5089 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5091 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5092 snprintf(xpath_value
, sizeof(xpath_value
),
5093 "%s/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
5095 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5098 return nb_cli_apply_changes(vty
, NULL
);
5101 DEFUN_YANG (set_distance
,
5103 "set distance (0-255)",
5105 "BGP Administrative Distance to use\n"
5109 const char *xpath
= "./set-action[action='frr-bgp-route-map:distance']";
5110 char xpath_value
[XPATH_MAXLEN
];
5112 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5113 snprintf(xpath_value
, sizeof(xpath_value
),
5114 "%s/rmap-set-action/frr-bgp-route-map:distance", xpath
);
5115 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5116 argv
[idx_number
]->arg
);
5117 return nb_cli_apply_changes(vty
, NULL
);
5120 DEFUN_YANG (no_set_distance
,
5121 no_set_distance_cmd
,
5122 "no set distance [(0-255)]",
5124 "BGP Administrative Distance to use\n"
5127 const char *xpath
= "./set-action[action='frr-bgp-route-map:distance']";
5129 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5130 return nb_cli_apply_changes(vty
, NULL
);
5133 DEFUN_YANG (set_local_pref
,
5135 "set local-preference WORD",
5137 "BGP local preference path attribute\n"
5138 "Preference value (0-4294967295)\n")
5142 "./set-action[action='frr-bgp-route-map:set-local-preference']";
5143 char xpath_value
[XPATH_MAXLEN
];
5145 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5146 snprintf(xpath_value
, sizeof(xpath_value
),
5147 "%s/rmap-set-action/frr-bgp-route-map:local-pref", xpath
);
5148 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5149 argv
[idx_number
]->arg
);
5150 return nb_cli_apply_changes(vty
, NULL
);
5153 DEFUN_YANG (no_set_local_pref
,
5154 no_set_local_pref_cmd
,
5155 "no set local-preference [WORD]",
5158 "BGP local preference path attribute\n"
5159 "Preference value (0-4294967295)\n")
5162 "./set-action[action='frr-bgp-route-map:set-local-preference']";
5164 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5165 return nb_cli_apply_changes(vty
, NULL
);
5168 DEFUN_YANG (set_weight
,
5170 "set weight (0-4294967295)",
5172 "BGP weight for routing table\n"
5176 const char *xpath
= "./set-action[action='frr-bgp-route-map:weight']";
5177 char xpath_value
[XPATH_MAXLEN
];
5179 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5180 snprintf(xpath_value
, sizeof(xpath_value
),
5181 "%s/rmap-set-action/frr-bgp-route-map:weight", xpath
);
5182 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5183 argv
[idx_number
]->arg
);
5184 return nb_cli_apply_changes(vty
, NULL
);
5187 DEFUN_YANG (no_set_weight
,
5189 "no set weight [(0-4294967295)]",
5192 "BGP weight for routing table\n"
5195 const char *xpath
= "./set-action[action='frr-bgp-route-map:weight']";
5197 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5198 return nb_cli_apply_changes(vty
, NULL
);
5201 DEFUN_YANG (set_label_index
,
5202 set_label_index_cmd
,
5203 "set label-index (0-1048560)",
5205 "Label index to associate with the prefix\n"
5206 "Label index value\n")
5210 "./set-action[action='frr-bgp-route-map:label-index']";
5211 char xpath_value
[XPATH_MAXLEN
];
5213 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5214 snprintf(xpath_value
, sizeof(xpath_value
),
5215 "%s/rmap-set-action/frr-bgp-route-map:label-index", xpath
);
5216 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5217 argv
[idx_number
]->arg
);
5218 return nb_cli_apply_changes(vty
, NULL
);
5221 DEFUN_YANG (no_set_label_index
,
5222 no_set_label_index_cmd
,
5223 "no set label-index [(0-1048560)]",
5226 "Label index to associate with the prefix\n"
5227 "Label index value\n")
5230 "./set-action[action='frr-bgp-route-map:label-index']";
5232 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5233 return nb_cli_apply_changes(vty
, NULL
);
5236 DEFUN_YANG (set_aspath_prepend_asn
,
5237 set_aspath_prepend_asn_cmd
,
5238 "set as-path prepend (1-4294967295)...",
5240 "Transform BGP AS_PATH attribute\n"
5241 "Prepend to the as-path\n"
5248 str
= argv_concat(argv
, argc
, idx_asn
);
5251 "./set-action[action='frr-bgp-route-map:as-path-prepend']";
5252 char xpath_value
[XPATH_MAXLEN
];
5254 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5255 snprintf(xpath_value
, sizeof(xpath_value
),
5256 "%s/rmap-set-action/frr-bgp-route-map:prepend-as-path", xpath
);
5257 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, str
);
5258 ret
= nb_cli_apply_changes(vty
, NULL
);
5259 XFREE(MTYPE_TMP
, str
);
5263 DEFUN_YANG (set_aspath_prepend_lastas
,
5264 set_aspath_prepend_lastas_cmd
,
5265 "set as-path prepend last-as (1-10)",
5267 "Transform BGP AS_PATH attribute\n"
5268 "Prepend to the as-path\n"
5269 "Use the last AS-number in the as-path\n"
5270 "Number of times to insert\n")
5275 "./set-action[action='frr-bgp-route-map:as-path-prepend']";
5276 char xpath_value
[XPATH_MAXLEN
];
5278 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5279 snprintf(xpath_value
, sizeof(xpath_value
),
5280 "%s/rmap-set-action/frr-bgp-route-map:last-as", xpath
);
5281 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5282 argv
[idx_num
]->arg
);
5283 return nb_cli_apply_changes(vty
, NULL
);
5286 DEFUN_YANG (no_set_aspath_prepend
,
5287 no_set_aspath_prepend_cmd
,
5288 "no set as-path prepend [(1-4294967295)]",
5291 "Transform BGP AS_PATH attribute\n"
5292 "Prepend to the as-path\n"
5296 "./set-action[action='frr-bgp-route-map:as-path-prepend']";
5298 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5299 return nb_cli_apply_changes(vty
, NULL
);
5302 DEFUN_YANG (no_set_aspath_prepend_lastas
,
5303 no_set_aspath_prepend_lastas_cmd
,
5304 "no set as-path prepend last-as [(1-10)]",
5307 "Transform BGP AS_PATH attribute\n"
5308 "Prepend to the as-path\n"
5309 "Use the peers AS-number\n"
5310 "Number of times to insert\n")
5313 "./set-action[action='frr-bgp-route-map:as-path-prepend']";
5315 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5316 return nb_cli_apply_changes(vty
, NULL
);
5319 DEFUN_YANG (set_aspath_exclude
,
5320 set_aspath_exclude_cmd
,
5321 "set as-path exclude (1-4294967295)...",
5323 "Transform BGP AS-path attribute\n"
5324 "Exclude from the as-path\n"
5331 str
= argv_concat(argv
, argc
, idx_asn
);
5334 "./set-action[action='frr-bgp-route-map:as-path-exclude']";
5335 char xpath_value
[XPATH_MAXLEN
];
5337 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5338 snprintf(xpath_value
, sizeof(xpath_value
),
5339 "%s/rmap-set-action/frr-bgp-route-map:exclude-as-path", xpath
);
5340 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, str
);
5341 ret
= nb_cli_apply_changes(vty
, NULL
);
5342 XFREE(MTYPE_TMP
, str
);
5346 DEFUN_YANG (no_set_aspath_exclude
,
5347 no_set_aspath_exclude_cmd
,
5348 "no set as-path exclude (1-4294967295)...",
5351 "Transform BGP AS_PATH attribute\n"
5352 "Exclude from the as-path\n"
5356 "./set-action[action='frr-bgp-route-map:as-path-exclude']";
5358 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5359 return nb_cli_apply_changes(vty
, NULL
);
5362 ALIAS_YANG (no_set_aspath_exclude
, no_set_aspath_exclude_all_cmd
,
5363 "no set as-path exclude",
5365 "Transform BGP AS_PATH attribute\n"
5366 "Exclude from the as-path\n")
5368 DEFUN_YANG (set_community
,
5370 "set community AA:NN...",
5372 "BGP community attribute\n"
5380 struct community
*com
= NULL
;
5382 char *argstr
= NULL
;
5386 "./set-action[action='frr-bgp-route-map:set-community']";
5387 char xpath_value
[XPATH_MAXLEN
];
5389 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5390 snprintf(xpath_value
, sizeof(xpath_value
),
5391 "%s/rmap-set-action/frr-bgp-route-map:community-string",
5394 b
= buffer_new(1024);
5396 for (i
= idx_aa_nn
; i
< argc
; i
++) {
5397 if (strncmp(argv
[i
]->arg
, "additive", strlen(argv
[i
]->arg
))
5404 buffer_putc(b
, ' ');
5408 if (strncmp(argv
[i
]->arg
, "internet", strlen(argv
[i
]->arg
))
5410 buffer_putstr(b
, "internet");
5413 if (strncmp(argv
[i
]->arg
, "local-AS", strlen(argv
[i
]->arg
))
5415 buffer_putstr(b
, "local-AS");
5418 if (strncmp(argv
[i
]->arg
, "no-a", strlen("no-a")) == 0
5419 && strncmp(argv
[i
]->arg
, "no-advertise",
5420 strlen(argv
[i
]->arg
))
5422 buffer_putstr(b
, "no-advertise");
5425 if (strncmp(argv
[i
]->arg
, "no-e", strlen("no-e")) == 0
5426 && strncmp(argv
[i
]->arg
, "no-export", strlen(argv
[i
]->arg
))
5428 buffer_putstr(b
, "no-export");
5431 if (strncmp(argv
[i
]->arg
, "blackhole", strlen(argv
[i
]->arg
))
5433 buffer_putstr(b
, "blackhole");
5436 if (strncmp(argv
[i
]->arg
, "graceful-shutdown",
5437 strlen(argv
[i
]->arg
))
5439 buffer_putstr(b
, "graceful-shutdown");
5442 buffer_putstr(b
, argv
[i
]->arg
);
5444 buffer_putc(b
, '\0');
5446 /* Fetch result string then compile it to communities attribute. */
5447 str
= buffer_getstr(b
);
5451 com
= community_str2com(str
);
5452 XFREE(MTYPE_TMP
, str
);
5455 /* Can't compile user input into communities attribute. */
5457 vty_out(vty
, "%% Malformed communities attribute\n");
5458 return CMD_WARNING_CONFIG_FAILED
;
5461 /* Set communites attribute string. */
5462 str
= community_str(com
, false);
5465 size_t argstr_sz
= strlen(str
) + strlen(" additive") + 1;
5466 argstr
= XCALLOC(MTYPE_TMP
, argstr_sz
);
5467 strlcpy(argstr
, str
, argstr_sz
);
5468 strlcat(argstr
, " additive", argstr_sz
);
5469 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argstr
);
5471 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, str
);
5473 ret
= nb_cli_apply_changes(vty
, NULL
);
5476 XFREE(MTYPE_TMP
, argstr
);
5477 community_free(&com
);
5482 DEFUN_YANG (set_community_none
,
5483 set_community_none_cmd
,
5484 "set community none",
5486 "BGP community attribute\n"
5487 "No community attribute\n")
5490 "./set-action[action='frr-bgp-route-map:set-community']";
5491 char xpath_value
[XPATH_MAXLEN
];
5493 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5495 snprintf(xpath_value
, sizeof(xpath_value
),
5496 "%s/rmap-set-action/frr-bgp-route-map:community-none", xpath
);
5497 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, "true");
5498 return nb_cli_apply_changes(vty
, NULL
);
5501 DEFUN_YANG (no_set_community
,
5502 no_set_community_cmd
,
5503 "no set community AA:NN...",
5506 "BGP community attribute\n"
5510 "./set-action[action='frr-bgp-route-map:set-community']";
5512 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5513 return nb_cli_apply_changes(vty
, NULL
);
5516 ALIAS_YANG (no_set_community
,
5517 no_set_community_short_cmd
,
5521 "BGP community attribute\n")
5523 DEFPY_YANG (set_community_delete
,
5524 set_community_delete_cmd
,
5525 "set comm-list <(1-99)|(100-500)|COMMUNITY_LIST_NAME> delete",
5527 "set BGP community list (for deletion)\n"
5528 "Community-list number (standard)\n"
5529 "Community-list number (expanded)\n"
5530 "Community-list name\n"
5531 "Delete matching communities\n")
5534 "./set-action[action='frr-bgp-route-map:comm-list-delete']";
5535 char xpath_value
[XPATH_MAXLEN
];
5536 int idx_comm_list
= 2;
5538 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5540 snprintf(xpath_value
, sizeof(xpath_value
),
5541 "%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
5543 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5544 argv
[idx_comm_list
]->arg
);
5546 return nb_cli_apply_changes(vty
, NULL
);
5550 DEFUN_YANG (no_set_community_delete
,
5551 no_set_community_delete_cmd
,
5552 "no set comm-list [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> delete]",
5555 "set BGP community list (for deletion)\n"
5556 "Community-list number (standard)\n"
5557 "Community-list number (expanded)\n"
5558 "Community-list name\n"
5559 "Delete matching communities\n")
5562 "./set-action[action='frr-bgp-route-map:comm-list-delete']";
5564 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5565 return nb_cli_apply_changes(vty
, NULL
);
5568 DEFUN_YANG (set_lcommunity
,
5570 "set large-community AA:BB:CC...",
5572 "BGP large community attribute\n"
5573 "Large Community number in aa:bb:cc format or additive\n")
5578 "./set-action[action='frr-bgp-route-map:set-large-community']";
5579 char xpath_value
[XPATH_MAXLEN
];
5581 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5583 snprintf(xpath_value
, sizeof(xpath_value
),
5584 "%s/rmap-set-action/frr-bgp-route-map:large-community-string",
5586 str
= argv_concat(argv
, argc
, 2);
5587 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, str
);
5588 ret
= nb_cli_apply_changes(vty
, NULL
);
5589 XFREE(MTYPE_TMP
, str
);
5593 DEFUN_YANG (set_lcommunity_none
,
5594 set_lcommunity_none_cmd
,
5595 "set large-community none",
5597 "BGP large community attribute\n"
5598 "No large community attribute\n")
5601 "./set-action[action='frr-bgp-route-map:set-large-community']";
5602 char xpath_value
[XPATH_MAXLEN
];
5604 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5606 snprintf(xpath_value
, sizeof(xpath_value
),
5607 "%s/rmap-set-action/frr-bgp-route-map:large-community-none",
5609 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, "true");
5610 return nb_cli_apply_changes(vty
, NULL
);
5613 DEFUN_YANG (no_set_lcommunity
,
5614 no_set_lcommunity_cmd
,
5615 "no set large-community none",
5618 "BGP large community attribute\n"
5619 "No community attribute\n")
5622 "./set-action[action='frr-bgp-route-map:set-large-community']";
5624 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5625 return nb_cli_apply_changes(vty
, NULL
);
5628 DEFUN_YANG (no_set_lcommunity1
,
5629 no_set_lcommunity1_cmd
,
5630 "no set large-community AA:BB:CC...",
5633 "BGP large community attribute\n"
5634 "Large community in AA:BB:CC... format or additive\n")
5637 "./set-action[action='frr-bgp-route-map:set-large-community']";
5639 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5640 return nb_cli_apply_changes(vty
, NULL
);
5643 ALIAS_YANG (no_set_lcommunity1
,
5644 no_set_lcommunity1_short_cmd
,
5645 "no set large-community",
5648 "BGP large community attribute\n")
5650 DEFPY_YANG (set_lcommunity_delete
,
5651 set_lcommunity_delete_cmd
,
5652 "set large-comm-list <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> delete",
5654 "set BGP large community list (for deletion)\n"
5655 "Large Community-list number (standard)\n"
5656 "Large Communitly-list number (expanded)\n"
5657 "Large Community-list name\n"
5658 "Delete matching large communities\n")
5661 "./set-action[action='frr-bgp-route-map:large-comm-list-delete']";
5662 char xpath_value
[XPATH_MAXLEN
];
5663 int idx_lcomm_list
= 2;
5665 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5667 snprintf(xpath_value
, sizeof(xpath_value
),
5668 "%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
5670 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
5671 argv
[idx_lcomm_list
]->arg
);
5673 return nb_cli_apply_changes(vty
, NULL
);
5676 DEFUN_YANG (no_set_lcommunity_delete
,
5677 no_set_lcommunity_delete_cmd
,
5678 "no set large-comm-list <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [delete]",
5681 "set BGP large community list (for deletion)\n"
5682 "Large Community-list number (standard)\n"
5683 "Large Communitly-list number (expanded)\n"
5684 "Large Community-list name\n"
5685 "Delete matching large communities\n")
5688 "./set-action[action='frr-bgp-route-map:large-comm-list-delete']";
5690 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5691 return nb_cli_apply_changes(vty
, NULL
);
5694 ALIAS_YANG (no_set_lcommunity_delete
,
5695 no_set_lcommunity_delete_short_cmd
,
5696 "no set large-comm-list",
5699 "set BGP large community list (for deletion)\n")
5701 DEFUN_YANG (set_ecommunity_rt
,
5702 set_ecommunity_rt_cmd
,
5703 "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
5705 "BGP extended community attribute\n"
5706 "Route Target extended community\n"
5707 "VPN extended community\n")
5713 "./set-action[action='frr-bgp-route-map:set-extcommunity-rt']";
5714 char xpath_value
[XPATH_MAXLEN
];
5716 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5718 snprintf(xpath_value
, sizeof(xpath_value
),
5719 "%s/rmap-set-action/frr-bgp-route-map:extcommunity-rt", xpath
);
5720 str
= argv_concat(argv
, argc
, idx_asn_nn
);
5721 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, str
);
5722 ret
= nb_cli_apply_changes(vty
, NULL
);
5723 XFREE(MTYPE_TMP
, str
);
5727 DEFUN_YANG (no_set_ecommunity_rt
,
5728 no_set_ecommunity_rt_cmd
,
5729 "no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
5732 "BGP extended community attribute\n"
5733 "Route Target extended community\n"
5734 "VPN extended community\n")
5737 "./set-action[action='frr-bgp-route-map:set-extcommunity-rt']";
5738 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5739 return nb_cli_apply_changes(vty
, NULL
);
5742 ALIAS_YANG (no_set_ecommunity_rt
,
5743 no_set_ecommunity_rt_short_cmd
,
5744 "no set extcommunity rt",
5747 "BGP extended community attribute\n"
5748 "Route Target extended community\n")
5750 DEFUN_YANG (set_ecommunity_soo
,
5751 set_ecommunity_soo_cmd
,
5752 "set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
5754 "BGP extended community attribute\n"
5755 "Site-of-Origin extended community\n"
5756 "VPN extended community\n")
5762 "./set-action[action='frr-bgp-route-map:set-extcommunity-soo']";
5763 char xpath_value
[XPATH_MAXLEN
];
5765 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5767 snprintf(xpath_value
, sizeof(xpath_value
),
5768 "%s/rmap-set-action/frr-bgp-route-map:extcommunity-soo",
5770 str
= argv_concat(argv
, argc
, idx_asn_nn
);
5771 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, str
);
5772 ret
= nb_cli_apply_changes(vty
, NULL
);
5773 XFREE(MTYPE_TMP
, str
);
5777 DEFUN_YANG (no_set_ecommunity_soo
,
5778 no_set_ecommunity_soo_cmd
,
5779 "no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
5782 "BGP extended community attribute\n"
5783 "Site-of-Origin extended community\n"
5784 "VPN extended community\n")
5787 "./set-action[action='frr-bgp-route-map:set-extcommunity-soo']";
5788 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5789 return nb_cli_apply_changes(vty
, NULL
);
5792 ALIAS_YANG (no_set_ecommunity_soo
,
5793 no_set_ecommunity_soo_short_cmd
,
5794 "no set extcommunity soo",
5797 "GP extended community attribute\n"
5798 "Site-of-Origin extended community\n")
5800 DEFUN_YANG(set_ecommunity_none
, set_ecommunity_none_cmd
,
5801 "set extcommunity none",
5803 "BGP extended community attribute\n"
5804 "No extended community attribute\n")
5807 "./set-action[action='frr-bgp-route-map:set-extcommunity-none']";
5808 char xpath_value
[XPATH_MAXLEN
];
5810 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5812 snprintf(xpath_value
, sizeof(xpath_value
),
5813 "%s/rmap-set-action/frr-bgp-route-map:extcommunity-none",
5815 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, "true");
5816 return nb_cli_apply_changes(vty
, NULL
);
5819 DEFUN_YANG(no_set_ecommunity_none
, no_set_ecommunity_none_cmd
,
5820 "no set extcommunity none",
5822 "BGP extended community attribute\n"
5823 "No extended community attribute\n")
5826 "./set-action[action='frr-bgp-route-map:set-extcommunity-none']";
5827 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5828 return nb_cli_apply_changes(vty
, NULL
);
5831 DEFUN_YANG (set_ecommunity_lb
,
5832 set_ecommunity_lb_cmd
,
5833 "set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
5835 "BGP extended community attribute\n"
5836 "Link bandwidth extended community\n"
5837 "Bandwidth value in Mbps\n"
5838 "Cumulative bandwidth of all multipaths (outbound-only)\n"
5839 "Internally computed bandwidth based on number of multipaths (outbound-only)\n"
5840 "Attribute is set as non-transitive\n")
5843 int idx_non_transitive
= 0;
5845 "./set-action[action='frr-bgp-route-map:set-extcommunity-lb']";
5846 char xpath_lb_type
[XPATH_MAXLEN
];
5847 char xpath_bandwidth
[XPATH_MAXLEN
];
5848 char xpath_non_transitive
[XPATH_MAXLEN
];
5850 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5852 snprintf(xpath_lb_type
, sizeof(xpath_lb_type
),
5853 "%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type",
5855 snprintf(xpath_bandwidth
, sizeof(xpath_bandwidth
),
5856 "%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth",
5858 snprintf(xpath_non_transitive
, sizeof(xpath_non_transitive
),
5859 "%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific",
5862 if ((strcmp(argv
[idx_lb
]->arg
, "cumulative")) == 0)
5863 nb_cli_enqueue_change(vty
, xpath_lb_type
, NB_OP_MODIFY
,
5864 "cumulative-bandwidth");
5865 else if ((strcmp(argv
[idx_lb
]->arg
, "num-multipaths")) == 0)
5866 nb_cli_enqueue_change(vty
, xpath_lb_type
, NB_OP_MODIFY
,
5867 "computed-bandwidth");
5869 nb_cli_enqueue_change(vty
, xpath_lb_type
, NB_OP_MODIFY
,
5870 "explicit-bandwidth");
5871 nb_cli_enqueue_change(vty
, xpath_bandwidth
, NB_OP_MODIFY
,
5875 if (argv_find(argv
, argc
, "non-transitive", &idx_non_transitive
))
5876 nb_cli_enqueue_change(vty
, xpath_non_transitive
, NB_OP_MODIFY
,
5879 nb_cli_enqueue_change(vty
, xpath_non_transitive
, NB_OP_MODIFY
,
5882 return nb_cli_apply_changes(vty
, NULL
);
5885 DEFUN_YANG (no_set_ecommunity_lb
,
5886 no_set_ecommunity_lb_cmd
,
5887 "no set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
5890 "BGP extended community attribute\n"
5891 "Link bandwidth extended community\n"
5892 "Bandwidth value in Mbps\n"
5893 "Cumulative bandwidth of all multipaths (outbound-only)\n"
5894 "Internally computed bandwidth based on number of multipaths (outbound-only)\n"
5895 "Attribute is set as non-transitive\n")
5898 "./set-action[action='frr-bgp-route-map:set-extcommunity-lb']";
5900 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5901 return nb_cli_apply_changes(vty
, NULL
);
5904 ALIAS_YANG (no_set_ecommunity_lb
,
5905 no_set_ecommunity_lb_short_cmd
,
5906 "no set extcommunity bandwidth",
5909 "BGP extended community attribute\n"
5910 "Link bandwidth extended community\n")
5912 DEFUN_YANG (set_origin
,
5914 "set origin <egp|igp|incomplete>",
5919 "unknown heritage\n")
5922 const char *origin_type
;
5924 "./set-action[action='frr-bgp-route-map:set-origin']";
5925 char xpath_value
[XPATH_MAXLEN
];
5927 if (strncmp(argv
[idx_origin
]->arg
, "igp", 2) == 0)
5928 origin_type
= "igp";
5929 else if (strncmp(argv
[idx_origin
]->arg
, "egp", 1) == 0)
5930 origin_type
= "egp";
5931 else if (strncmp(argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
5932 origin_type
= "incomplete";
5934 vty_out(vty
, "%% Invalid match origin type\n");
5935 return CMD_WARNING_CONFIG_FAILED
;
5938 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5939 snprintf(xpath_value
, sizeof(xpath_value
),
5940 "%s/rmap-set-action/frr-bgp-route-map:origin", xpath
);
5941 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, origin_type
);
5943 return nb_cli_apply_changes(vty
, NULL
);
5946 DEFUN_YANG (no_set_origin
,
5948 "no set origin [<egp|igp|incomplete>]",
5954 "unknown heritage\n")
5957 "./set-action[action='frr-bgp-route-map:set-origin']";
5959 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5960 return nb_cli_apply_changes(vty
, NULL
);
5963 DEFUN_YANG (set_atomic_aggregate
,
5964 set_atomic_aggregate_cmd
,
5965 "set atomic-aggregate",
5967 "BGP atomic aggregate attribute\n" )
5970 "./set-action[action='frr-bgp-route-map:atomic-aggregate']";
5971 char xpath_value
[XPATH_MAXLEN
];
5973 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
5974 snprintf(xpath_value
, sizeof(xpath_value
),
5975 "%s/rmap-set-action/frr-bgp-route-map:atomic-aggregate",
5977 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, NULL
);
5979 return nb_cli_apply_changes(vty
, NULL
);
5982 DEFUN_YANG (no_set_atomic_aggregate
,
5983 no_set_atomic_aggregate_cmd
,
5984 "no set atomic-aggregate",
5987 "BGP atomic aggregate attribute\n" )
5990 "./set-action[action='frr-bgp-route-map:atomic-aggregate']";
5992 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
5993 return nb_cli_apply_changes(vty
, NULL
);
5996 DEFUN_YANG (set_aggregator_as
,
5997 set_aggregator_as_cmd
,
5998 "set aggregator as (1-4294967295) A.B.C.D",
6000 "BGP aggregator attribute\n"
6001 "AS number of aggregator\n"
6003 "IP address of aggregator\n")
6007 char xpath_asn
[XPATH_MAXLEN
];
6008 char xpath_addr
[XPATH_MAXLEN
];
6010 "./set-action[action='frr-bgp-route-map:aggregator']";
6012 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6015 xpath_asn
, sizeof(xpath_asn
),
6016 "%s/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn",
6018 nb_cli_enqueue_change(vty
, xpath_asn
, NB_OP_MODIFY
,
6019 argv
[idx_number
]->arg
);
6022 xpath_addr
, sizeof(xpath_addr
),
6023 "%s/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address",
6025 nb_cli_enqueue_change(vty
, xpath_addr
, NB_OP_MODIFY
,
6026 argv
[idx_ipv4
]->arg
);
6028 return nb_cli_apply_changes(vty
, NULL
);
6031 DEFUN_YANG (no_set_aggregator_as
,
6032 no_set_aggregator_as_cmd
,
6033 "no set aggregator as [(1-4294967295) A.B.C.D]",
6036 "BGP aggregator attribute\n"
6037 "AS number of aggregator\n"
6039 "IP address of aggregator\n")
6042 "./set-action[action='frr-bgp-route-map:aggregator']";
6044 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6045 return nb_cli_apply_changes(vty
, NULL
);
6048 DEFUN_YANG (match_ipv6_next_hop
,
6049 match_ipv6_next_hop_cmd
,
6050 "match ipv6 next-hop X:X::X:X",
6053 "Match IPv6 next-hop address of route\n"
6054 "IPv6 address of next hop\n")
6057 "./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']";
6058 char xpath_value
[XPATH_MAXLEN
];
6060 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6061 snprintf(xpath_value
, sizeof(xpath_value
),
6062 "%s/rmap-match-condition/frr-bgp-route-map:ipv6-address",
6064 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[3]->arg
);
6066 return nb_cli_apply_changes(vty
, NULL
);
6069 DEFUN_YANG (no_match_ipv6_next_hop
,
6070 no_match_ipv6_next_hop_cmd
,
6071 "no match ipv6 next-hop X:X::X:X",
6075 "Match IPv6 next-hop address of route\n"
6076 "IPv6 address of next hop\n")
6079 "./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']";
6081 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6082 return nb_cli_apply_changes(vty
, NULL
);
6085 DEFPY_YANG (match_ipv4_next_hop
,
6086 match_ipv4_next_hop_cmd
,
6087 "match ip next-hop address A.B.C.D",
6090 "Match IP next-hop address of route\n"
6092 "IP address of next-hop\n")
6095 "./match-condition[condition='frr-bgp-route-map:ipv4-nexthop']";
6096 char xpath_value
[XPATH_MAXLEN
];
6098 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6099 snprintf(xpath_value
, sizeof(xpath_value
),
6100 "%s/rmap-match-condition/frr-bgp-route-map:ipv4-address",
6102 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[4]->arg
);
6104 return nb_cli_apply_changes(vty
, NULL
);
6107 DEFPY_YANG (no_match_ipv4_next_hop
,
6108 no_match_ipv4_next_hop_cmd
,
6109 "no match ip next-hop address [A.B.C.D]",
6113 "Match IP next-hop address of route\n"
6115 "IP address of next-hop\n")
6118 "./match-condition[condition='frr-bgp-route-map:ipv4-nexthop']";
6120 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6121 return nb_cli_apply_changes(vty
, NULL
);
6124 DEFUN_YANG (set_ipv6_nexthop_peer
,
6125 set_ipv6_nexthop_peer_cmd
,
6126 "set ipv6 next-hop peer-address",
6129 "Next hop address\n"
6130 "Use peer address (for BGP only)\n")
6133 "./set-action[action='frr-bgp-route-map:ipv6-peer-address']";
6134 char xpath_value
[XPATH_MAXLEN
];
6136 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6137 snprintf(xpath_value
, sizeof(xpath_value
),
6138 "%s/rmap-set-action/frr-bgp-route-map:preference", xpath
);
6139 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, "true");
6141 return nb_cli_apply_changes(vty
, NULL
);
6144 DEFUN_YANG (no_set_ipv6_nexthop_peer
,
6145 no_set_ipv6_nexthop_peer_cmd
,
6146 "no set ipv6 next-hop peer-address",
6150 "IPv6 next-hop address\n"
6151 "Use peer address (for BGP only)\n")
6154 "./set-action[action='frr-bgp-route-map:ipv6-peer-address']";
6156 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6157 return nb_cli_apply_changes(vty
, NULL
);
6160 DEFUN_YANG (set_ipv6_nexthop_prefer_global
,
6161 set_ipv6_nexthop_prefer_global_cmd
,
6162 "set ipv6 next-hop prefer-global",
6165 "IPv6 next-hop address\n"
6166 "Prefer global over link-local if both exist\n")
6169 "./set-action[action='frr-bgp-route-map:ipv6-prefer-global']";
6170 char xpath_value
[XPATH_MAXLEN
];
6172 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6173 snprintf(xpath_value
, sizeof(xpath_value
),
6174 "%s/rmap-set-action/frr-bgp-route-map:preference", xpath
);
6175 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, "true");
6177 return nb_cli_apply_changes(vty
, NULL
);
6180 DEFUN_YANG (no_set_ipv6_nexthop_prefer_global
,
6181 no_set_ipv6_nexthop_prefer_global_cmd
,
6182 "no set ipv6 next-hop prefer-global",
6186 "IPv6 next-hop address\n"
6187 "Prefer global over link-local if both exist\n")
6190 "./set-action[action='frr-bgp-route-map:ipv6-prefer-global']";
6192 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6193 return nb_cli_apply_changes(vty
, NULL
);
6196 DEFUN_YANG (set_ipv6_nexthop_global
,
6197 set_ipv6_nexthop_global_cmd
,
6198 "set ipv6 next-hop global X:X::X:X",
6201 "IPv6 next-hop address\n"
6202 "IPv6 global address\n"
6203 "IPv6 address of next hop\n")
6207 "./set-action[action='frr-bgp-route-map:ipv6-nexthop-global']";
6208 char xpath_value
[XPATH_MAXLEN
];
6210 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6211 snprintf(xpath_value
, sizeof(xpath_value
),
6212 "%s/rmap-set-action/frr-bgp-route-map:ipv6-address", xpath
);
6213 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
6214 argv
[idx_ipv6
]->arg
);
6216 return nb_cli_apply_changes(vty
, NULL
);
6219 DEFUN_YANG (no_set_ipv6_nexthop_global
,
6220 no_set_ipv6_nexthop_global_cmd
,
6221 "no set ipv6 next-hop global X:X::X:X",
6225 "IPv6 next-hop address\n"
6226 "IPv6 global address\n"
6227 "IPv6 address of next hop\n")
6230 "./set-action[action='frr-bgp-route-map:ipv6-nexthop-global']";
6232 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6233 return nb_cli_apply_changes(vty
, NULL
);
6236 #ifdef KEEP_OLD_VPN_COMMANDS
6237 DEFUN_YANG (set_vpn_nexthop
,
6238 set_vpn_nexthop_cmd
,
6239 "set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
6241 "VPNv4 information\n"
6242 "VPN next-hop address\n"
6243 "IP address of next hop\n"
6244 "VPNv6 information\n"
6245 "VPN next-hop address\n"
6246 "IPv6 address of next hop\n")
6251 char xpath_value
[XPATH_MAXLEN
];
6253 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
6254 if (afi
== AFI_IP
) {
6256 "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
6258 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6260 xpath_value
, sizeof(xpath_value
),
6261 "%s/rmap-set-action/frr-bgp-route-map:ipv4-address",
6265 "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
6267 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6269 xpath_value
, sizeof(xpath_value
),
6270 "%s/rmap-set-action/frr-bgp-route-map:ipv6-address",
6274 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
6277 return nb_cli_apply_changes(vty
, NULL
);
6283 DEFUN_YANG (no_set_vpn_nexthop
,
6284 no_set_vpn_nexthop_cmd
,
6285 "no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
6288 "VPNv4 information\n"
6289 "VPN next-hop address\n"
6290 "IP address of next hop\n"
6291 "VPNv6 information\n"
6292 "VPN next-hop address\n"
6293 "IPv6 address of next hop\n")
6298 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
6299 if (afi
== AFI_IP
) {
6301 "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
6302 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6305 "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
6306 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6308 return nb_cli_apply_changes(vty
, NULL
);
6312 #endif /* KEEP_OLD_VPN_COMMANDS */
6314 DEFUN_YANG (set_ipx_vpn_nexthop
,
6315 set_ipx_vpn_nexthop_cmd
,
6316 "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
6318 "IPv4 information\n"
6319 "IPv6 information\n"
6321 "VPN next-hop address\n"
6322 "IP address of next hop\n"
6323 "IPv6 address of next hop\n")
6328 char xpath_value
[XPATH_MAXLEN
];
6330 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
6331 if (afi
== AFI_IP
) {
6333 "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
6335 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6337 xpath_value
, sizeof(xpath_value
),
6338 "%s/rmap-set-action/frr-bgp-route-map:ipv4-address",
6342 "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
6344 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6346 xpath_value
, sizeof(xpath_value
),
6347 "%s/rmap-set-action/frr-bgp-route-map:ipv6-address",
6350 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
6352 return nb_cli_apply_changes(vty
, NULL
);
6357 DEFUN_YANG (no_set_ipx_vpn_nexthop
,
6358 no_set_ipx_vpn_nexthop_cmd
,
6359 "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
6362 "IPv4 information\n"
6363 "IPv6 information\n"
6365 "VPN next-hop address\n"
6366 "IP address of next hop\n"
6367 "IPv6 address of next hop\n")
6372 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
6373 if (afi
== AFI_IP
) {
6375 "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
6376 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6379 "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
6380 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6382 return nb_cli_apply_changes(vty
, NULL
);
6387 DEFUN_YANG (set_originator_id
,
6388 set_originator_id_cmd
,
6389 "set originator-id A.B.C.D",
6391 "BGP originator ID attribute\n"
6392 "IP address of originator\n")
6396 "./set-action[action='frr-bgp-route-map:originator-id']";
6397 char xpath_value
[XPATH_MAXLEN
];
6399 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
6400 snprintf(xpath_value
, sizeof(xpath_value
),
6401 "%s/rmap-set-action/frr-bgp-route-map:originator-id", xpath
);
6402 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
,
6403 argv
[idx_ipv4
]->arg
);
6405 return nb_cli_apply_changes(vty
, NULL
);
6408 DEFUN_YANG (no_set_originator_id
,
6409 no_set_originator_id_cmd
,
6410 "no set originator-id [A.B.C.D]",
6413 "BGP originator ID attribute\n"
6414 "IP address of originator\n")
6417 "./set-action[action='frr-bgp-route-map:originator-id']";
6419 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
6420 return nb_cli_apply_changes(vty
, NULL
);
6423 /* Initialization of route map. */
6424 void bgp_route_map_init(void)
6428 route_map_add_hook(bgp_route_map_add
);
6429 route_map_delete_hook(bgp_route_map_delete
);
6430 route_map_event_hook(bgp_route_map_event
);
6432 route_map_match_interface_hook(generic_match_add
);
6433 route_map_no_match_interface_hook(generic_match_delete
);
6435 route_map_match_ip_address_hook(generic_match_add
);
6436 route_map_no_match_ip_address_hook(generic_match_delete
);
6438 route_map_match_ip_address_prefix_list_hook(generic_match_add
);
6439 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete
);
6441 route_map_match_ip_next_hop_hook(generic_match_add
);
6442 route_map_no_match_ip_next_hop_hook(generic_match_delete
);
6444 route_map_match_ip_next_hop_prefix_list_hook(generic_match_add
);
6445 route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete
);
6447 route_map_match_ip_next_hop_type_hook(generic_match_add
);
6448 route_map_no_match_ip_next_hop_type_hook(generic_match_delete
);
6450 route_map_match_ipv6_address_hook(generic_match_add
);
6451 route_map_no_match_ipv6_address_hook(generic_match_delete
);
6453 route_map_match_ipv6_address_prefix_list_hook(generic_match_add
);
6454 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete
);
6456 route_map_match_ipv6_next_hop_type_hook(generic_match_add
);
6457 route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete
);
6459 route_map_match_metric_hook(generic_match_add
);
6460 route_map_no_match_metric_hook(generic_match_delete
);
6462 route_map_match_tag_hook(generic_match_add
);
6463 route_map_no_match_tag_hook(generic_match_delete
);
6465 route_map_set_srte_color_hook(generic_set_add
);
6466 route_map_no_set_srte_color_hook(generic_set_delete
);
6468 route_map_set_ip_nexthop_hook(generic_set_add
);
6469 route_map_no_set_ip_nexthop_hook(generic_set_delete
);
6471 route_map_set_ipv6_nexthop_local_hook(generic_set_add
);
6472 route_map_no_set_ipv6_nexthop_local_hook(generic_set_delete
);
6474 route_map_set_metric_hook(generic_set_add
);
6475 route_map_no_set_metric_hook(generic_set_delete
);
6477 route_map_set_tag_hook(generic_set_add
);
6478 route_map_no_set_tag_hook(generic_set_delete
);
6480 route_map_install_match(&route_match_peer_cmd
);
6481 route_map_install_match(&route_match_alias_cmd
);
6482 route_map_install_match(&route_match_local_pref_cmd
);
6483 #ifdef HAVE_SCRIPTING
6484 route_map_install_match(&route_match_script_cmd
);
6486 route_map_install_match(&route_match_ip_address_cmd
);
6487 route_map_install_match(&route_match_ip_next_hop_cmd
);
6488 route_map_install_match(&route_match_ip_route_source_cmd
);
6489 route_map_install_match(&route_match_ip_address_prefix_list_cmd
);
6490 route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd
);
6491 route_map_install_match(&route_match_ip_next_hop_type_cmd
);
6492 route_map_install_match(&route_match_ip_route_source_prefix_list_cmd
);
6493 route_map_install_match(&route_match_aspath_cmd
);
6494 route_map_install_match(&route_match_community_cmd
);
6495 route_map_install_match(&route_match_lcommunity_cmd
);
6496 route_map_install_match(&route_match_ecommunity_cmd
);
6497 route_map_install_match(&route_match_local_pref_cmd
);
6498 route_map_install_match(&route_match_metric_cmd
);
6499 route_map_install_match(&route_match_origin_cmd
);
6500 route_map_install_match(&route_match_probability_cmd
);
6501 route_map_install_match(&route_match_interface_cmd
);
6502 route_map_install_match(&route_match_tag_cmd
);
6503 route_map_install_match(&route_match_mac_address_cmd
);
6504 route_map_install_match(&route_match_evpn_vni_cmd
);
6505 route_map_install_match(&route_match_evpn_route_type_cmd
);
6506 route_map_install_match(&route_match_evpn_rd_cmd
);
6507 route_map_install_match(&route_match_evpn_default_route_cmd
);
6508 route_map_install_match(&route_match_vrl_source_vrf_cmd
);
6510 route_map_install_set(&route_set_evpn_gateway_ip_ipv4_cmd
);
6511 route_map_install_set(&route_set_evpn_gateway_ip_ipv6_cmd
);
6512 route_map_install_set(&route_set_table_id_cmd
);
6513 route_map_install_set(&route_set_srte_color_cmd
);
6514 route_map_install_set(&route_set_ip_nexthop_cmd
);
6515 route_map_install_set(&route_set_local_pref_cmd
);
6516 route_map_install_set(&route_set_weight_cmd
);
6517 route_map_install_set(&route_set_label_index_cmd
);
6518 route_map_install_set(&route_set_metric_cmd
);
6519 route_map_install_set(&route_set_distance_cmd
);
6520 route_map_install_set(&route_set_aspath_prepend_cmd
);
6521 route_map_install_set(&route_set_aspath_exclude_cmd
);
6522 route_map_install_set(&route_set_origin_cmd
);
6523 route_map_install_set(&route_set_atomic_aggregate_cmd
);
6524 route_map_install_set(&route_set_aggregator_as_cmd
);
6525 route_map_install_set(&route_set_community_cmd
);
6526 route_map_install_set(&route_set_community_delete_cmd
);
6527 route_map_install_set(&route_set_lcommunity_cmd
);
6528 route_map_install_set(&route_set_lcommunity_delete_cmd
);
6529 route_map_install_set(&route_set_vpnv4_nexthop_cmd
);
6530 route_map_install_set(&route_set_vpnv6_nexthop_cmd
);
6531 route_map_install_set(&route_set_originator_id_cmd
);
6532 route_map_install_set(&route_set_ecommunity_rt_cmd
);
6533 route_map_install_set(&route_set_ecommunity_soo_cmd
);
6534 route_map_install_set(&route_set_ecommunity_lb_cmd
);
6535 route_map_install_set(&route_set_ecommunity_none_cmd
);
6536 route_map_install_set(&route_set_tag_cmd
);
6537 route_map_install_set(&route_set_label_index_cmd
);
6539 install_element(RMAP_NODE
, &match_peer_cmd
);
6540 install_element(RMAP_NODE
, &match_peer_local_cmd
);
6541 install_element(RMAP_NODE
, &no_match_peer_cmd
);
6542 install_element(RMAP_NODE
, &match_ip_route_source_cmd
);
6543 install_element(RMAP_NODE
, &no_match_ip_route_source_cmd
);
6544 install_element(RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
6545 install_element(RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
6546 install_element(RMAP_NODE
, &match_mac_address_cmd
);
6547 install_element(RMAP_NODE
, &no_match_mac_address_cmd
);
6548 install_element(RMAP_NODE
, &match_evpn_vni_cmd
);
6549 install_element(RMAP_NODE
, &no_match_evpn_vni_cmd
);
6550 install_element(RMAP_NODE
, &match_evpn_route_type_cmd
);
6551 install_element(RMAP_NODE
, &no_match_evpn_route_type_cmd
);
6552 install_element(RMAP_NODE
, &match_evpn_rd_cmd
);
6553 install_element(RMAP_NODE
, &no_match_evpn_rd_cmd
);
6554 install_element(RMAP_NODE
, &match_evpn_default_route_cmd
);
6555 install_element(RMAP_NODE
, &no_match_evpn_default_route_cmd
);
6556 install_element(RMAP_NODE
, &set_evpn_gw_ip_ipv4_cmd
);
6557 install_element(RMAP_NODE
, &no_set_evpn_gw_ip_ipv4_cmd
);
6558 install_element(RMAP_NODE
, &set_evpn_gw_ip_ipv6_cmd
);
6559 install_element(RMAP_NODE
, &no_set_evpn_gw_ip_ipv6_cmd
);
6560 install_element(RMAP_NODE
, &match_vrl_source_vrf_cmd
);
6561 install_element(RMAP_NODE
, &no_match_vrl_source_vrf_cmd
);
6563 install_element(RMAP_NODE
, &match_aspath_cmd
);
6564 install_element(RMAP_NODE
, &no_match_aspath_cmd
);
6565 install_element(RMAP_NODE
, &match_local_pref_cmd
);
6566 install_element(RMAP_NODE
, &no_match_local_pref_cmd
);
6567 install_element(RMAP_NODE
, &match_alias_cmd
);
6568 install_element(RMAP_NODE
, &no_match_alias_cmd
);
6569 install_element(RMAP_NODE
, &match_community_cmd
);
6570 install_element(RMAP_NODE
, &no_match_community_cmd
);
6571 install_element(RMAP_NODE
, &match_lcommunity_cmd
);
6572 install_element(RMAP_NODE
, &no_match_lcommunity_cmd
);
6573 install_element(RMAP_NODE
, &match_ecommunity_cmd
);
6574 install_element(RMAP_NODE
, &no_match_ecommunity_cmd
);
6575 install_element(RMAP_NODE
, &match_origin_cmd
);
6576 install_element(RMAP_NODE
, &no_match_origin_cmd
);
6577 install_element(RMAP_NODE
, &match_probability_cmd
);
6578 install_element(RMAP_NODE
, &no_match_probability_cmd
);
6580 install_element(RMAP_NODE
, &no_set_table_id_cmd
);
6581 install_element(RMAP_NODE
, &set_table_id_cmd
);
6582 install_element(RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
6583 install_element(RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
6584 install_element(RMAP_NODE
, &set_local_pref_cmd
);
6585 install_element(RMAP_NODE
, &set_distance_cmd
);
6586 install_element(RMAP_NODE
, &no_set_distance_cmd
);
6587 install_element(RMAP_NODE
, &no_set_local_pref_cmd
);
6588 install_element(RMAP_NODE
, &set_weight_cmd
);
6589 install_element(RMAP_NODE
, &set_label_index_cmd
);
6590 install_element(RMAP_NODE
, &no_set_weight_cmd
);
6591 install_element(RMAP_NODE
, &no_set_label_index_cmd
);
6592 install_element(RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
6593 install_element(RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
6594 install_element(RMAP_NODE
, &set_aspath_exclude_cmd
);
6595 install_element(RMAP_NODE
, &no_set_aspath_prepend_cmd
);
6596 install_element(RMAP_NODE
, &no_set_aspath_prepend_lastas_cmd
);
6597 install_element(RMAP_NODE
, &no_set_aspath_exclude_cmd
);
6598 install_element(RMAP_NODE
, &no_set_aspath_exclude_all_cmd
);
6599 install_element(RMAP_NODE
, &set_origin_cmd
);
6600 install_element(RMAP_NODE
, &no_set_origin_cmd
);
6601 install_element(RMAP_NODE
, &set_atomic_aggregate_cmd
);
6602 install_element(RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
6603 install_element(RMAP_NODE
, &set_aggregator_as_cmd
);
6604 install_element(RMAP_NODE
, &no_set_aggregator_as_cmd
);
6605 install_element(RMAP_NODE
, &set_community_cmd
);
6606 install_element(RMAP_NODE
, &set_community_none_cmd
);
6607 install_element(RMAP_NODE
, &no_set_community_cmd
);
6608 install_element(RMAP_NODE
, &no_set_community_short_cmd
);
6609 install_element(RMAP_NODE
, &set_community_delete_cmd
);
6610 install_element(RMAP_NODE
, &no_set_community_delete_cmd
);
6611 install_element(RMAP_NODE
, &set_lcommunity_cmd
);
6612 install_element(RMAP_NODE
, &set_lcommunity_none_cmd
);
6613 install_element(RMAP_NODE
, &no_set_lcommunity_cmd
);
6614 install_element(RMAP_NODE
, &no_set_lcommunity1_cmd
);
6615 install_element(RMAP_NODE
, &no_set_lcommunity1_short_cmd
);
6616 install_element(RMAP_NODE
, &set_lcommunity_delete_cmd
);
6617 install_element(RMAP_NODE
, &no_set_lcommunity_delete_cmd
);
6618 install_element(RMAP_NODE
, &no_set_lcommunity_delete_short_cmd
);
6619 install_element(RMAP_NODE
, &set_ecommunity_rt_cmd
);
6620 install_element(RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
6621 install_element(RMAP_NODE
, &no_set_ecommunity_rt_short_cmd
);
6622 install_element(RMAP_NODE
, &set_ecommunity_soo_cmd
);
6623 install_element(RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
6624 install_element(RMAP_NODE
, &no_set_ecommunity_soo_short_cmd
);
6625 install_element(RMAP_NODE
, &set_ecommunity_lb_cmd
);
6626 install_element(RMAP_NODE
, &no_set_ecommunity_lb_cmd
);
6627 install_element(RMAP_NODE
, &no_set_ecommunity_lb_short_cmd
);
6628 install_element(RMAP_NODE
, &set_ecommunity_none_cmd
);
6629 install_element(RMAP_NODE
, &no_set_ecommunity_none_cmd
);
6630 #ifdef KEEP_OLD_VPN_COMMANDS
6631 install_element(RMAP_NODE
, &set_vpn_nexthop_cmd
);
6632 install_element(RMAP_NODE
, &no_set_vpn_nexthop_cmd
);
6633 #endif /* KEEP_OLD_VPN_COMMANDS */
6634 install_element(RMAP_NODE
, &set_ipx_vpn_nexthop_cmd
);
6635 install_element(RMAP_NODE
, &no_set_ipx_vpn_nexthop_cmd
);
6636 install_element(RMAP_NODE
, &set_originator_id_cmd
);
6637 install_element(RMAP_NODE
, &no_set_originator_id_cmd
);
6639 route_map_install_match(&route_match_ipv6_address_cmd
);
6640 route_map_install_match(&route_match_ipv6_next_hop_cmd
);
6641 route_map_install_match(&route_match_ipv4_next_hop_cmd
);
6642 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd
);
6643 route_map_install_match(&route_match_ipv6_next_hop_type_cmd
);
6644 route_map_install_set(&route_set_ipv6_nexthop_global_cmd
);
6645 route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd
);
6646 route_map_install_set(&route_set_ipv6_nexthop_local_cmd
);
6647 route_map_install_set(&route_set_ipv6_nexthop_peer_cmd
);
6649 install_element(RMAP_NODE
, &match_ipv6_next_hop_cmd
);
6650 install_element(RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
6651 install_element(RMAP_NODE
, &match_ipv4_next_hop_cmd
);
6652 install_element(RMAP_NODE
, &no_match_ipv4_next_hop_cmd
);
6653 install_element(RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
6654 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
6655 install_element(RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
6656 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
6657 install_element(RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
6658 install_element(RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
6659 #ifdef HAVE_SCRIPTING
6660 install_element(RMAP_NODE
, &match_script_cmd
);
6664 void bgp_route_map_terminate(void)
6666 /* ToDo: Cleanup all the used memory */