Issue about setting interface flag on network device.

陳國成 gcchen.org at gmail.com
Mon Sep 26 04:17:29 EDT 2011


Hi,

I encounter a strange problem when using 2.6.30 kernel.

There are two processes, one runs main1() and the other runs main2().
Two processes are running simultaneously on uni-processor system.
Besides, eth0 is a proprietory ethernet driver.

IFF_ALLMULTI can be set on eth0 successfully most of the time.
The result looks like:

main2: save_flags = 0x1043, flags = 0x1243

seldom, setting IFF_ALLMULTI on eth0 will not take effect and the
result looks like:

main2: save_flags = 0x1002, flags = 0x1043
main2: ret = 0

Please give me some suggestion about how to debug this issue.

int ifUp(const char *ifName)
{
    int sockfd = 0;
    struct ifreq ifr;
    int ret = 0;

    if (ifName == NULL)
    {
        ret = -1;
    }
    else
    {
        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
            ret = -1;
        }
        else
        {
            strncpy(ifr.ifr_name, ifName, IFNAMSIZ);
            ifr.ifr_flags = (IFF_UP | IFF_RUNNING | IFF_MULTICAST);
            if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
            {
                ret = -1;
            }
            close(sockfd);
        }
    }

    return ret;
}

short get_interface_flags(char *ifname)
{
    struct ifreq ifr;
    int sockfd, err;

    sockfd = socket(PF_INET, SOCK_DGRAM, 0);

    if (sockfd <= 0)
        return -1;

    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

    err = ioctl(sockfd, SIOCGIFFLAGS, (void*)&ifr);

    close(sockfd);

    if (err != 0)
        return -1;

    return ifr.ifr_flags;
}


short set_interface_flags(char *ifname, short flags)
{
    struct ifreq ifr;
    int sockfd, err;

    sockfd = socket(PF_INET, SOCK_DGRAM, 0);

    if (sockfd <= 0)
        return -1;

    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    ifr.ifr_flags = flags;

    err = ioctl(sockfd, SIOCSIFFLAGS, (void*)&ifr);

    close(sockfd);

    if (err != 0)
        return -1;

    return 0;
}

int main1()
{
	ifUp("eth0");
}

int main2()
{
    short flags, save_flags;
	short ret;

    /* Set the interface flags to receive all multicast packets */
    save_flags = get_interface_flags("eth0");
    if (save_flags != -1)
    {
        ret = set_interface_flags("eth0", save_flags | IFF_ALLMULTI);

        flags = get_interface_flags("eth0");
      	printf("%s: save_flags = 0x%x, flags = 0x%x\n", __FUNCTION__,
save_flags, flags);
        if (((flags & IFF_ALLMULTI) != IFF_ALLMULTI))
		{
                    printf("%s: ret = %d\n", __FUNCTION__, ret);
		}
    }
}


Thanks & Regards,
GC



More information about the Kernelnewbies mailing list