mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-16 14:00:29 +00:00
bgpd: update the mpls entry to handle return traffic
When advertising an mpls vpn entry with a new label, the return traffic is redirected to the local machine, but the MPLS traffic is dropped. Add an MPLS entry to handle MPLS packets which have the new label value. Traffic is swapped to the original label value from the mpls vpn next-hop entry; then it is sent to the resolved next-hop of the original next-hop from the mpls vpn next-hop entry. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
98c615f05a
commit
27f4deed0a
@ -1730,7 +1730,7 @@ void bgp_label_per_nexthop_free(struct bgp_label_per_nexthop_cache *blnc)
|
||||
bgp_zebra_send_nexthop_label(ZEBRA_MPLS_LABELS_DELETE,
|
||||
blnc->label, blnc->nh->ifindex,
|
||||
blnc->nh->vrf_id, ZEBRA_LSP_BGP,
|
||||
&blnc->nexthop);
|
||||
&blnc->nexthop, 0, NULL);
|
||||
bgp_lp_release(LP_TYPE_NEXTHOP, blnc, blnc->label);
|
||||
}
|
||||
bgp_label_per_nexthop_cache_del(blnc->tree, blnc);
|
||||
|
@ -1390,9 +1390,10 @@ 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, blnc->nh->ifindex,
|
||||
blnc->nh->vrf_id, 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, 0, NULL);
|
||||
|
||||
LIST_FOREACH (pi, &(blnc->paths), mplsvpn.blnc.label_nh_thread) {
|
||||
if (!pi->net)
|
||||
@ -1486,7 +1487,7 @@ _vpn_leak_from_vrf_get_per_nexthop_label(struct bgp_path_info *pi,
|
||||
bgp_zebra_send_nexthop_label(
|
||||
ZEBRA_MPLS_LABELS_REPLACE, blnc->label,
|
||||
bnc->nexthop->ifindex, bnc->nexthop->vrf_id,
|
||||
ZEBRA_LSP_BGP, &blnc->nexthop);
|
||||
ZEBRA_LSP_BGP, &blnc->nexthop, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3885,6 +3886,68 @@ int bgp_mplsvpn_nh_label_bind_cmp(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bgp_mplsvpn_nh_label_bind_send_nexthop_label(
|
||||
struct bgp_mplsvpn_nh_label_bind_cache *bmnc, int cmd)
|
||||
{
|
||||
struct prefix pfx_nh, *p = NULL;
|
||||
uint32_t num_labels = 0, lsp_num_labels;
|
||||
mpls_label_t label[MPLS_MAX_LABELS];
|
||||
struct nexthop *nh;
|
||||
ifindex_t ifindex = IFINDEX_INTERNAL;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
uint32_t i;
|
||||
|
||||
if (bmnc->nh == NULL)
|
||||
return;
|
||||
nh = bmnc->nh;
|
||||
switch (nh->type) {
|
||||
case NEXTHOP_TYPE_IFINDEX:
|
||||
p = &bmnc->nexthop;
|
||||
label[num_labels] = bmnc->orig_label;
|
||||
num_labels += 1;
|
||||
ifindex = nh->ifindex;
|
||||
vrf_id = nh->vrf_id;
|
||||
break;
|
||||
case NEXTHOP_TYPE_IPV4:
|
||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||
case NEXTHOP_TYPE_IPV6:
|
||||
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||
if (nh->type == NEXTHOP_TYPE_IPV4 ||
|
||||
nh->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
|
||||
pfx_nh.family = AF_INET;
|
||||
pfx_nh.prefixlen = IPV4_MAX_BITLEN;
|
||||
IPV4_ADDR_COPY(&pfx_nh.u.prefix4, &nh->gate.ipv4);
|
||||
} else {
|
||||
pfx_nh.family = AF_INET6;
|
||||
pfx_nh.prefixlen = IPV6_MAX_BITLEN;
|
||||
IPV6_ADDR_COPY(&pfx_nh.u.prefix6, &nh->gate.ipv6);
|
||||
}
|
||||
p = &pfx_nh;
|
||||
if (nh->nh_label) {
|
||||
if (nh->nh_label->num_labels >
|
||||
MPLS_MAX_LABELS - num_labels)
|
||||
lsp_num_labels = MPLS_MAX_LABELS - num_labels;
|
||||
else
|
||||
lsp_num_labels = nh->nh_label->num_labels;
|
||||
for (i = 0; i < lsp_num_labels; i++)
|
||||
label[num_labels + i] = nh->nh_label->label[i];
|
||||
num_labels += lsp_num_labels;
|
||||
}
|
||||
label[num_labels] = bmnc->orig_label;
|
||||
num_labels += 1;
|
||||
if (nh->type == NEXTHOP_TYPE_IPV4_IFINDEX ||
|
||||
nh->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
|
||||
ifindex = nh->ifindex;
|
||||
vrf_id = nh->vrf_id;
|
||||
}
|
||||
break;
|
||||
case NEXTHOP_TYPE_BLACKHOLE:
|
||||
return;
|
||||
}
|
||||
bgp_zebra_send_nexthop_label(cmd, bmnc->new_label, ifindex, vrf_id,
|
||||
ZEBRA_LSP_BGP, p, num_labels, &label[0]);
|
||||
}
|
||||
|
||||
void bgp_mplsvpn_nh_label_bind_free(
|
||||
struct bgp_mplsvpn_nh_label_bind_cache *bmnc)
|
||||
{
|
||||
@ -3894,8 +3957,11 @@ void bgp_mplsvpn_nh_label_bind_free(
|
||||
&bmnc->bgp_vpn->mplsvpn_nh_label_bind, bmnc);
|
||||
return;
|
||||
}
|
||||
if (bmnc->new_label != MPLS_INVALID_LABEL)
|
||||
if (bmnc->new_label != MPLS_INVALID_LABEL) {
|
||||
bgp_mplsvpn_nh_label_bind_send_nexthop_label(
|
||||
bmnc, ZEBRA_MPLS_LABELS_DELETE);
|
||||
bgp_lp_release(LP_TYPE_BGP_L3VPN_BIND, bmnc, bmnc->new_label);
|
||||
}
|
||||
bgp_mplsvpn_nh_label_bind_cache_del(
|
||||
&bmnc->bgp_vpn->mplsvpn_nh_label_bind, bmnc);
|
||||
XFREE(MTYPE_MPLSVPN_NH_LABEL_BIND_CACHE, bmnc);
|
||||
@ -4003,7 +4069,14 @@ static int bgp_mplsvpn_nh_label_bind_get_local_label_cb(mpls_label_t label,
|
||||
}
|
||||
bmnc->allocation_in_progress = false;
|
||||
|
||||
/* Create MPLS entry with new_label */
|
||||
if (bmnc->new_label != MPLS_INVALID_LABEL)
|
||||
/*
|
||||
* Create the LSP : <local_label -> bmnc->orig_label,
|
||||
* via bmnc->prefix, interface bnc->nexthop->ifindex
|
||||
*/
|
||||
bgp_mplsvpn_nh_label_bind_send_nexthop_label(
|
||||
bmnc, ZEBRA_MPLS_LABELS_ADD);
|
||||
|
||||
LIST_FOREACH (pi, &(bmnc->paths), mplsvpn.bmnc.nh_label_bind_thread) {
|
||||
/* we can advertise it */
|
||||
if (!pi->net)
|
||||
@ -4078,4 +4151,13 @@ void bgp_mplsvpn_nh_label_bind_register_local_label(struct bgp *bgp,
|
||||
}
|
||||
|
||||
/* Add or update the selected nexthop */
|
||||
if (!bmnc->nh)
|
||||
bmnc->nh = nexthop_dup(pi->nexthop->nexthop, NULL);
|
||||
else if (!nexthop_same(pi->nexthop->nexthop, bmnc->nh)) {
|
||||
nexthop_free(bmnc->nh);
|
||||
bmnc->nh = nexthop_dup(pi->nexthop->nexthop, NULL);
|
||||
if (bmnc->new_label != MPLS_INVALID_LABEL)
|
||||
bgp_mplsvpn_nh_label_bind_send_nexthop_label(
|
||||
bmnc, ZEBRA_MPLS_LABELS_REPLACE);
|
||||
}
|
||||
}
|
||||
|
@ -349,6 +349,9 @@ struct bgp_mplsvpn_nh_label_bind_cache {
|
||||
struct prefix nexthop;
|
||||
mpls_label_t orig_label;
|
||||
|
||||
/* resolved interface for the paths */
|
||||
struct nexthop *nh;
|
||||
|
||||
/* number of mplsvpn path */
|
||||
unsigned int path_count;
|
||||
|
||||
|
@ -3914,10 +3914,13 @@ 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)
|
||||
enum lsp_types_t ltype, struct prefix *p,
|
||||
uint32_t num_labels,
|
||||
mpls_label_t out_labels[])
|
||||
{
|
||||
struct zapi_labels zl = {};
|
||||
struct zapi_nexthop *znh;
|
||||
int i = 0;
|
||||
|
||||
zl.type = ltype;
|
||||
zl.local_label = label;
|
||||
@ -3935,8 +3938,16 @@ void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
|
||||
: NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||
znh->ifindex = ifindex;
|
||||
znh->vrf_id = vrf_id;
|
||||
znh->label_num = 0;
|
||||
|
||||
if (num_labels == 0)
|
||||
znh->label_num = 0;
|
||||
else {
|
||||
if (num_labels > MPLS_MAX_LABELS)
|
||||
znh->label_num = MPLS_MAX_LABELS;
|
||||
else
|
||||
znh->label_num = num_labels;
|
||||
for (i = 0; i < znh->label_num; i++)
|
||||
znh->labels[i] = out_labels[i];
|
||||
}
|
||||
/* vrf_id is DEFAULT_VRF */
|
||||
zebra_send_mpls_labels(zclient, cmd, &zl);
|
||||
}
|
||||
|
@ -121,5 +121,6 @@ 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);
|
||||
struct prefix *p, uint32_t num_labels,
|
||||
mpls_label_t out_labels[]);
|
||||
#endif /* _QUAGGA_BGP_ZEBRA_H */
|
||||
|
Loading…
Reference in New Issue
Block a user