From: Nadav Har'El <n...@scylladb.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

SIOCGIFFLAGS ioctl: remove BSD-specific bits

The SIOCGIFFLAGS ioctl returns a set of flags for a network interface.
Many of the classic bits there, like IFF_UP and IFF_LOOPBACK, are the same
in our internal implementation (BSD-based) and desired output (Linux),
but not all of them are the same. We already had a function to convert
the internal bitmask into a Linux bitmask, but it was incomplete.

Of particular importance is BSD's IFF_SIMPLEX flag, which does not exist
on Linux, and is set by OSv's Xen network driver. As we failed to clear
this flag, clients thought they were seeing Linux's IFF_SLAVE (which is
at the same bit position, 0x800). In particular OpenMPI did not like
seeing this flag, and refused to use this network interface.

Fixes #862

Signed-off-by: Nadav Har'El <n...@scylladb.com>
Message-Id: <20170314133315.18971-1-...@scylladb.com>

---
diff --git a/bsd/sys/compat/linux/linux_ioctl.cc b/bsd/sys/compat/linux/linux_ioctl.cc
--- a/bsd/sys/compat/linux/linux_ioctl.cc
+++ b/bsd/sys/compat/linux/linux_ioctl.cc
@@ -143,26 +143,27 @@ linux_ifconf(struct bsd_ifconf *ifc_p)
     return (0);
 }

+// While many of the traditional bits returned by SIOCGIFFLAGS are the same
+// on BSD and Linux, some of the newer ones have different location, or
+// different meaning for the same bit location. So we need to convert the
+// BSD bits which we store internally to the Linux bits applications expect
+// us to return.
 static void
 linux_gifflags(struct ifnet *ifp, struct l_ifreq *ifr)
 {
     l_short flags;

+    // This assignment drops all the flags beyond the 16th bit.
+    // None of them have a Linux equivalent.
     flags = (ifp->if_flags | ifp->if_drv_flags);
-    /* These flags have no Linux equivalent
-     *
-     *  Notes:
-     *       - We do show IFF_SMART|IFF_DRV_OACTIVE|IFF_SIMPLEX
- * - IFF_LINK0 has a value of 0x1000 which conflics with the Linux
-     *         IFF_MULTICAST value.
-     */
-    flags &= ~(IFF_LINK0|IFF_LINK1|IFF_LINK2);
+    // These flags have no Linux equivalent:
+ flags &= ~(IFF_SMART|IFF_DRV_OACTIVE|IFF_SIMPLEX|IFF_LINK0|IFF_LINK1| IFF_LINK2);
     /* Linux' multicast flag is in a different bit */
     if (flags & IFF_MULTICAST) {
         flags &= ~IFF_MULTICAST;
         flags |= 0x1000;
     }
-    ifr->ifr_flags = flags ;
+    ifr->ifr_flags = flags;
 }

 #define ARPHRD_ETHER   1

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to