[Lxc-users] [Network] ioctl on socket fails in container

stephane.riviere at regis-dgac.net stephane.riviere at regis-dgac.net
Wed Apr 14 09:22:19 UTC 2010


Hi,

I'm using LXC to run Perl scripts that generate network traffic, using the 
Net::RawIP package.
The scripts work perfectly well on a "real" host, but fail inside an LXC 
container.

After a few hours of testing/debuging, the origin of the problem is that 
some basic ioctl calls on socket fails.

Net::RawIP relies on SIOCGIFADDR et SIOCGIFHWADDR to get the IP and MAC 
addresses of the network interface.

My container has 2 interfaces : 1 macvlan (normally used to generate 
traffic) and 1 bridged (to dialogue with the host and the other 
containers).

In the container, these ioctl calls fail with an "Invalid argument" on 
every interface, including the loopback.


I've extracted the failing code from Net::RawIP to have a simple test 
program (code at the end of the message).
It just creates a socket and do the 2 ioctl calls on it.

My LXC configuration is based on the article of Stéphane Graber 
(http://www.stgraber.org/category/lxc):

- host : Ubuntu 9.10 Desktop (2.6.31 kernel)
- containers : Ubuntu 8.04 


I really don't know what's wrong, because ifconfig relies on the same 
basic call to get interface information...

If anyone has any idea, I would greatly appreciate it :-)



Stéphane.



------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <netinet/if_ether.h>
#include <net/if.h>
#include <errno.h>


int main(int argc, char* argv[])
{
   unsigned int ip;
   unsigned char mac[256];
   int fd; 
 
   if(argc!=2) {
      printf("Usage : test <device>\n");
      return -1;
   }
   fd = tap(argv[1],&ip,mac);
 
   if(fd>0) {
      printf("Got IP (%i) and MAC (%s)\n",ip,mac);
   }

}

/* Code extracted from Net::RawIP */
int tap(char *dev,unsigned int *my_eth_ip,unsigned char *my_eth_mac)
{
 
    int fd,v,s;
    struct ifreq ifr;
 
   memset(&ifr,0,sizeof(struct ifreq));
    (void)strcpy(ifr.ifr_name, dev);

   printf("Getting IP / MAC info for device (%s)\n",dev);
    if ((fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
        printf("Socket creation failed with code (%d) : %s\n",errno, 
strerror(errno));
       return -1;
    }

    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
        close(fd);
        printf("SIOCGIFADDR failed with code (%d) : %s\n",errno, 
strerror(errno));
        return -1;
    }
 
    *my_eth_ip = ntohl(((struct 
sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr);

    if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
        close(fd);
        printf("SIOCGIFHWADDR failed with code (%d) : %s\n",errno, 
strerror(errno));
        return -1;
    }

    memcpy(my_eth_mac, ifr.ifr_hwaddr.sa_data,ETH_ALEN);

    return fd;
}

------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxcontainers.org/pipermail/lxc-users/attachments/20100414/395e4818/attachment.html>


More information about the lxc-users mailing list