Attention is currently required from: plaisthos.
Hello plaisthos,
I'd like you to do a code review.
Please visit
http://gerrit.openvpn.net/c/openvpn/+/1703?usp=email
to review the following change.
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/dco.c
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
8 files changed, 95 insertions(+), 0 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/03/1703/1
diff --git a/doc/man-sections/vpn-network-options.rst
b/doc/man-sections/vpn-network-options.rst
index 181c990..4cc11e9 100644
--- a/doc/man-sections/vpn-network-options.rst
+++ b/doc/man-sections/vpn-network-options.rst
@@ -304,6 +304,12 @@
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.
+
+ (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/dco.c b/src/openvpn/dco.c
index fbefcb6..40ef5b6 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -395,6 +395,7 @@
msg(msglevel, "Note: --netns not supported by DCO, disabling data
channel offload.");
return false;
}
+
#endif /* if defined(_WIN32) */
#if defined(HAVE_LIBCAPNG)
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..bb9e77a 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 ifindex, l3mdev_index, ret = -1;
+
+ CLEAR(req);
+
+ ifindex = if_nametoindex(iface);
+ l3mdev_index = if_nametoindex(ctx->l3mdev);
+
+ if (ifindex == 0)
+ {
+ msg(M_WARN | M_ERRNO, "%s: rtnl: cannot get ifindex for %s", __func__,
iface);
+ return -1;
+ }
+ if (l3mdev_index == 0)
+ {
+ msg(M_WARN | M_ERRNO, "%s: rtnl: cannot get ifindex for %s", __func__,
ctx->l3mdev);
+ return -1;
+ }
+
+ 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 bde3680..5247c8e 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -6496,6 +6496,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: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I115a17a2c61c65f48aea41d94150f34ea31f82da
Gerrit-Change-Number: 1703
Gerrit-PatchSet: 1
Gerrit-Owner: its_Giaan <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel