Commit a0265685 by Stéphane Graber

Make lxc-user-nic use mkifname

NetworkManager at least expects all veth devices to be called veth* otherwise it'll consider them as physical interface and try to do DHCP on them. This change makes lxc-user-nic use the same function that we use for LXC itself which will give us standard vethXXXXX kind of interfaces. Signed-off-by: 's avatarStéphane Graber <stgraber@ubuntu.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 00194067
...@@ -34,12 +34,6 @@ ...@@ -34,12 +34,6 @@
#include <sys/syscall.h> #include <sys/syscall.h>
#include <time.h> #include <time.h>
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#else
#include <../include/ifaddrs.h>
#endif
#if HAVE_PTY_H #if HAVE_PTY_H
#include <pty.h> #include <pty.h>
#else #else
...@@ -280,74 +274,6 @@ static struct caps_opt caps_opt[] = { ...@@ -280,74 +274,6 @@ static struct caps_opt caps_opt[] = {
static struct caps_opt caps_opt[] = {}; static struct caps_opt caps_opt[] = {};
#endif #endif
static char padchar[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char *mkifname(char *template)
{
char *name = NULL;
int i = 0;
FILE *urandom;
unsigned int seed;
struct ifaddrs *ifaddr, *ifa;
int ifexists = 0;
/* Get all the network interfaces */
getifaddrs(&ifaddr);
/* Initialize the random number generator */
process_lock();
urandom = fopen ("/dev/urandom", "r");
process_unlock();
if (urandom != NULL) {
if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
seed = time(0);
process_lock();
fclose(urandom);
process_unlock();
}
else
seed = time(0);
#ifndef HAVE_RAND_R
srand(seed);
#endif
/* Generate random names until we find one that doesn't exist */
while(1) {
ifexists = 0;
name = strdup(template);
if (name == NULL)
return NULL;
for (i = 0; i < strlen(name); i++) {
if (name[i] == 'X') {
#ifdef HAVE_RAND_R
name[i] = padchar[rand_r(&seed) % (strlen(padchar) - 1)];
#else
name[i] = padchar[rand() % (strlen(padchar) - 1)];
#endif
}
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifa->ifa_name, name) == 0) {
ifexists = 1;
break;
}
}
if (ifexists == 0)
break;
free(name);
}
freeifaddrs(ifaddr);
return name;
}
static int run_buffer(char *buffer) static int run_buffer(char *buffer)
{ {
FILE *f; FILE *f;
...@@ -2668,7 +2594,7 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd ...@@ -2668,7 +2594,7 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
ERROR("veth1 name too long"); ERROR("veth1 name too long");
return -1; return -1;
} }
veth1 = mkifname(veth1buf); veth1 = lxc_mkifname(veth1buf);
if (!veth1) { if (!veth1) {
ERROR("failed to allocate a temporary name"); ERROR("failed to allocate a temporary name");
return -1; return -1;
...@@ -2678,7 +2604,7 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd ...@@ -2678,7 +2604,7 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
} }
snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX"); snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
veth2 = mkifname(veth2buf); veth2 = lxc_mkifname(veth2buf);
if (!veth2) { if (!veth2) {
ERROR("failed to allocate a temporary name"); ERROR("failed to allocate a temporary name");
goto out_delete; goto out_delete;
...@@ -2787,7 +2713,7 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n ...@@ -2787,7 +2713,7 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
if (err >= sizeof(peerbuf)) if (err >= sizeof(peerbuf))
return -1; return -1;
peer = mkifname(peerbuf); peer = lxc_mkifname(peerbuf);
if (!peer) { if (!peer) {
ERROR("failed to make a temporary name"); ERROR("failed to make a temporary name");
return -1; return -1;
......
...@@ -266,20 +266,16 @@ out_del: ...@@ -266,20 +266,16 @@ out_del:
/* /*
* Get a new nic. * Get a new nic.
* *dest will container the name (lxcuser-%d) which is attached * *dest will container the name (vethXXXXXX) which is attached
* on the host to the lxc bridge * on the host to the lxc bridge
*/ */
static void get_new_nicname(char **dest, char *br, int pid, char **cnic) static void get_new_nicname(char **dest, char *br, int pid, char **cnic)
{ {
int i = 0; char template[IFNAMSIZ];
// TODO - speed this up. For large installations we won't snprintf(template, sizeof(template), "vethXXXXXX");
// want n stats for every nth container startup. *dest = lxc_mkifname(template);
while (1) {
sprintf(*dest, "lxcuser-%d", i); create_nic(*dest, br, pid, cnic);
if (!nic_exists(*dest) && create_nic(*dest, br, pid, cnic))
return;
i++;
}
} }
static bool get_nic_from_line(char *p, char **nic) static bool get_nic_from_line(char *p, char **nic)
......
...@@ -50,6 +50,12 @@ ...@@ -50,6 +50,12 @@
#include "conf.h" #include "conf.h"
#include "lxclock.h" #include "lxclock.h"
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#else
#include <../include/ifaddrs.h>
#endif
#ifndef IFLA_LINKMODE #ifndef IFLA_LINKMODE
# define IFLA_LINKMODE 17 # define IFLA_LINKMODE 17
#endif #endif
...@@ -1108,6 +1114,74 @@ const char *lxc_net_type_to_str(int type) ...@@ -1108,6 +1114,74 @@ const char *lxc_net_type_to_str(int type)
return lxc_network_types[type]; return lxc_network_types[type];
} }
static char padchar[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *lxc_mkifname(char *template)
{
char *name = NULL;
int i = 0;
FILE *urandom;
unsigned int seed;
struct ifaddrs *ifaddr, *ifa;
int ifexists = 0;
/* Get all the network interfaces */
getifaddrs(&ifaddr);
/* Initialize the random number generator */
process_lock();
urandom = fopen ("/dev/urandom", "r");
process_unlock();
if (urandom != NULL) {
if (fread (&seed, sizeof(seed), 1, urandom) <= 0)
seed = time(0);
process_lock();
fclose(urandom);
process_unlock();
}
else
seed = time(0);
#ifndef HAVE_RAND_R
srand(seed);
#endif
/* Generate random names until we find one that doesn't exist */
while(1) {
ifexists = 0;
name = strdup(template);
if (name == NULL)
return NULL;
for (i = 0; i < strlen(name); i++) {
if (name[i] == 'X') {
#ifdef HAVE_RAND_R
name[i] = padchar[rand_r(&seed) % (strlen(padchar) - 1)];
#else
name[i] = padchar[rand() % (strlen(padchar) - 1)];
#endif
}
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifa->ifa_name, name) == 0) {
ifexists = 1;
break;
}
}
if (ifexists == 0)
break;
free(name);
}
freeifaddrs(ifaddr);
return name;
}
int setup_private_host_hw_addr(char *veth1) int setup_private_host_hw_addr(char *veth1)
{ {
struct ifreq ifr; struct ifreq ifr;
......
...@@ -131,6 +131,11 @@ extern int lxc_neigh_proxy_on(const char *name, int family); ...@@ -131,6 +131,11 @@ extern int lxc_neigh_proxy_on(const char *name, int family);
*/ */
extern int lxc_neigh_proxy_off(const char *name, int family); extern int lxc_neigh_proxy_off(const char *name, int family);
/*
* Generate a new unique network interface name
*/
extern char *lxc_mkifname(char *template);
extern const char *lxc_net_type_to_str(int type); extern const char *lxc_net_type_to_str(int type);
extern int setup_private_host_hw_addr(char *veth1); extern int setup_private_host_hw_addr(char *veth1);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment