]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: add 'mpls bgp l3vpn-multi-domain-switching' command
authorLouis Scalbert <louis.scalbert@6wind.com>
Tue, 2 May 2023 14:19:20 +0000 (16:19 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 16 Jun 2023 08:54:58 +0000 (10:54 +0200)
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>
bgpd/bgp_vty.c
bgpd/bgpd.h

index 6d7b745713a3d424bcd790c2f98f6f8e97dd3935..6a4c7c4e983be4bf143076a2abb75b4340e4ffd9 100644 (file)
@@ -18997,6 +18997,12 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                        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);
        }
@@ -19047,6 +19053,35 @@ DEFPY(mpls_bgp_forwarding, mpls_bgp_forwarding_cmd,
        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",
@@ -19106,6 +19141,8 @@ static void bgp_vty_if_init(void)
 
        /* "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)
index ecd122fee2fb482c87f5249428c435a00e1fd2bf..0eb58773d003ee8902730a78ac2204b31c1eb405 100644 (file)
@@ -811,6 +811,8 @@ DECLARE_QOBJ_TYPE(bgp);
 
 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;
 };