[M] Change in openvpn[master]: Add support for user defined L3 master devices

"its_Giaan \(Code Review\) via Openvpn-devel" <[email protected]>
Newsgroups gmane.network.openvpn.devel
Message-ID <9cd17c4dd3b425ca83c6cae827e84c6c0b80f7c8-EmailReplacePatchSet-HTML@gerrit.openvpn.net>
Attention is currently required from: its_Giaan, plaisthos.

Hello flichtenheld, plaisthos, 

I'd like you to reexamine a change. Please visit

    http://gerrit.openvpn.net/c/openvpn/+/1703?usp=email

to look at the new patch set (#2).


Change subject: Add support for user defined L3 master devices
......................................................................

Add support for user defined L3 master devices

Introduce the --l3mdev option to allow associating OpenVPN
tun interfaces with a user-defined L3 master device (VRF).

When configured, the tun interface is automatically bound
to the specified l3mdev during interface initialization.

This allows VPN traffic to operate within a VRF domain,
enabling network isolation and policy-based routing at L3 level.

Note: This feature is Linux-only and relies on SITNL backend.

Change-Id: I115a17a2c61c65f48aea41d94150f34ea31f82da
Signed-off-by: Gianmarco De Gregori <[email protected]>
---
M doc/man-sections/vpn-network-options.rst
M src/openvpn/networking.h
M src/openvpn/networking_sitnl.c
M src/openvpn/networking_sitnl.h
M src/openvpn/options.c
M src/openvpn/options.h
M src/openvpn/tun.c
7 files changed, 104 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/03/1703/2

diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst
index 181c990..3853066 100644
--- a/doc/man-sections/vpn-network-options.rst
+++ b/doc/man-sections/vpn-network-options.rst
@@ -304,6 +304,19 @@
   Specify the link layer address, more commonly known as the MAC address.
   Only applied to TAP devices.
 
+--l3mdev name
+   Specify the L3 master device (such as VRF) to which the tunnel
+   interface will be bound. The specified device must already exist.
+
+   Unlike ``--bind-dev``, which affects only the transport traffic
+   (the encrypted packets exchanged between peers),
+   ``--l3mdev`` associates tun0 with an L3 master device,
+   causing the data traffic traversing the tunnel
+   (in its unencrypted form within the local networking stack)
+   to follow the routing policy associated with that L3 domain.
+
+  (Supported on Linux only, on other platforms this is a no-op).
+
 --netns name
   Specify the network namespace in which the tunnel interface will be created.
   The namespace must already exist.
diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h
index fab6bbf..3b4ac9f 100644
--- a/src/openvpn/networking.h
+++ b/src/openvpn/networking.h
@@ -125,6 +125,16 @@
 int net_iface_del(openvpn_net_ctx_t *ctx, const openvpn_net_iface_t *iface);
 
 /**
+ * Bind a network interface to an L3 master device.
+ *
+ * @param ctx       OpenVPN network context.
+ * @param iface     Interface to bind.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int net_iface_l3mdev_bind(openvpn_net_ctx_t *ctx, const char *iface);
+
+/**
  * Bring interface up or down.
  *
  * @param ctx       the implementation specific context
diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c
index b60131f..a1d6086 100644
--- a/src/openvpn/networking_sitnl.c
+++ b/src/openvpn/networking_sitnl.c
@@ -187,6 +187,7 @@
     char path[PATH_MAX];
 
     ctx->netns = NULL;
+    ctx->l3mdev = NULL;
 
     if (c && c->options.netns)
     {
@@ -200,6 +201,16 @@
         ctx->netns = c->options.netns;
     }
 
+    if (c && c->options.l3mdev)
+    {
+        if (!if_nametoindex(c->options.l3mdev))
+        {
+            msg(M_ERR, "%s: L3 master device %s does not exist", __func__, c->options.l3mdev);
+        }
+
+        ctx->l3mdev = c->options.l3mdev;
+    }
+
     ctx->gc = gc_new();
     return 0;
 }
@@ -1046,6 +1057,44 @@
 #ifdef ENABLE_SITNL
 
 int
+net_iface_l3mdev_bind(openvpn_net_ctx_t *ctx, const char *iface)
+{
+    struct sitnl_link_req req;
+    int ret = -1;
+
+    CLEAR(req);
+
+    int ifindex = if_nametoindex(iface);
+    int l3mdev_index = if_nametoindex(ctx->l3mdev);
+
+    if (ifindex == 0)
+    {
+        msg(M_WARN | M_ERRNO, "%s: rtnl: cannot get ifindex for %s", __func__, iface);
+        return ret;
+    }
+    if (l3mdev_index == 0)
+    {
+        msg(M_WARN | M_ERRNO, "%s: rtnl: cannot get ifindex for %s", __func__, ctx->l3mdev);
+        return ret;
+    }
+
+    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i));
+    req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+    req.n.nlmsg_type = RTM_NEWLINK;
+
+    req.i.ifi_family = AF_PACKET;
+    req.i.ifi_index = ifindex;
+
+    SITNL_ADDATTR(&req.n, sizeof(req), IFLA_MASTER, &l3mdev_index, sizeof(int));
+
+    msg(M_INFO, "Binding %s to %s", iface, ctx->l3mdev);
+
+    ret = sitnl_send(&req.n, 0, 0, NULL, NULL);
+err:
+    return ret;
+}
+
+int
 net_iface_up(openvpn_net_ctx_t *ctx, const char *iface, bool up)
 {
     struct sitnl_link_req req;
diff --git a/src/openvpn/networking_sitnl.h b/src/openvpn/networking_sitnl.h
index 7e723fe..6dff698 100644
--- a/src/openvpn/networking_sitnl.h
+++ b/src/openvpn/networking_sitnl.h
@@ -28,6 +28,7 @@
 struct openvpn_net_ctx
 {
     const char *netns;
+    const char *l3mdev;
     struct gc_arena gc;
 };
 
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index b602dcc..bfc13e2 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -320,6 +320,9 @@
     "--bind-dev dev  : Bind to the given device when making connection to a peer or\n"
     "                  listening for connections. This allows sending encrypted packets\n"
     "                  via a VRF present on the system.\n"
+    "--l3mdev        : Enslave the tunnel interface to a layer 3 master device causing\n"
+    "                  the data traffic traversing the tunnel to follow the routing policy\n"
+    "                  associated with that layer 3 domain.\n"
 #endif
     "--txqueuelen n  : Set the tun/tap TX queue length to n (Linux only).\n"
     "--mlock         : Disable Paging -- ensures key material and tunnel\n"
@@ -6503,6 +6506,14 @@
         VERIFY_PERMISSION(OPT_P_GENERAL);
         options->netns = p[1];
     }
+    else if (streq(p[0], "l3mdev") && p[1] && !p[2])
+    {
+#ifndef ENABLE_SITNL
+        msg(M_WARN, "NOTE: --l3mdev is supported only on Linux when compiled with SITNL");
+#endif
+        VERIFY_PERMISSION(OPT_P_GENERAL);
+        options->l3mdev = p[1];
+    }
     else if (streq(p[0], "nice") && p[1] && !p[2])
     {
         VERIFY_PERMISSION(OPT_P_NICE);
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 88a6dfa..1afd41b 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -316,6 +316,7 @@
     struct dns_options dns_options;
 
     const char *netns;
+    const char *l3mdev;
     bool remote_random;
     const char *ipchange;
     const char *dev;
diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 51d9bed..250ce50 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -1059,6 +1059,15 @@
     {
         msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
     }
+#if defined(ENABLE_SITNL)
+    if (ctx->l3mdev)
+    {
+        if (net_iface_l3mdev_bind(ctx, ifname) < 0)
+        {
+            msg(M_NONFATAL, "Linux can't bind %s to %s", ifname, ctx->l3mdev);
+        }
+    }
+#endif
 
     if (net_iface_up(ctx, ifname, true) < 0)
     {
@@ -1265,6 +1274,16 @@
         msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
     }
 
+#if defined(ENABLE_SITNL)
+    if (ctx->l3mdev)
+    {
+        if (net_iface_l3mdev_bind(ctx, ifname) < 0)
+        {
+            msg(M_NONFATAL, "Linux can't bind %s to %s", ifname, ctx->l3mdev);
+        }
+    }
+#endif
+
     if (net_iface_up(ctx, ifname, true) < 0)
     {
         msg(M_FATAL, "Linux can't bring %s up", ifname);

-- 
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1703?usp=email
To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email

Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I115a17a2c61c65f48aea41d94150f34ea31f82da
Gerrit-Change-Number: 1703
Gerrit-PatchSet: 2
Gerrit-Owner: its_Giaan <[email protected]>
Gerrit-Reviewer: flichtenheld <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
Gerrit-Attention: its_Giaan <[email protected]>

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.