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