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 <[email protected]> --- bsd/sys/compat/linux/linux_ioctl.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/bsd/sys/compat/linux/linux_ioctl.cc b/bsd/sys/compat/linux/linux_ioctl.cc index 59f1eb3..43a50bb 100644 --- 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 -- 2.9.3 -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
