summaryrefslogtreecommitdiff
path: root/bgpd/bgp_nht.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2022-08-17 11:52:51 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2022-09-05 22:26:33 +0200
commit4cd690ae4d16814b0d5098764790578dab39e4a2 (patch)
tree0754d947ea06e91e54de83c82c1d18601c5f4344 /bgpd/bgp_nht.c
parent6e616738caa4a310d692660d23f96ab8dc77d672 (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.c37
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)))));
}