diff options
| author | paulzlabn <paulz@labn.net> | 2018-03-14 13:31:58 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-14 13:31:58 -0700 | 
| commit | 3f1224cd1a9408bdad6aca8c0c205211cb548d5c (patch) | |
| tree | 87e6a52a3e7ad7b09caa3207f081fd92bc8fd018 /bgpd | |
| parent | fd9b55a2b77c187730600d429b3f290ab58fa035 (diff) | |
| parent | 6ca96cc6ada990d052fcfc48cffeef454ae64a10 (diff) | |
Merge branch 'master' into working/master/bgp-vpn-vrf-leaking
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/.gitignore | 1 | ||||
| -rw-r--r-- | bgpd/bgp_attr.c | 50 | ||||
| -rw-r--r-- | bgpd/bgp_attr.h | 17 | ||||
| -rw-r--r-- | bgpd/bgp_debug.c | 5 | ||||
| -rw-r--r-- | bgpd/bgp_debug.h | 1 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.c | 206 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.h | 19 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_private.h | 26 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 142 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 47 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 44 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 6 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 18 | 
13 files changed, 428 insertions, 154 deletions
diff --git a/bgpd/.gitignore b/bgpd/.gitignore index a97bdb83d3..105be22995 100644 --- a/bgpd/.gitignore +++ b/bgpd/.gitignore @@ -16,4 +16,3 @@ TAGS  .arch-ids  *~  *.loT -*clippy.c diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index c23950799f..c3a1105995 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2107,6 +2107,51 @@ bgp_attr_prefix_sid(struct bgp_attr_parser_args *args,  	return BGP_ATTR_PARSE_PROCEED;  } +/* PMSI tunnel attribute (RFC 6514) + * Basic validation checks done here. + */ +static bgp_attr_parse_ret_t +bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args) +{ +	struct peer *const peer = args->peer; +	struct attr *const attr = args->attr; +	const bgp_size_t length = args->length; +	u_int8_t tnl_type; + +	/* Verify that the receiver is expecting "ingress replication" as we +	 * can only support that. +	 */ +	if (length < 2) { +		zlog_err("Bad PMSI tunnel attribute length %d", length); +		return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, +					  args->total); +	} +	stream_getc(peer->curr); /* Flags */ +	tnl_type = stream_getc(peer->curr); +	if (tnl_type > PMSI_TNLTYPE_MAX) { +		zlog_err("Invalid PMSI tunnel attribute type %d", tnl_type); +		return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, +					  args->total); +	} +	if (tnl_type == PMSI_TNLTYPE_INGR_REPL) { +		if (length != 9) { +			zlog_err("Bad PMSI tunnel attribute length %d for IR", +				 length); +			return bgp_attr_malformed( +				args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, +				args->total); +		} +	} + +	attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL); +	attr->pmsi_tnl_type = tnl_type; + +	/* Forward read pointer of input stream. */ +	stream_forward_getp(peer->curr, length - 2); + +	return BGP_ATTR_PARSE_PROCEED; +} +  /* BGP unknown attribute treatment. */  static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)  { @@ -2440,6 +2485,9 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,  		case BGP_ATTR_PREFIX_SID:  			ret = bgp_attr_prefix_sid(&attr_args, mp_update);  			break; +		case BGP_ATTR_PMSI_TUNNEL: +			ret = bgp_attr_pmsi_tunnel(&attr_args); +			break;  		default:  			ret = bgp_attr_unknown(&attr_args);  			break; @@ -3263,7 +3311,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,  		stream_putc(s, BGP_ATTR_PMSI_TUNNEL);  		stream_putc(s, 9); // Length  		stream_putc(s, 0); // Flags -		stream_putc(s, 6); // Tunnel type: Ingress Replication (6) +		stream_putc(s, PMSI_TNLTYPE_INGR_REPL); // IR (6)  		stream_put(s, &(attr->label),  			   BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI  		stream_put_ipv4(s, attr->nexthop.s_addr); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 1a49e4ecf2..5403f32543 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -66,6 +66,8 @@  #define BGP_PREFIX_SID_IPV6_LENGTH            19  #define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH  6 +/* PMSI tunnel types (RFC 6514) */ +  struct bgp_attr_encap_subtlv {  	struct bgp_attr_encap_subtlv *next; /* for chaining */  	/* Reference count of this attribute. */ @@ -96,6 +98,18 @@ struct overlay_index {  	union gw_addr gw_ip;  }; +enum pta_type { +	PMSI_TNLTYPE_NO_INFO = 0, +	PMSI_TNLTYPE_RSVP_TE_P2MP, +	PMSI_TNLTYPE_MLDP_P2MP, +	PMSI_TNLTYPE_PIM_SSM, +	PMSI_TNLTYPE_PIM_SM, +	PMSI_TNLTYPE_PIM_BIDIR, +	PMSI_TNLTYPE_INGR_REPL, +	PMSI_TNLTYPE_MLDP_MP2MP, +	PMSI_TNLTYPE_MAX = PMSI_TNLTYPE_MLDP_MP2MP +}; +  /* BGP core attribute structure. */  struct attr {  	/* AS Path structure */ @@ -119,6 +133,9 @@ struct attr {  	/* Path origin attribute */  	u_char origin; +	/* PMSI tunnel type (RFC 6514). */ +	enum pta_type pmsi_tnl_type; +  	/* has the route-map changed any attribute?  	   Used on the peer outbound side. */  	u_int32_t rmap_change_flags; diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 691cdd19d7..f867266956 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -162,7 +162,6 @@ static const struct message bgp_notify_capability_msg[] = {  const char *bgp_origin_str[] = {"i", "e", "?"};  const char *bgp_origin_long_str[] = {"IGP", "EGP", "incomplete"}; -  /* Given a string return a pointer the corresponding peer structure */  static struct peer *bgp_find_peer(struct vty *vty, const char *peer_str)  { @@ -417,6 +416,10 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size)  				 inet_ntoa(attr->cluster->list[i]));  	} +	if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) +		snprintf(buf + strlen(buf), size - strlen(buf), +			 ", pmsi tnltype %u", attr->pmsi_tnl_type); +  	if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))  		snprintf(buf + strlen(buf), size - strlen(buf), ", path %s",  			 aspath_print(attr->aspath)); diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index 57f8fef5f2..fe7ca8c46a 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -142,6 +142,7 @@ struct bgp_debug_filter {  #define CONF_BGP_DEBUG(a, b)    (conf_bgp_debug_ ## a & BGP_DEBUG_ ## b)  extern const char *bgp_type_str[]; +extern const char *pmsi_tnltype_str[];  extern int bgp_dump_attr(struct attr *, char *, size_t);  extern int bgp_debug_peer_updout_enabled(char *host); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index fc7549671e..94d9cb465b 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -475,6 +475,17 @@ static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)  }  /* + * Convert nexthop (remote VTEP IP) into an IPv6 address. + */ +static void evpn_convert_nexthop_to_ipv6(struct attr *attr) +{ +	if (BGP_ATTR_NEXTHOP_AFI_IP6(attr)) +		return; +	ipv4_to_ipv4_mapped_ipv6(&attr->mp_nexthop_global, attr->nexthop); +	attr->mp_nexthop_len = IPV6_MAX_BYTELEN; +} + +/*   * Add (update) or delete MACIP from zebra.   */  static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, @@ -622,17 +633,17 @@ static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,  }  /* - * Build extended communities for EVPN route. RT and ENCAP are - * applicable to all routes. - * TODO: currently kernel doesnt support ipv6 routes with ipv4 nexthops. - * This means that we can't do symmetric routing for ipv6 hosts routes - * in the same way as ipv4 host routes. - * We wont attach l3-vni related RTs for ipv6 routes. - * For now, We will only adevrtise ipv4 host routes - * with L3-VNI related ext-comm. + * Build extended communities for EVPN route. + * This function is applicable for type-2 and type-3 routes. The layer-2 RT + * and ENCAP extended communities are applicable for all routes. + * The default gateway extended community and MAC mobility (sticky) extended + * community are added as needed based on passed settings - only for type-2 + * routes. Likewise, the layer-3 RT and Router MAC extended communities are + * added, if present, based on passed settings - only for non-link-local + * type-2 routes.   */  static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, -				     afi_t afi) +				     int add_l3_ecomm)  {  	struct ecommunity ecom_encap;  	struct ecommunity ecom_sticky; @@ -662,11 +673,10 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,  	for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))  		attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom); -	/* -	 * only attach l3-vni export rts for ipv4 address family and if we are -	 * advertising both the labels in type-2 routes +	/* Add the export RTs for L3VNI if told to - caller determines +	 * when this should be done.  	 */ -	if (afi == AFI_IP && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { +	if (add_l3_ecomm) {  		vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);  		if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {  			for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, @@ -676,6 +686,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,  		}  	} +	/* Add MAC mobility (sticky) if needed. */  	if (attr->sticky) {  		seqnum = 0;  		memset(&ecom_sticky, 0, sizeof(ecom_sticky)); @@ -686,12 +697,8 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,  			ecommunity_merge(attr->ecommunity, &ecom_sticky);  	} -	/* -	 * only attach l3-vni rmac for ipv4 address family and if we are -	 * advertising both the labels in type-2 routes -	 */ -	if (afi == AFI_IP && !is_zero_mac(&attr->rmac) -	    && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { +	/* Add RMAC, if told to. */ +	if (add_l3_ecomm) {  		memset(&ecom_rmac, 0, sizeof(ecom_rmac));  		encode_rmac_extcomm(&eval_rmac, &attr->rmac);  		ecom_rmac.size = 1; @@ -700,6 +707,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,  			ecommunity_merge(attr->ecommunity, &ecom_rmac);  	} +	/* Add default gateway, if needed. */  	if (attr->default_gw) {  		memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));  		encode_default_gw_extcomm(&eval_default_gw); @@ -1260,6 +1268,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,  	struct bgp_node *rn;  	struct attr attr;  	struct attr *attr_new; +	int add_l3_ecomm = 0;  	struct bgp_info *ri;  	afi_t afi = AFI_L2VPN;  	safi_t safi = SAFI_EVPN; @@ -1279,14 +1288,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,  	if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)  		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL); -	/* router mac is only needed for type-2 and type-5  routes */ +	/* router mac is only needed for type-2 routes here. */  	if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)  		bgpevpn_get_rmac(vpn, &attr.rmac);  	vni2label(vpn->vni, &(attr.label)); -	/* Set up RT and ENCAP extended community. */ -	build_evpn_route_extcomm( -		vpn, &attr, IS_EVPN_PREFIX_IPADDR_V4(p) ? AFI_IP : AFI_IP6); +	/* Include L3 VNI related RTs and RMAC for type-2 routes, if they're +	 * IPv4 or IPv6 global addresses and we're advertising L3VNI with +	 * these routes. +	 */ +	if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && +	    (IS_EVPN_PREFIX_IPADDR_V4(p) || +	     !IN6_IS_ADDR_LINKLOCAL(&p->prefix.ip.ipaddr_v6)) && +	    CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) +		add_l3_ecomm = 1; + +	/* Set up extended community. */ +	build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);  	/* First, create (or fetch) route node within the VNI. */  	/* NOTE: There is no RD here. */ @@ -1466,22 +1484,20 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)  	struct attr attr;  	struct attr attr_sticky;  	struct attr attr_def_gw; -	struct attr attr_ip6; -	struct attr attr_sticky_ip6; -	struct attr attr_def_gw_ip6; +	struct attr attr_ip6_ll;  	struct attr *attr_new; +	int add_l3_ecomm = 0;  	afi = AFI_L2VPN;  	safi = SAFI_EVPN;  	memset(&attr, 0, sizeof(struct attr));  	memset(&attr_sticky, 0, sizeof(struct attr));  	memset(&attr_def_gw, 0, sizeof(struct attr)); -	memset(&attr_ip6, 0, sizeof(struct attr)); -	memset(&attr_sticky_ip6, 0, sizeof(struct attr)); -	memset(&attr_def_gw_ip6, 0, sizeof(struct attr)); +	memset(&attr_ip6_ll, 0, sizeof(struct attr)); -	/* Build path-attribute - all type-2 routes for this VNI will share the -	 * same path attribute. +	/* Build path-attribute - multiple type-2 routes for this VNI will share +	 * the same path attribute, but we need separate structures for sticky +	 * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).  	 */  	bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);  	bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP); @@ -1500,31 +1516,21 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)  	attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;  	attr_def_gw.default_gw = 1;  	bgpevpn_get_rmac(vpn, &attr_def_gw.rmac); -	bgp_attr_default_set(&attr_ip6, BGP_ORIGIN_IGP); -	bgp_attr_default_set(&attr_sticky_ip6, BGP_ORIGIN_IGP); -	bgp_attr_default_set(&attr_def_gw_ip6, BGP_ORIGIN_IGP); -	attr_ip6.nexthop = vpn->originator_ip; -	attr_ip6.mp_nexthop_global_in = vpn->originator_ip; -	attr_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; -	bgpevpn_get_rmac(vpn, &attr_ip6.rmac); -	attr_sticky_ip6.nexthop = vpn->originator_ip; -	attr_sticky_ip6.mp_nexthop_global_in = vpn->originator_ip; -	attr_sticky_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; -	attr_sticky_ip6.sticky = 1; -	bgpevpn_get_rmac(vpn, &attr_sticky_ip6.rmac); -	attr_def_gw_ip6.nexthop = vpn->originator_ip; -	attr_def_gw_ip6.mp_nexthop_global_in = vpn->originator_ip; -	attr_def_gw_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; -	attr_def_gw_ip6.default_gw = 1; -	bgpevpn_get_rmac(vpn, &attr_def_gw_ip6.rmac); - -	/* Set up RT, ENCAP and sticky MAC extended community. */ -	build_evpn_route_extcomm(vpn, &attr, AFI_IP); -	build_evpn_route_extcomm(vpn, &attr_sticky, AFI_IP); -	build_evpn_route_extcomm(vpn, &attr_def_gw, AFI_IP); -	build_evpn_route_extcomm(vpn, &attr_ip6, AFI_IP6); -	build_evpn_route_extcomm(vpn, &attr_sticky_ip6, AFI_IP6); -	build_evpn_route_extcomm(vpn, &attr_def_gw_ip6, AFI_IP); +	bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP); +	attr_ip6_ll.nexthop = vpn->originator_ip; +	attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip; +	attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; + +	/* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if +	 * using L3 VNI for type-2 routes also. +	 */ +	if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) +		add_l3_ecomm = 1; + +	build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm); +	build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm); +	build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm); +	build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0);  	/* Walk this VNI's route table and update local type-2 routes. For any  	 * routes updated, update corresponding entry in the global table too. @@ -1538,7 +1544,11 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)  		if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)  			continue; -		if (IS_EVPN_PREFIX_IPADDR_V4(evp)) { +		if (IS_EVPN_PREFIX_IPADDR_V6(evp) && +		    IN6_IS_ADDR_LINKLOCAL(&evp->prefix.ip.ipaddr_v6)) +			update_evpn_route_entry(bgp, vpn, afi, safi, rn, +						&attr_ip6_ll, 0, 1, &ri, 0); +		else {  			if (evpn_route_is_sticky(bgp, rn))  				update_evpn_route_entry(bgp, vpn, afi, safi, rn,  							&attr_sticky, 0, 1, &ri, @@ -1550,19 +1560,6 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)  			else  				update_evpn_route_entry(bgp, vpn, afi, safi, rn,  							&attr, 0, 1, &ri, 0); -		} else { -			if (evpn_route_is_sticky(bgp, rn)) -				update_evpn_route_entry(bgp, vpn, afi, safi, rn, -							&attr_sticky_ip6, 0, 1, -							&ri, 0); -			else if (evpn_route_is_def_gw(bgp, rn)) -				update_evpn_route_entry(bgp, vpn, afi, safi, rn, -							&attr_def_gw_ip6, 0, 1, -							&ri, 0); -			else -				update_evpn_route_entry(bgp, vpn, afi, safi, rn, -							&attr_ip6, 0, 1, &ri, -							0);  		}  		/* If a local route exists for this prefix, we need to update @@ -1593,11 +1590,9 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)  	/* Unintern temporary. */  	aspath_unintern(&attr.aspath); -	aspath_unintern(&attr_ip6.aspath);  	aspath_unintern(&attr_sticky.aspath); -	aspath_unintern(&attr_sticky_ip6.aspath);  	aspath_unintern(&attr_def_gw.aspath); -	aspath_unintern(&attr_def_gw_ip6.aspath); +	aspath_unintern(&attr_ip6_ll.aspath);  	return 0;  } @@ -1791,6 +1786,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,  {  	struct bgp_node *rn;  	struct bgp_info *ri; +	struct attr attr;  	struct attr *attr_new;  	int ret = 0;  	struct prefix p; @@ -1827,6 +1823,15 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,  	} else  		return 0; +	/* EVPN routes currently only support a IPv4 next hop which corresponds +	 * to the remote VTEP. When importing into a VRF, if it is IPv6 host +	 * route, we have to convert the next hop to an IPv4-mapped address +	 * for the rest of the code to flow through. +	 */ +	bgp_attr_dup(&attr, parent_ri->attr); +	if (afi == AFI_IP6) +		evpn_convert_nexthop_to_ipv6(&attr); +  	/* Check if route entry is already present. */  	for (ri = rn->info; ri; ri = ri->next)  		if (ri->extra @@ -1835,7 +1840,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,  	if (!ri) {  		/* Add (or update) attribute to hash. */ -		attr_new = bgp_attr_intern(parent_ri->attr); +		attr_new = bgp_attr_intern(&attr);  		/* Create new route with its attribute. */  		ri = info_make(parent_ri->type, parent_ri->sub_type, 0, @@ -1850,21 +1855,25 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,  		}  		bgp_info_add(rn, ri);  	} else { -		if (attrhash_cmp(ri->attr, parent_ri->attr) +		if (attrhash_cmp(ri->attr, &attr)  		    && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {  			bgp_unlock_node(rn);  			return 0;  		}  		/* The attribute has changed. */  		/* Add (or update) attribute to hash. */ -		attr_new = bgp_attr_intern(parent_ri->attr); +		attr_new = bgp_attr_intern(&attr);  		/* Restore route, if needed. */  		if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))  			bgp_info_restore(rn, ri);  		/* Mark if nexthop has changed. */ -		if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) +		if ((afi == AFI_IP && +		    !IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) || +		    (afi == AFI_IP6 && +		    !IPV6_ADDR_SAME(&ri->attr->mp_nexthop_global, +				    &attr_new->mp_nexthop_global)))  			SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);  		/* Unintern existing, set to new. */ @@ -2577,10 +2586,12 @@ static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,  static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)  {  	/* delete all ipv4 routes and withdraw from peers */ -	bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST); +	if (advertise_type5_routes(bgp_vrf, AFI_IP)) +		bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);  	/* delete all ipv6 routes and withdraw from peers */ -	bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST); +	if (advertise_type5_routes(bgp_vrf, AFI_IP6)) +		bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);  }  /* update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5 @@ -2588,10 +2599,12 @@ static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)  static void update_advertise_vrf_routes(struct bgp *bgp_vrf)  {  	/* update all ipv4 routes */ -	bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST); +	if (advertise_type5_routes(bgp_vrf, AFI_IP)) +		bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);  	/* update all ipv6 routes */ -	bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST); +	if (advertise_type5_routes(bgp_vrf, AFI_IP6)) +		bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);  }  /* @@ -2922,6 +2935,19 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,  		return -1;  	} +	/* If PMSI is present, log if it is anything other than IR. +	 * Note: We just simply ignore the values as it is not clear if +	 * doing anything else is better. +	 */ +	if (attr && +	    (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) { +		if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) { +			zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d", +				  peer->bgp->vrf_id, peer->host, +				  attr->pmsi_tnl_type); +		} +	} +  	/* Make prefix_rd */  	prd.family = AF_UNSPEC;  	prd.prefixlen = 64; @@ -3214,10 +3240,6 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,  	struct prefix_evpn evp;  	char buf[PREFIX_STRLEN]; -	/* NOTE: Check needed as this is called per-route also. */ -	if (!advertise_type5_routes(bgp_vrf, afi)) -		return; -  	build_type5_prefix_from_ip_prefix(&evp, p);  	ret = delete_evpn_type5_route(bgp_vrf, &evp);  	if (ret) { @@ -3235,10 +3257,6 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)  	struct bgp_node *rn = NULL;  	struct bgp_info *ri; -	/* Bail out early if we don't have to advertise type-5 routes. */ -	if (!advertise_type5_routes(bgp_vrf, afi)) -		return; -  	table = bgp_vrf->rib[afi][safi];  	for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {  		/* Only care about "selected" routes - non-imported. */ @@ -3267,11 +3285,7 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,  	int ret = 0;  	struct prefix_evpn evp;  	char buf[PREFIX_STRLEN]; - -	/* NOTE: Check needed as this is called per-route also. */ -	if (!advertise_type5_routes(bgp_vrf, afi)) -		return; - +    	build_type5_prefix_from_ip_prefix(&evp, p);  	ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);  	if (ret) @@ -3290,10 +3304,6 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,  	struct bgp_node *rn = NULL;  	struct bgp_info *ri; -	/* Bail out early if we don't have to advertise type-5 routes. */ -	if (!advertise_type5_routes(bgp_vrf, afi)) -		return; -  	table = bgp_vrf->rib[afi][safi];  	for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {  		/* Need to identify the "selected" route entry to use its diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index bf6150e648..7c0d638327 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -55,6 +55,25 @@ static inline vni_t label2vni(mpls_label_t *label)  	return vni;  } +static inline int advertise_type5_routes(struct bgp *bgp_vrf, +					 afi_t afi) +{ +	if (!bgp_vrf->l3vni) +		return 0; + +	if (afi == AFI_IP && +	    CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) +		return 1; + +	if (afi == AFI_IP6 && +	    CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) +		return 1; + +	return 0; +} +  extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,  					   struct prefix *p,  					   struct attr *src_attr, afi_t afi, diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 63dd581845..ce279005dc 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -285,6 +285,14 @@ static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,  	}  } +static inline int is_evpn_prefix_default(struct prefix *evp) +{ +	if (evp->family != AF_EVPN) +		return 0; + +	return ((evp->u.prefix_evpn.ip_prefix_length  == 0) ? 1 : 0); +} +  static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,  					       struct prefix *ip)  { @@ -352,19 +360,17 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,  	p->prefix.ip.ipaddr_v4 = originator_ip;  } -static inline int advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi) +static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi, +					     safi_t safi)  { -	if (!bgp_vrf->l3vni) -		return 0; - -	if (afi == AFI_IP -	    && CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) +	if (afi == AFI_IP && +	    CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))  		return 1; - -	if (afi == AFI_IP6 -	    && CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) +	else if (afi == AFI_IP6 && +		 CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], +			    BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))  		return 1; -  	return 0;  } diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index d42da23f52..58487a682c 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -2419,7 +2419,50 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,  /*   * evpn - enable advertisement of default g/w   */ -static void evpn_set_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn) +static void evpn_process_default_originate_cmd(struct bgp *bgp_vrf, +					       afi_t afi, int add) +{ +	struct prefix ip_prefix; +	safi_t safi = SAFI_UNICAST; /* ipv4/ipv6 unicast */ + +	/* form the default prefix 0.0.0.0/0 */ +	memset(&ip_prefix, 0, sizeof(struct prefix)); +	ip_prefix.family = afi2family(afi); +	ip_prefix.prefixlen = 0; + +	if (add) { +		/* bail if we are already advertising default route */ +		if (evpn_default_originate_set(bgp_vrf, afi, safi)) +			return; + +		if (afi == AFI_IP) +			SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +				 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4); +		else if (afi == AFI_IP6) +			SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +				 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6); +		bgp_evpn_advertise_type5_route(bgp_vrf, &ip_prefix, +					       NULL, afi, safi); +	} else { +		/* bail out if we havent advertised the default route */ +		if (!evpn_default_originate_set(bgp_vrf, afi, safi)) +			return; +		if (afi == AFI_IP) +			UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +				   BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4); +		else if (afi == AFI_IP6) +			UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +				   BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6); +		bgp_evpn_withdraw_type5_route(bgp_vrf, &ip_prefix, +					      afi, safi); +	} +} + +/* + * evpn - enable advertisement of default g/w + */ +static void evpn_set_advertise_subnet(struct bgp *bgp, +				      struct bgpevpn *vpn)  {  	if (vpn->advertise_subnet)  		return; @@ -2612,6 +2655,43 @@ DEFUN (no_bgp_evpn_advertise_all_vni,  	return CMD_SUCCESS;  } +DEFUN (bgp_evpn_default_originate, +       bgp_evpn_default_originate_cmd, +       "default-originate <ipv4 | ipv6>", +       "originate a default route\n" +       "ipv4 address family\n" +       "ipv6 address family\n") +{ +	afi_t afi = 0; +	int idx_afi = 0; +	struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); + +	if (!bgp_vrf) +		return CMD_WARNING; +	argv_find_and_parse_afi(argv, argc, &idx_afi, &afi); +	evpn_process_default_originate_cmd(bgp_vrf, afi, 1); +	return CMD_SUCCESS; +} + +DEFUN (no_bgp_evpn_default_originate, +       no_bgp_evpn_default_originate_cmd, +       "no default-originate <ipv4 | ipv6>", +       NO_STR +       "withdraw a default route\n" +       "ipv4 address family\n" +       "ipv6 address family\n") +{ +	afi_t afi = 0; +	int idx_afi = 0; +	struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); + +	if (!bgp_vrf) +		return CMD_WARNING; +	argv_find_and_parse_afi(argv, argc, &idx_afi, &afi); +	evpn_process_default_originate_cmd(bgp_vrf, afi, 0); +	return CMD_SUCCESS; +} +  DEFUN (bgp_evpn_advertise_vni_subnet,         bgp_evpn_advertise_vni_subnet_cmd,         "advertise-subnet", @@ -2631,14 +2711,6 @@ DEFUN (bgp_evpn_advertise_vni_subnet,  	if (!bgp_vrf)  		return CMD_WARNING; -	if (!(advertise_type5_routes(bgp_vrf, AFI_IP) -	      || advertise_type5_routes(bgp_vrf, AFI_IP6))) { -		vty_out(vty, -			"%%Please enable ip prefix advertisement under l2vpn evpn in %s", -			vrf_id_to_name(bgp_vrf->vrf_id)); -		return CMD_WARNING; -	} -  	evpn_set_advertise_subnet(bgp, vpn);  	return CMD_SUCCESS;  } @@ -2711,19 +2783,23 @@ DEFUN (bgp_evpn_advertise_type5,  		/* if we are already advertising ipv4 prefix as type-5  		 * nothing to do  		 */ -		if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, -						BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) +		if (!rmap_changed && +		    CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +			       BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))  			return CMD_WARNING; -		SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN); +		SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +			 BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);  	} else {  		/* if we are already advertising ipv6 prefix as type-5  		 * nothing to do  		 */ -		if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, -						BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) +		if (!rmap_changed && +		    CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +			       BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))  			return CMD_WARNING; -		SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN); +		SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +			 BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);  	}  	if (rmap_changed) { @@ -2766,7 +2842,7 @@ DEFUN (no_bgp_evpn_advertise_type5,  	argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);  	argv_find_and_parse_safi(argv, argc, &idx_safi, &safi); -	if (!(afi == AFI_IP) || (afi == AFI_IP6)) { +	if (!(afi == AFI_IP || afi == AFI_IP6)) {  		vty_out(vty,  			"%%only ipv4 or ipv6 address families are supported");  		return CMD_WARNING; @@ -2780,25 +2856,25 @@ DEFUN (no_bgp_evpn_advertise_type5,  	if (afi == AFI_IP) { -		/* if we are already advertising ipv4 prefix as type-5 +		/* if we are not advertising ipv4 prefix as type-5  		 * nothing to do  		 */ -		if (CHECK_FLAG(bgp_vrf->vrf_flags, -			       BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) { +		if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +			       BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {  			bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi); -			UNSET_FLAG(bgp_vrf->vrf_flags, -				   BGP_VRF_ADVERTISE_IPV4_IN_EVPN); +			UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +				   BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);  		}  	} else { -		/* if we are already advertising ipv6 prefix as type-5 +		/* if we are not advertising ipv6 prefix as type-5  		 * nothing to do  		 */ -		if (CHECK_FLAG(bgp_vrf->vrf_flags, -			       BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) { +		if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], +			       BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {  			bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);  			UNSET_FLAG(bgp_vrf->vrf_flags, -				   BGP_VRF_ADVERTISE_IPV6_IN_EVPN); +				   BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);  		}  	} @@ -4305,12 +4381,22 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,  	if (bgp->advertise_gw_macip)  		vty_out(vty, "  advertise-default-gw\n"); -	if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) +	if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))  		vty_out(vty, "  advertise ipv4 unicast\n"); -	if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) +	if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))  		vty_out(vty, "  advertise ipv6 unicast\n"); +	if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4)) +		vty_out(vty, "  default-originate ipv4\n"); + +	if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], +		       BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6)) +		vty_out(vty, "  default-originate ipv6\n"); +  	if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))  		vty_out(vty, "   rd %s\n",  			prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1))); @@ -4373,6 +4459,8 @@ void bgp_ethernetvpn_init(void)  	install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);  	install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);  	install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd); +	install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd); +	install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);  	/* "show bgp l2vpn evpn" commands. */  	install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 26f96d684a..032b33229c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -82,6 +82,21 @@  extern const char *bgp_origin_str[];  extern const char *bgp_origin_long_str[]; +/* PMSI strings. */ +#define PMSI_TNLTYPE_STR_NO_INFO "No info" +#define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO +static const struct message bgp_pmsi_tnltype_str[] = { +	{PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO}, +	{PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"}, +	{PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"}, +	{PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"}, +	{PMSI_TNLTYPE_PIM_SM, "PIM-SM"}, +	{PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"}, +	{PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"}, +	{PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"}, +	{0} +}; +  struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,  				  safi_t safi, struct prefix *p,  				  struct prefix_rd *prd) @@ -2285,12 +2300,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,  	/* advertise/withdraw type-5 routes */  	if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { -		if (new_select -		    && (!new_select->extra || !new_select->extra->parent)) -			bgp_evpn_advertise_type5_route( -				bgp, &rn->p, new_select->attr, afi, safi); -		else if (old_select -			 && (!old_select->extra || !old_select->extra->parent)) +		if (advertise_type5_routes(bgp, afi) && new_select && +		    (!new_select->extra || !new_select->extra->parent)) +			bgp_evpn_advertise_type5_route(bgp, &rn->p, +						       new_select->attr, +						       afi, safi); +		else if (advertise_type5_routes(bgp, afi) && old_select && +		         (!old_select->extra || !old_select->extra->parent))  			bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);  	} @@ -7197,6 +7213,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,  	json_object *json_ext_community = NULL;  	json_object *json_lcommunity = NULL;  	json_object *json_last_update = NULL; +	json_object *json_pmsi = NULL;  	json_object *json_nexthop_global = NULL;  	json_object *json_nexthop_ll = NULL;  	json_object *json_nexthops = NULL; @@ -7949,6 +7966,24 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,  					       json_last_update);  		} else  			vty_out(vty, "      Last update: %s", ctime(&tbuf)); + +		/* Line 10 display PMSI tunnel attribute, if present */ +		if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) { +			const char *str = lookup_msg(bgp_pmsi_tnltype_str, +						     attr->pmsi_tnl_type, +						     PMSI_TNLTYPE_STR_DEFAULT); + +			if (json_paths) { +				json_pmsi = json_object_new_object(); +				json_object_string_add(json_pmsi, +						       "tunnelType", str); +				json_object_object_add(json_path, "pmsi", +						       json_pmsi); +			} else +				vty_out(vty, "      PMSI Tunnel Type: %s\n", +					str); +		} +  	}  	/* We've constructed the json object for this path, add it to the json diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index b79c6a7c3a..5a265b6c9c 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -595,6 +595,24 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {  	route_match_ip_route_source_prefix_list_compile,  	route_match_ip_route_source_prefix_list_free}; +/* `match evpn default-route' */ + +/* Match function should return 1 if match is success else 0 */ +static route_map_result_t route_match_evpn_default_route(void *rule, +							 struct prefix *p, +							 route_map_object_t +							 type, void *object) +{ +	if (type == RMAP_BGP && is_evpn_prefix_default(p)) +		return RMAP_MATCH; + +	return RMAP_NOMATCH; +} + +/* Route map commands for default-route matching. */ +struct route_map_rule_cmd route_match_evpn_default_route_cmd = { +	"evpn default-route", route_match_evpn_default_route, NULL, NULL}; +  /* `match mac address MAC_ACCESS_LIST' */  /* Match function should return 1 if match is success else return @@ -3254,6 +3272,29 @@ DEFUN (no_match_evpn_vni,  				      RMAP_EVENT_MATCH_DELETED);  } +DEFUN (match_evpn_default_route, +       match_evpn_default_route_cmd, +       "match evpn default-route", +       MATCH_STR +       EVPN_HELP_STR +       "default EVPN type-5 route\n") +{ +	return bgp_route_match_add(vty, "evpn default-route", NULL, +				   RMAP_EVENT_MATCH_ADDED); +} + +DEFUN (no_match_evpn_default_route, +       no_match_evpn_default_route_cmd, +       "no match evpn default-route", +       NO_STR +       MATCH_STR +       EVPN_HELP_STR +       "default EVPN type-5 route\n") +{ +	return bgp_route_match_delete(vty, "evpn default-route", NULL, +				      RMAP_EVENT_MATCH_DELETED); +} +  DEFUN (match_peer,         match_peer_cmd,         "match peer <A.B.C.D|X:X::X:X|WORD>", @@ -4633,6 +4674,7 @@ void bgp_route_map_init(void)  	route_map_install_match(&route_match_mac_address_cmd);  	route_map_install_match(&route_match_evpn_vni_cmd);  	route_map_install_match(&route_match_evpn_route_type_cmd); +	route_map_install_match(&route_match_evpn_default_route_cmd);  	route_map_install_set(&route_set_ip_nexthop_cmd);  	route_map_install_set(&route_set_local_pref_cmd); @@ -4669,6 +4711,8 @@ void bgp_route_map_init(void)  	install_element(RMAP_NODE, &no_match_evpn_vni_cmd);  	install_element(RMAP_NODE, &match_evpn_route_type_cmd);  	install_element(RMAP_NODE, &no_match_evpn_route_type_cmd); +	install_element(RMAP_NODE, &match_evpn_default_route_cmd); +	install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);  	install_element(RMAP_NODE, &match_aspath_cmd);  	install_element(RMAP_NODE, &no_match_aspath_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e7d58a021b..2eae2e5e9e 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7534,16 +7534,14 @@ static void bgp_pthreads_init()  		.id = PTHREAD_IO,  		.start = frr_pthread_attr_default.start,  		.stop = frr_pthread_attr_default.stop, -		.name = "BGP I/O thread",  	};  	struct frr_pthread_attr ka = {  		.id = PTHREAD_KEEPALIVES,  		.start = bgp_keepalives_start,  		.stop = bgp_keepalives_stop, -		.name = "BGP Keepalives thread",  	}; -	frr_pthread_new(&io); -	frr_pthread_new(&ka); +	frr_pthread_new(&io, "BGP I/O thread"); +	frr_pthread_new(&ka, "BGP Keepalives thread");  }  void bgp_pthreads_run() diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 41ae8e916f..664f8c9da4 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -319,6 +319,13 @@ struct bgp {  #define BGP_CONFIG_DAMPENING              (1 << 0)  #define BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT  (1 << 1) +/* l2vpn evpn flags - 1 << 0 is used for DAMPENNG */ +#define BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST      (1 << 1) +#define BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST      (1 << 2) +#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4	   (1 << 3) +#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6	   (1 << 4) + +  	/* Route table for next-hop lookup cache. */  	struct bgp_table *nexthop_cache_table[AFI_MAX]; @@ -430,12 +437,11 @@ struct bgp {  	/* vrf flags */  	uint32_t vrf_flags;  #define BGP_VRF_AUTO                        (1 << 0) -#define BGP_VRF_ADVERTISE_IPV4_IN_EVPN      (1 << 1) -#define BGP_VRF_ADVERTISE_IPV6_IN_EVPN      (1 << 2) -#define BGP_VRF_IMPORT_RT_CFGD              (1 << 3) -#define BGP_VRF_EXPORT_RT_CFGD              (1 << 4) -#define BGP_VRF_RD_CFGD                     (1 << 5) -#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY    (1 << 6) +#define BGP_VRF_IMPORT_RT_CFGD              (1 << 1) +#define BGP_VRF_EXPORT_RT_CFGD              (1 << 2) +#define BGP_VRF_RD_CFGD                     (1 << 3) +#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY    (1 << 4) +  	/* unique ID for auto derivation of RD for this vrf */  	uint16_t vrf_rd_id;  | 
