summaryrefslogtreecommitdiffstats
path: root/src/VBox/HostDrivers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c50
2 files changed, 50 insertions, 2 deletions
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
index 1cff0981..d7c1afb5 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
@@ -202,6 +202,8 @@ typedef struct VBOXNETFLTINS
struct sk_buff_head XmitQueue;
struct work_struct XmitTask;
# endif
+ /** Unique identifier of network namespace of device to attach to. */
+ uint32_t uNamespaceInode;
/** @} */
# elif defined(RT_OS_SOLARIS)
/** @name Solaris instance data.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
index 85777fa1..a016cf69 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
@@ -47,7 +47,11 @@
#if RTLNX_VER_MIN(2,6,24)
# include <linux/nsproxy.h>
#endif
-#if RTLNX_VER_MIN(6,4,10) || RTLNX_RHEL_RANGE(9,4, 9,99)
+#if RTLNX_VER_MIN(3,10,0) /* proc_ns introduced */
+# define VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+# include <linux/proc_ns.h>
+#endif
+#if RTLNX_VER_MIN(6,4,10) || RTLNX_RHEL_RANGE(9,4, 9,99) || RTLNX_SUSE_MAJ_PREREQ(15, 6)
# include <net/gso.h>
#endif
#include <linux/netdevice.h>
@@ -1841,6 +1845,7 @@ static void vboxNetFltSetLinkState(PVBOXNETFLTINS pThis, struct net_device *pDev
*/
static int vboxNetFltLinuxAttachToInterface(PVBOXNETFLTINS pThis, struct net_device *pDev)
{
+ bool fAlreadyAttached = false;
LogFlow(("vboxNetFltLinuxAttachToInterface: pThis=%p (%s)\n", pThis, pThis->szName));
/*
@@ -1849,9 +1854,20 @@ static int vboxNetFltLinuxAttachToInterface(PVBOXNETFLTINS pThis, struct net_dev
dev_hold(pDev);
RTSpinlockAcquire(pThis->hSpinlock);
- ASMAtomicUoWritePtr(&pThis->u.s.pDev, pDev);
+ if (ASMAtomicUoReadPtrT(&pThis->u.s.pDev, struct net_device *))
+ fAlreadyAttached = true; /* Do not attach multiple times! */
+ else
+ ASMAtomicUoWritePtr(&pThis->u.s.pDev, pDev);
RTSpinlockRelease(pThis->hSpinlock);
+ if (fAlreadyAttached)
+ {
+ dev_put(pDev);
+ Log(("vboxNetFltLinuxAttachToInterface: Not attaching to %p(%s), already attached to %p(%s).\n",
+ pDev, pDev->name, pThis->u.s.pDev, pThis->u.s.pDev->name));
+ return VINF_ALREADY_INITIALIZED;
+ }
+
Log(("vboxNetFltLinuxAttachToInterface: Device %p(%s) retained. ref=%d\n",
pDev, pDev->name,
#if RTLNX_VER_MIN(2,6,37)
@@ -2062,6 +2078,29 @@ static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned
if (ulEventType == NETDEV_REGISTER)
{
+#ifdef VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+# if RTLNX_VER_MIN(3,19,0) /* ns_common introduced */
+# define VBOX_DEV_NET_NS_INUM(dev) dev_net(dev)->ns.inum
+# else
+# define VBOX_DEV_NET_NS_INUM(dev) dev_net(dev)->proc_inum
+# endif
+ if (pThis->u.s.uNamespaceInode == 0 || pThis->u.s.uNamespaceInode == VBOX_DEV_NET_NS_INUM(pDev))
+ {
+ /* Skip namespace if it is present */
+ const char *pcszIfName = strchr(pThis->szName, '/');
+ if (pcszIfName)
+ ++pcszIfName;
+ else
+ pcszIfName = pThis->szName;
+ if (strcmp(pDev->name, pcszIfName) == 0)
+ vboxNetFltLinuxAttachToInterface(pThis, pDev);
+ else
+ Log(("VBoxNetFlt: not attaching to '%s' as it does not match '%s'\n", pDev->name, pcszIfName));
+ }
+ else
+ Log(("VBoxNetFlt: ignoring '%s' in wrong namespace (%u, expected %u)\n", pDev->name,
+ VBOX_DEV_NET_NS_INUM(pDev), pThis->u.s.uNamespaceInode));
+#else /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
#if RTLNX_VER_MIN(2,6,24) /* cgroups/namespaces introduced */
# if RTLNX_VER_MIN(2,6,26)
# define VBOX_DEV_NET(dev) dev_net(dev)
@@ -2081,6 +2120,7 @@ static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned
vboxNetFltLinuxAttachToInterface(pThis, pDev);
}
}
+#endif /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
}
else
{
@@ -2579,6 +2619,12 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
pThis->u.s.fPromiscuousSet = false;
pThis->u.s.fPacketHandler = false;
memset(&pThis->u.s.PacketType, 0, sizeof(pThis->u.s.PacketType));
+#ifdef VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+ /* We should get the interface name in the form <namespace>/<ifname>, parse it. */
+ pThis->u.s.uNamespaceInode = RTStrToUInt32(pThis->szName);
+#else /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
+ pThis->u.s.uNamespaceInode = 0;
+#endif /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
skb_queue_head_init(&pThis->u.s.XmitQueue);
# if RTLNX_VER_MIN(2,6,20)