When acting as intermediate device for BGP signaling, and
as transit device for data traffic, the device is not able
to modify the label value from incoming MPLS VPN updates:
- as BGP device, modifying the label value is necessary
when redistributing VPN prefixes with its own next-hop.
- as transit device that connects two ethernet segments
on separate interfaces, the return MPLS traffic must be
handled: the modified label value must be swapped with
the original label value and sent back to the original
next-hop.
The border router use case can be taken as example, when
it acts both as transit and as BGP device:
- When receiving updates from a border router peer, and where
interior traffic is expected to transit through the local
border router.
- When receiving updates from interior devices, and where
exterior traffic will transit through the local border router.
In those two situations, a new label is bound to the received
entry, and the entry is advertised to a new peer with the new
label. In the same time, an MPLS entry is created to handle
return traffic with the new mpls label: the traffic would be
swapped to the original MPLS label and the original next-hop.
This is the first commit of a series of patches, that address
the above mentioned issue.
The first commit introduces a new per-interface command:
> interface eth0
> [no] mpls bgp l3vpn-multi-domain-switching
> exit
This command will authorise mpls vpn updates to have a new
label value bound to the mpls vpn routes received over that
interface.
Link: https://www.rfc-editor.org/rfc/rfc3107.html#section-3
> When a BGP speaker redistributes a route, the label(s) assigned to
> that route must not be changed (except by omission), unless the
> speaker changes the value of the Next Hop attribute of the route.
Link: https://www.rfc-editor.org/rfc/rfc3031.html#section-4.6
Link: https://www.rfc-editor.org/rfc/rfc4364.html#section-10
sub-chapter b.
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
vty_out(vty, " mpls bgp forwarding\n");
write++;
}
+ if (CHECK_FLAG(iifp->flags,
+ BGP_INTERFACE_MPLS_L3VPN_SWITCHING)) {
+ vty_out(vty,
+ " mpls bgp l3vpn-multi-domain-switching\n");
+ write++;
+ }
if_vty_config_end(vty);
}
return CMD_SUCCESS;
}
+DEFPY(mpls_bgp_l3vpn_multi_domain_switching,
+ mpls_bgp_l3vpn_multi_domain_switching_cmd,
+ "[no$no] mpls bgp l3vpn-multi-domain-switching",
+ NO_STR MPLS_STR BGP_STR
+ "Bind a local MPLS label to incoming L3VPN updates\n")
+{
+ bool check;
+ struct bgp_interface *iifp;
+
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ iifp = ifp->info;
+ if (!iifp) {
+ vty_out(vty, "Interface %s not available\n", ifp->name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ check = CHECK_FLAG(iifp->flags, BGP_INTERFACE_MPLS_L3VPN_SWITCHING);
+ if (check == !no)
+ return CMD_SUCCESS;
+ if (no)
+ UNSET_FLAG(iifp->flags, BGP_INTERFACE_MPLS_L3VPN_SWITCHING);
+ else
+ SET_FLAG(iifp->flags, BGP_INTERFACE_MPLS_L3VPN_SWITCHING);
+ /* trigger a nht update on eBGP sessions */
+ if (if_is_operative(ifp))
+ bgp_nht_ifp_up(ifp);
+
+ return CMD_SUCCESS;
+}
+
DEFPY (bgp_inq_limit,
bgp_inq_limit_cmd,
"bgp input-queue-limit (1-4294967295)$limit",
/* "mpls bgp forwarding" commands. */
install_element(INTERFACE_NODE, &mpls_bgp_forwarding_cmd);
+ install_element(INTERFACE_NODE,
+ &mpls_bgp_l3vpn_multi_domain_switching_cmd);
}
void bgp_vty_init(void)
struct bgp_interface {
#define BGP_INTERFACE_MPLS_BGP_FORWARDING (1 << 0)
+/* L3VPN multi domain switching */
+#define BGP_INTERFACE_MPLS_L3VPN_SWITCHING (1 << 1)
uint32_t flags;
};