diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2022-08-17 11:52:51 +0200 | 
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2022-09-05 22:26:33 +0200 | 
| commit | 4cd690ae4d16814b0d5098764790578dab39e4a2 (patch) | |
| tree | 0754d947ea06e91e54de83c82c1d18601c5f4344 /bgpd/bgp_nht.c | |
| parent | 6e616738caa4a310d692660d23f96ab8dc77d672 (diff) | |
bgpd: add 'mpls bgp forwarding' to ease mpls vpn ebgp peering
RFC4364 describes peerings between multiple AS domains, to ease
the continuity of VPN services across multiple SPs. This commit
implements a sub-set of IETF option b) described in chapter 10 b.
The ASBR to ASBR approach is taken, with an EBGP peering between
the two routers. The EBGP peering must be directly connected to
the outgoing interface used. In those conditions, the next hop
is directly connected, and there is no need to have a transport
label to convey the VPN label. A new vty command is added on a
per interface basis:
This command if enabled, will permit to convey BGP VPN labels
without any transport labels (i.e. with implicit-null label).
restriction:
this command is used only for EBGP directly connected peerings.
Other use cases are not covered.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd/bgp_nht.c')
| -rw-r--r-- | bgpd/bgp_nht.c | 37 | 
1 files changed, 37 insertions, 0 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 297623365a..b38e5b7a9a 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -61,6 +61,42 @@ static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)  		    && bnc->nexthop_num > 0));  } +static int bgp_isvalid_nexthop_for_ebgp(struct bgp_nexthop_cache *bnc, +					struct bgp_path_info *path) +{ +	struct interface *ifp = NULL; +	struct nexthop *nexthop; +	struct bgp_interface *iifp; +	struct peer *peer; + +	if (!path->extra || !path->extra->peer_orig) +		return false; + +	peer = path->extra->peer_orig; + +	/* only connected ebgp peers are valid */ +	if (peer->sort != BGP_PEER_EBGP || peer->ttl != BGP_DEFAULT_TTL || +	    CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK) || +	    CHECK_FLAG(peer->bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) +		return false; + +	for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next) { +		if (nexthop->type == NEXTHOP_TYPE_IFINDEX || +		    nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX || +		    nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +			ifp = if_lookup_by_index( +				bnc->ifindex ? bnc->ifindex : nexthop->ifindex, +				bnc->bgp->vrf_id); +		} +		if (!ifp) +			continue; +		iifp = ifp->info; +		if (CHECK_FLAG(iifp->flags, BGP_INTERFACE_MPLS_BGP_FORWARDING)) +			return true; +	} +	return false; +} +  static int bgp_isvalid_nexthop_for_mplsovergre(struct bgp_nexthop_cache *bnc,  					       struct bgp_path_info *path)  { @@ -105,6 +141,7 @@ static int bgp_isvalid_nexthop_for_mpls(struct bgp_nexthop_cache *bnc,  		(bnc && (bnc->nexthop_num > 0 &&  			 (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_LABELED_VALID) ||  			  bnc->bgp->srv6_enabled || +			  bgp_isvalid_nexthop_for_ebgp(bnc, path) ||  			  bgp_isvalid_nexthop_for_mplsovergre(bnc, path)))));  }  | 
