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

Reply via email to