summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2023-02-16 10:39:40 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2023-03-22 12:06:29 +0100
commitaa274376040e216710560b230fa473ea5f922ac2 (patch)
tree78867a66b15526c47b801e1b80afed9e297e6a7c /bgpd
parentbgpd: add support for l3vpn per-nexthop label (diff)
downloadfrr-aa274376040e216710560b230fa473ea5f922ac2.tar.xz
frr-aa274376040e216710560b230fa473ea5f922ac2.zip
bgpd: use nexthop interface when adding LSP in BGP MPLSVPN
BGP MPLSVPN next hop label allocation was using only the next-hop IP address. As MPLSVPN contexts rely on bnc contexts, the real nexthop interface is known, and the LSP entry to enter can apply to the specific interface. To illustrate, the BGP service is able to handle the following two iproute2 commands: > ip -f mpls route add 105 via inet 192.0.2.45 dev r1-eth1 > ip -f mpls route add 105 via inet 192.0.2.46 dev r1-eth2 Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_labelpool.c6
-rw-r--r--bgpd/bgp_labelpool.h5
-rw-r--r--bgpd/bgp_mplsvpn.c20
-rw-r--r--bgpd/bgp_zebra.c12
-rw-r--r--bgpd/bgp_zebra.h1
5 files changed, 38 insertions, 6 deletions
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index 4d7019993..1b9a7e1ae 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -1606,10 +1606,14 @@ void bgp_label_per_nexthop_free(struct bgp_label_per_nexthop_cache *blnc)
{
if (blnc->label != MPLS_INVALID_LABEL) {
bgp_zebra_send_nexthop_label(ZEBRA_MPLS_LABELS_DELETE,
- blnc->label, ZEBRA_LSP_BGP,
+ blnc->label, blnc->nh->ifindex,
+ blnc->nh->vrf_id, ZEBRA_LSP_BGP,
&blnc->nexthop);
bgp_lp_release(LP_TYPE_NEXTHOP, blnc, blnc->label);
}
bgp_label_per_nexthop_cache_del(blnc->tree, blnc);
+ if (blnc->nh)
+ nexthop_free(blnc->nh);
+ blnc->nh = NULL;
XFREE(MTYPE_LABEL_PER_NEXTHOP_CACHE, blnc);
}
diff --git a/bgpd/bgp_labelpool.h b/bgpd/bgp_labelpool.h
index fd3656068..c26d9cd8c 100644
--- a/bgpd/bgp_labelpool.h
+++ b/bgpd/bgp_labelpool.h
@@ -66,6 +66,11 @@ struct bgp_label_per_nexthop_cache {
/* back pointer to bgp instance */
struct bgp *to_bgp;
+ /* copy a nexthop resolution from bgp nexthop tracking
+ * used to extract the interface nexthop
+ */
+ struct nexthop *nh;
+
/* list of path_vrfs using it */
LIST_HEAD(path_lists, bgp_path_info) paths;
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 01081ff11..dfa275036 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1388,8 +1388,9 @@ static int bgp_mplsvpn_get_label_per_nexthop_cb(mpls_label_t label,
/* update paths */
if (blnc->label != MPLS_INVALID_LABEL)
- bgp_zebra_send_nexthop_label(ZEBRA_MPLS_LABELS_ADD, blnc->label,
- ZEBRA_LSP_BGP, &blnc->nexthop);
+ bgp_zebra_send_nexthop_label(
+ ZEBRA_MPLS_LABELS_ADD, blnc->label, blnc->nh->ifindex,
+ blnc->nh->vrf_id, ZEBRA_LSP_BGP, &blnc->nexthop);
LIST_FOREACH (pi, &(blnc->paths), label_nh_thread) {
if (!pi->net)
@@ -1470,6 +1471,21 @@ static mpls_label_t _vpn_leak_from_vrf_get_per_nexthop_label(
pi->label_nexthop_cache = blnc;
pi->label_nexthop_cache->path_count++;
}
+
+ /* then add or update the selected nexthop */
+ if (!blnc->nh)
+ blnc->nh = nexthop_dup(bnc->nexthop, NULL);
+ else if (!nexthop_same(bnc->nexthop, blnc->nh)) {
+ nexthop_free(blnc->nh);
+ blnc->nh = nexthop_dup(bnc->nexthop, NULL);
+ if (blnc->label != MPLS_INVALID_LABEL) {
+ bgp_zebra_send_nexthop_label(
+ ZEBRA_MPLS_LABELS_REPLACE, blnc->label,
+ bnc->nexthop->ifindex, bnc->nexthop->vrf_id,
+ ZEBRA_LSP_BGP, &blnc->nexthop);
+ }
+ }
+
return blnc->label;
}
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index e8455741e..6259ad7ea 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -3892,6 +3892,7 @@ int bgp_zebra_srv6_manager_release_locator_chunk(const char *name)
}
void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
+ ifindex_t ifindex, vrf_id_t vrf_id,
enum lsp_types_t ltype, struct prefix *p)
{
struct zapi_labels zl = {};
@@ -3905,9 +3906,14 @@ void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
IPV4_ADDR_COPY(&znh->gate.ipv4, &p->u.prefix4);
else
IPV6_ADDR_COPY(&znh->gate.ipv6, &p->u.prefix6);
- znh->type =
- (p->family == AF_INET) ? NEXTHOP_TYPE_IPV4 : NEXTHOP_TYPE_IPV6;
- znh->ifindex = 0;
+ if (ifindex == IFINDEX_INTERNAL)
+ znh->type = (p->family == AF_INET) ? NEXTHOP_TYPE_IPV4
+ : NEXTHOP_TYPE_IPV6;
+ else
+ znh->type = (p->family == AF_INET) ? NEXTHOP_TYPE_IPV4_IFINDEX
+ : NEXTHOP_TYPE_IPV6_IFINDEX;
+ znh->ifindex = ifindex;
+ znh->vrf_id = vrf_id;
znh->label_num = 0;
/* vrf_id is DEFAULT_VRF */
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index d065f7e72..ff5e6ddbf 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -120,6 +120,7 @@ extern int bgp_zebra_stale_timer_update(struct bgp *bgp);
extern int bgp_zebra_srv6_manager_get_locator_chunk(const char *name);
extern int bgp_zebra_srv6_manager_release_locator_chunk(const char *name);
extern void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
+ ifindex_t index, vrf_id_t vrfid,
enum lsp_types_t ltype,
struct prefix *p);
#endif /* _QUAGGA_BGP_ZEBRA_H */