@Nadav
Sorry for not immediately sending mail about what that patch is. But you figured out most if it already.
I sent bug demonstration code as a patch only because it was convenient.
I will open issue.



On 03/13/2017 03:40 PM, Nadav Har'El wrote:

On Mon, Mar 13, 2017 at 4:32 PM, Nadav Har'El <[email protected] <mailto:[email protected]>> wrote:



    We need to understand how IFF_SLAVE and IFF_SIMPLEX came to have
    the same bit... Did we get one from BSD and one from Linux?


Indeed this seems to be the case. The bits which Linux applications expect are in /usr/include/net/if.h or in OSv, include/api/net/if.h But the bits the internal BSD-based network stack uses are defined in bsbsd/sys/net/if.h.
Those are not the same bits, as we noticed.

So, in bsd/sys/compat/linux/linux_ioctl.cc in case SIOCGIFFLAGS, we call a function linux_gifflags() to translate the flags from the internal BSD bits to the Linux bits. But it appears that this function doesn't do all the necessary translations - in particularly the thing with IFF_SLAVE vs IFF_SIMPLEX.


    Can you please open an issue about it?




        Signed-off-by: Justin Cinkelj <[email protected]
        <mailto:[email protected]>>
        ---
         tests/tst-ifaddrs.cc | 121
        ++++++++++++++++++++++++++++++++++++++++++++++++++-
         1 file changed, 120 insertions(+), 1 deletion(-)

        diff --git a/tests/tst-ifaddrs.cc b/tests/tst-ifaddrs.cc
        index bfb682c..983a466 100644
        --- a/tests/tst-ifaddrs.cc
        +++ b/tests/tst-ifaddrs.cc
        @@ -22,6 +22,8 @@

         #include <linux/if_packet.h> // for sockaddr_ll

        +int main2(int argc, char *argv[]);
        +
         static int tests = 0, fails = 0;

         template<typename T>
        @@ -62,7 +64,7 @@ bool do_expectge(T actual, T expected, const
        char *actuals, const char *expected
                 do_expectge(var, 0, #call, "0", __FILE__, __LINE__); \
                 do_expect(errno, 0, #call " errno", "0", __FILE__,
        __LINE__);

        -int main()
        +int main(int argc, char *argv[])
         {
             // Start by testing if_nameindex() because Musl's
        get_ifaddrs() actually
             // uses that, and the second won't work if the first doesn't.
        @@ -174,6 +176,123 @@ noni:

             freeifaddrs(ifaddr);

        +    main2(argc, argv);
        +
             std::cout << "SUMMARY: " << tests << " tests, " << fails
        << " failures\n";
             return fails == 0 ? 0 : 1;
         }
        +
        +
        +//#include <stdio.h>
        +//#include <stdlib.h>
        +#include <unistd.h>
        +#include <string.h>
        +//#include <sys/socket.h>
        +#include <sys/ioctl.h>
        +//#include <linux/if.h>
        +//#include <netinet/in.h>
        +//#include <arpa/inet.h>
        +#include <net/if.h>
        +
        +#define print_flag(flags, IFF_X) { printf( "   %d = " #IFF_X
        " (0x%08x)\n", (flags & IFF_X) != 0, IFF_X); }
        +void print_all_flags(uint32_t flags)
        +{
        +printf( "  flags = 0x%08x\n", flags);
        +
        +print_flag(flags, IFF_UP);
        +print_flag(flags, IFF_BROADCAST);
        +print_flag(flags, IFF_DEBUG);
        +print_flag(flags, IFF_LOOPBACK);
        +print_flag(flags, IFF_POINTOPOINT);
        +print_flag(flags, IFF_NOTRAILERS);
        +print_flag(flags, IFF_RUNNING);
        +print_flag(flags, IFF_NOARP);
        +print_flag(flags, IFF_PROMISC);
        +print_flag(flags, IFF_ALLMULTI);
        +print_flag(flags, IFF_MASTER);
        +print_flag(flags, IFF_SLAVE);
        +print_flag(flags, IFF_MULTICAST);
        +print_flag(flags, IFF_PORTSEL);
        +print_flag(flags, IFF_AUTOMEDIA);
        +print_flag(flags, IFF_DYNAMIC);
        +}
        +
        +#define MAX_IFCONF_SIZE 1024
        +#define DEFAULT_NUMBER_INTERFACES 10
        +int main2(int argc, char *argv[])
        +{
        +    int sd;
        +    struct ifconf ifconf;
        +    int ifc_len;
        +    struct ifreq *ifr;
        +    const char* iface_name = nullptr;
        +
        +    printf("\n\n/* main2
        ------------------------------------------------*/\n");
        +
        +    if (argc >= 2) {
        +        iface_name = argv[1];
        +    }
        +    else {
        +        iface_name = "eth0";
        +    }
        +
        +    fprintf(stderr, "DBG %s:%d %s: start iface_name=%s\n",
        __FILE__,__LINE__,__FUNCTION__, iface_name);
        +    sd = socket(AF_INET, SOCK_DGRAM, 0);
        +    expectge(sd, 0);
        +
        +    ifc_len = sizeof(struct ifreq) * DEFAULT_NUMBER_INTERFACES;
        +    ifconf.ifc_len = ifc_len;
        +    ifconf.ifc_req = (ifreq*)malloc(ifc_len);
        +    if (NULL == ifconf.ifc_req) {
        +        close(sd);
        +        return -1;
        +    }
        +
        +    memset(ifconf.ifc_req, 0, ifconf.ifc_len);
        +
        +    if (ioctl(sd, SIOCGIFCONF, &ifconf) < 0) {
        +        printf("opal_ifinit: ioctl(SIOCGIFCONF) \
        +                    failed with errno=%d\n",
        +                    errno);
        +        free(ifconf.ifc_req);
        +        close(sd);
        +        return -1;
        +    }
        +
        +    int ii;
        +    printf("ifconf.ifc_len = %d, ifconf.ifc_req=%p, sz=%d\n",
        ifconf.ifc_len, ifconf.ifc_req, sizeof(ifconf.ifc_req[0]));
        +    for(ii=0; ii<ifconf.ifc_len; ii+=sizeof(ifreq)) {
        +        ifr = (ifreq*) (((char*)ifconf.ifc_req) + ii);
        +        printf("ii =%d/%d name=%s\n", ii, ifconf.ifc_len,
        ifr->ifr_name);
        +        if (AF_INET != ifr->ifr_addr.sa_family) {
        +            fprintf(stderr, "DBG %s:%d %s: not AF_INET\n",
        __FILE__,__LINE__,__FUNCTION__);
        +            continue;
        +        }
        +        if (strcmp(iface_name, ifr->ifr_name) == 0) {
        +            printf("iface %s found\n", iface_name);
        +            break;
        +        }
        +    }
        +    if (ii >= ifconf.ifc_len) {
        +        printf("ifr == nullprt :/, dev %s not found\n",
        iface_name);
        +        return 0;
        +    }
        +
        +    if (ioctl(sd, SIOCGIFFLAGS, ifr) < 0) {
        +        printf("opal_ifinit: ioctl(SIOCGIFFLAGS) failed with
        errno=%d\n", errno);
        +        fprintf(stderr, "DBG %s:%d %s: SIOCGIFFLAGS
        failed\n", __FILE__,__LINE__,__FUNCTION__);
        +    }
        +
        +    print_all_flags(ifr->ifr_flags);
        +    printf("%-8s : flags=0x%08x IFF_SLAVE=%d IFF_UP=%d
        IFF_BROADCAST=%d\n", ifr->ifr_name,
        +        ifr->ifr_flags, ifr->ifr_flags & IFF_SLAVE,
        ifr->ifr_flags & IFF_UP, ifr->ifr_flags & IFF_BROADCAST);
        +    if ((ifr->ifr_flags & IFF_UP) == 0) {
        +        fprintf(stderr, "DBG %s:%d %s: not IFF_UP\n",
        __FILE__,__LINE__,__FUNCTION__);
        +    }
        +    /* Is this a slave to a load balancer or bonded channel?
        +       If so, don't use it -- pick up the master instead */
        +    if ((ifr->ifr_flags & IFF_SLAVE) != 0) {
        +        fprintf(stderr, "DBG %s:%d %s: is IFF_SLAVE\n",
        __FILE__,__LINE__,__FUNCTION__);
        +    }
        +
        +}
        --
        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]
        <mailto:osv-dev%[email protected]>.
        For more options, visit https://groups.google.com/d/optout
        <https://groups.google.com/d/optout>.




--
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.

Reply via email to