Commit 8befa924 by Serge Hallyn Committed by Stéphane Graber

lxc-user-nic: use common code from network.c

This pulls a lot of common code out of lxc_user_nic.c. It also moves one function from conf.c that was duplicated in lxc_user_nic.c (It removes a DEBUG statement because (a) it doesn't seem actually useful and (b) DEBUG doesn't work in network.c). Also replace the old test of only parsing code with a skeleton for a full test. (Note - the test will need some work, it's just there as do-what-i-mean code example) Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 8f7b58d6
...@@ -223,7 +223,7 @@ lxc_kill_SOURCES = lxc_kill.c ...@@ -223,7 +223,7 @@ lxc_kill_SOURCES = lxc_kill.c
lxc_create_SOURCES = lxc_create.c lxc_create_SOURCES = lxc_create.c
lxc_snapshot_SOURCES = lxc_snapshot.c lxc_snapshot_SOURCES = lxc_snapshot.c
lxc_usernsexec_SOURCES = lxc_usernsexec.c lxc_usernsexec_SOURCES = lxc_usernsexec.c
lxc_user_nic_SOURCES = lxc_user_nic.c lxc_user_nic_SOURCES = lxc_user_nic.c network.c network.h
install-exec-local: install-soPROGRAMS install-exec-local: install-soPROGRAMS
mkdir -p $(DESTDIR)$(datadir)/lxc mkdir -p $(DESTDIR)$(datadir)/lxc
......
...@@ -2583,47 +2583,6 @@ void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf) ...@@ -2583,47 +2583,6 @@ void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf)
free(conf->saved_nics); free(conf->saved_nics);
} }
static int setup_private_host_hw_addr(char *veth1)
{
struct ifreq ifr;
int err;
int sockfd;
process_lock();
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
process_unlock();
if (sockfd < 0)
return -errno;
snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) {
process_lock();
close(sockfd);
process_unlock();
return -errno;
}
ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
process_lock();
close(sockfd);
process_unlock();
if (err < 0)
return -errno;
DEBUG("mac address of host interface '%s' changed to private "
"%02x:%02x:%02x:%02x:%02x:%02x", veth1,
ifr.ifr_hwaddr.sa_data[0] & 0xff,
ifr.ifr_hwaddr.sa_data[1] & 0xff,
ifr.ifr_hwaddr.sa_data[2] & 0xff,
ifr.ifr_hwaddr.sa_data[3] & 0xff,
ifr.ifr_hwaddr.sa_data[4] & 0xff,
ifr.ifr_hwaddr.sa_data[5] & 0xff);
return 0;
}
static char *default_rootfs_mount = LXCROOTFSMOUNT; static char *default_rootfs_mount = LXCROOTFSMOUNT;
struct lxc_conf *lxc_conf_init(void) struct lxc_conf *lxc_conf_init(void)
......
...@@ -45,51 +45,9 @@ ...@@ -45,51 +45,9 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include <sys/param.h> #include <sys/param.h>
#include <sched.h>
#include "config.h" #include "config.h"
#include "utils.h" #include "utils.h"
#include "network.h"
#if ISTEST
#define CONF_FILE "/tmp/lxc-usernet"
#define DB_FILE "/tmp/nics"
#else
#define CONF_FILE LXC_USERNIC_CONF
#define DB_FILE LXC_USERNIC_DB
#endif
#include "nl.h"
#ifndef IFLA_LINKMODE
# define IFLA_LINKMODE 17
#endif
#ifndef IFLA_LINKINFO
# define IFLA_LINKINFO 18
#endif
#ifndef IFLA_NET_NS_PID
# define IFLA_NET_NS_PID 19
#endif
#ifndef IFLA_INFO_KIND
# define IFLA_INFO_KIND 1
#endif
#ifndef IFLA_VLAN_ID
# define IFLA_VLAN_ID 1
#endif
#ifndef IFLA_INFO_DATA
# define IFLA_INFO_DATA 2
#endif
#ifndef VETH_INFO_PEER
# define VETH_INFO_PEER 1
#endif
#ifndef IFLA_MACVLAN_MODE
# define IFLA_MACVLAN_MODE 1
#endif
void usage(char *me, bool fail) void usage(char *me, bool fail)
{ {
...@@ -146,14 +104,14 @@ static char *get_username(void) ...@@ -146,14 +104,14 @@ static char *get_username(void)
*/ */
static int get_alloted(char *me, char *intype, char *link) static int get_alloted(char *me, char *intype, char *link)
{ {
FILE *fin = fopen(CONF_FILE, "r"); FILE *fin = fopen(LXC_USERNIC_CONF, "r");
char *line = NULL; char *line = NULL;
char user[100], type[100], br[100]; char user[100], type[100], br[100];
size_t len = 0; size_t len = 0;
int n = -1, ret; int n = -1, ret;
if (!fin) { if (!fin) {
fprintf(stderr, "Failed to open %s: %s\n", CONF_FILE, fprintf(stderr, "Failed to open %s: %s\n", LXC_USERNIC_CONF,
strerror(errno)); strerror(errno));
return -1; return -1;
} }
...@@ -229,11 +187,7 @@ static bool nic_exists(char *nic) ...@@ -229,11 +187,7 @@ static bool nic_exists(char *nic)
int ret; int ret;
struct stat sb; struct stat sb;
#if ISTEST
ret = snprintf(path, MAXPATHLEN, "/tmp/lxcnettest/%s", nic);
#else
ret = snprintf(path, MAXPATHLEN, "/sys/class/net/%s", nic); ret = snprintf(path, MAXPATHLEN, "/sys/class/net/%s", nic);
#endif
if (ret < 0 || ret >= MAXPATHLEN) // should never happen! if (ret < 0 || ret >= MAXPATHLEN) // should never happen!
return true; return true;
ret = stat(path, &sb); ret = stat(path, &sb);
...@@ -242,198 +196,6 @@ static bool nic_exists(char *nic) ...@@ -242,198 +196,6 @@ static bool nic_exists(char *nic)
return true; return true;
} }
struct link_req {
struct nlmsg nlmsg;
struct ifinfomsg ifinfomsg;
};
#if ! ISTEST
static int lxc_veth_create(const char *name1, const char *name2)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct link_req *link_req;
struct rtattr *nest1, *nest2, *nest3;
int len, err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (err)
return err;
err = -EINVAL;
len = strlen(name1);
if (len == 1 || len >= IFNAMSIZ)
goto out;
len = strlen(name2);
if (len == 1 || len >= IFNAMSIZ)
goto out;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsghdr.nlmsg_flags =
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
err = -EINVAL;
nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest1)
goto out;
if (nla_put_string(nlmsg, IFLA_INFO_KIND, "veth"))
goto out;
nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
if (!nest2)
goto out;
nest3 = nla_begin_nested(nlmsg, VETH_INFO_PEER);
if (!nest3)
goto out;
nlmsg->nlmsghdr.nlmsg_len += sizeof(struct ifinfomsg);
if (nla_put_string(nlmsg, IFLA_IFNAME, name2))
goto out;
nla_end_nested(nlmsg, nest3);
nla_end_nested(nlmsg, nest2);
nla_end_nested(nlmsg, nest1);
if (nla_put_string(nlmsg, IFLA_IFNAME, name1))
goto out;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
}
static int lxc_netdev_move(char *ifname, pid_t pid)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL;
struct link_req *link_req;
int err, index;
index = if_nametoindex(ifname);
if (!ifname)
return -EINVAL;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = index;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
goto out;
err = netlink_transaction(&nlh, nlmsg, nlmsg);
out:
netlink_close(&nlh);
nlmsg_free(nlmsg);
return err;
}
static int setup_private_host_hw_addr(char *veth1)
{
struct ifreq ifr;
int err;
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
return -errno;
snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) {
close(sockfd);
return -errno;
}
ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
close(sockfd);
if (err < 0)
return -errno;
return 0;
}
static int netdev_set_flag(const char *name, int flag)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct link_req *link_req;
int index, len, err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (err)
return err;
err = -EINVAL;
len = strlen(name);
if (len == 1 || len >= IFNAMSIZ)
goto out;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
err = -EINVAL;
index = if_nametoindex(name);
if (!index)
goto out;
link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = index;
link_req->ifinfomsg.ifi_change |= IFF_UP;
link_req->ifinfomsg.ifi_flags |= flag;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(nlmsg);
nlmsg_free(answer);
return err;
}
static int instanciate_veth(char *n1, char **n2) static int instanciate_veth(char *n1, char **n2)
{ {
int err; int err;
...@@ -463,99 +225,8 @@ static int instanciate_veth(char *n1, char **n2) ...@@ -463,99 +225,8 @@ static int instanciate_veth(char *n1, char **n2)
return netdev_set_flag(n1, IFF_UP); return netdev_set_flag(n1, IFF_UP);
} }
static int lxc_bridge_attach(const char *bridge, const char *ifname)
{
int fd, index, err;
struct ifreq ifr;
if (strlen(ifname) >= IFNAMSIZ)
return -EINVAL;
index = if_nametoindex(ifname);
if (!index)
return -EINVAL;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
return -errno;
strncpy(ifr.ifr_name, bridge, IFNAMSIZ-1);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
ifr.ifr_ifindex = index;
err = ioctl(fd, SIOCBRADDIF, &ifr);
close(fd);
if (err)
err = -errno;
return err;
}
static int lxc_netdev_delete_by_index(int ifindex)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct link_req *link_req;
int err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = ifindex;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
nlmsg->nlmsghdr.nlmsg_type = RTM_DELLINK;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
}
static int lxc_netdev_delete_by_name(const char *name)
{
int index;
index = if_nametoindex(name);
if (!index)
return -EINVAL;
return lxc_netdev_delete_by_index(index);
}
#else
static int lxc_netdev_delete_by_name(const char *name)
{
char path[200];
sprintf(path, "/tmp/lxcnettest/%s", name);
return unlink(path);
}
#endif
static bool create_nic(char *nic, char *br, int pid, char **cnic) static bool create_nic(char *nic, char *br, int pid, char **cnic)
{ {
#if ISTEST
char path[200];
sprintf(path, "/tmp/lxcnettest/%s", nic);
int fd = open(path, O_RDWR|O_CREAT, S_IWUSR | S_IRUSR);
if (fd < 0)
return false;
close(fd);
return true;
#else
char *veth1buf, *veth2buf; char *veth1buf, *veth2buf;
veth1buf = alloca(IFNAMSIZ); veth1buf = alloca(IFNAMSIZ);
veth2buf = alloca(IFNAMSIZ); veth2buf = alloca(IFNAMSIZ);
...@@ -580,7 +251,7 @@ static bool create_nic(char *nic, char *br, int pid, char **cnic) ...@@ -580,7 +251,7 @@ static bool create_nic(char *nic, char *br, int pid, char **cnic)
} }
/* pass veth2 to target netns */ /* pass veth2 to target netns */
ret = lxc_netdev_move(veth2buf, pid); ret = lxc_netdev_move_by_name(veth2buf, pid);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid); fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid);
goto out_del; goto out_del;
...@@ -591,7 +262,6 @@ static bool create_nic(char *nic, char *br, int pid, char **cnic) ...@@ -591,7 +262,6 @@ static bool create_nic(char *nic, char *br, int pid, char **cnic)
out_del: out_del:
lxc_netdev_delete_by_name(veth1buf); lxc_netdev_delete_by_name(veth1buf);
return false; return false;
#endif
} }
/* /*
...@@ -775,65 +445,6 @@ again: ...@@ -775,65 +445,6 @@ again:
goto again; goto again;
} }
static int lxc_netdev_rename_by_index(int ifindex, const char *newname)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct link_req *link_req;
int len, err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (err)
return err;
len = strlen(newname);
if (len == 1 || len >= IFNAMSIZ)
goto out;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = ifindex;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
goto out;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
}
static int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
{
int len, index;
len = strlen(oldname);
if (len == 1 || len >= IFNAMSIZ)
return -EINVAL;
index = if_nametoindex(oldname);
if (!index) {
fprintf(stderr, "Error getting ifindex for %s\n", oldname);
return -EINVAL;
}
return lxc_netdev_rename_by_index(index, newname);
}
static int rename_in_ns(int pid, char *oldname, char *newname) static int rename_in_ns(int pid, char *oldname, char *newname)
{ {
char nspath[MAXPATHLEN]; char nspath[MAXPATHLEN];
...@@ -952,13 +563,13 @@ int main(int argc, char *argv[]) ...@@ -952,13 +563,13 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
if (!create_db_dir(DB_FILE)) { if (!create_db_dir(LXC_USERNIC_DB)) {
fprintf(stderr, "Failed to create directory for db file\n"); fprintf(stderr, "Failed to create directory for db file\n");
exit(1); exit(1);
} }
if ((fd = open_and_lock(DB_FILE)) < 0) { if ((fd = open_and_lock(LXC_USERNIC_DB)) < 0) {
fprintf(stderr, "Failed to lock %s\n", DB_FILE); fprintf(stderr, "Failed to lock %s\n", LXC_USERNIC_DB);
exit(1); exit(1);
} }
......
...@@ -130,6 +130,17 @@ out: ...@@ -130,6 +130,17 @@ out:
return err; return err;
} }
int lxc_netdev_move_by_name(char *ifname, pid_t pid)
{
int index;
index = if_nametoindex(ifname);
if (!ifname)
return -EINVAL;
return lxc_netdev_move_by_index(index, pid);
}
int lxc_netdev_delete_by_index(int ifindex) int lxc_netdev_delete_by_index(int ifindex)
{ {
struct nl_handler nlh; struct nl_handler nlh;
...@@ -233,7 +244,7 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname) ...@@ -233,7 +244,7 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
return lxc_netdev_rename_by_index(index, newname); return lxc_netdev_rename_by_index(index, newname);
} }
static int netdev_set_flag(const char *name, int flag) int netdev_set_flag(const char *name, int flag)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
...@@ -1036,3 +1047,35 @@ const char *lxc_net_type_to_str(int type) ...@@ -1036,3 +1047,35 @@ const char *lxc_net_type_to_str(int type)
return NULL; return NULL;
return lxc_network_types[type]; return lxc_network_types[type];
} }
int setup_private_host_hw_addr(char *veth1)
{
struct ifreq ifr;
int err;
int sockfd;
process_lock();
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
process_unlock();
if (sockfd < 0)
return -errno;
snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) {
process_lock();
close(sockfd);
process_unlock();
return -errno;
}
ifr.ifr_hwaddr.sa_data[0] = 0xfe;
err = ioctl(sockfd, SIOCSIFHWADDR, &ifr);
process_lock();
close(sockfd);
process_unlock();
if (err < 0)
return -errno;
return 0;
}
...@@ -32,6 +32,7 @@ extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr); ...@@ -32,6 +32,7 @@ extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr);
* Move a device between namespaces * Move a device between namespaces
*/ */
extern int lxc_netdev_move_by_index(int ifindex, pid_t pid); extern int lxc_netdev_move_by_index(int ifindex, pid_t pid);
extern int lxc_netdev_move_by_name(char *ifname, pid_t pid);
/* /*
* Delete a network device * Delete a network device
...@@ -45,6 +46,8 @@ extern int lxc_netdev_delete_by_index(int ifindex); ...@@ -45,6 +46,8 @@ extern int lxc_netdev_delete_by_index(int ifindex);
extern int lxc_netdev_rename_by_name(const char *oldname, const char *newname); extern int lxc_netdev_rename_by_name(const char *oldname, const char *newname);
extern int lxc_netdev_rename_by_index(int ifindex, const char *newname); extern int lxc_netdev_rename_by_index(int ifindex, const char *newname);
extern int netdev_set_flag(const char *name, int flag);
/* /*
* Set the device network up or down * Set the device network up or down
*/ */
...@@ -123,4 +126,5 @@ extern int lxc_neigh_proxy_on(const char *name, int family); ...@@ -123,4 +126,5 @@ 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);
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);
#endif #endif
...@@ -15,8 +15,6 @@ lxc_test_lxcpath_SOURCES = lxcpath.c ...@@ -15,8 +15,6 @@ lxc_test_lxcpath_SOURCES = lxcpath.c
lxc_test_cgpath_SOURCES = cgpath.c lxc_test_cgpath_SOURCES = cgpath.c
lxc_test_clonetest_SOURCES = clonetest.c lxc_test_clonetest_SOURCES = clonetest.c
lxc_test_console_SOURCES = console.c lxc_test_console_SOURCES = console.c
lxc_usernic_test_SOURCES = ../lxc/lxc_user_nic.c ../lxc/nl.c
lxc_usernic_test_CFLAGS = -DISTEST
lxc_test_snapshot_SOURCES = snapshot.c lxc_test_snapshot_SOURCES = snapshot.c
lxc_test_concurrent_SOURCES = concurrent.c lxc_test_concurrent_SOURCES = concurrent.c
lxc_test_may_control_SOURCES = may_control.c lxc_test_may_control_SOURCES = may_control.c
...@@ -42,7 +40,7 @@ endif ...@@ -42,7 +40,7 @@ endif
bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \ bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \
lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \ lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \
lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \ lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \
lxc-test-cgpath lxc-test-clonetest lxc-test-console lxc-usernic-test \ lxc-test-cgpath lxc-test-clonetest lxc-test-console \
lxc-test-snapshot lxc-test-concurrent lxc-test-may-control \ lxc-test-snapshot lxc-test-concurrent lxc-test-may-control \
lxc-test-reboot lxc-test-list lxc-test-attach lxc-test-reboot lxc-test-list lxc-test-attach
......
...@@ -21,47 +21,119 @@ ...@@ -21,47 +21,119 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
conffile="/tmp/lxc-usernet" cleanup() {
dbfile="/tmp/nics" sed -i '/usernic-user/d' /var/run/lxc/nics /etc/lxc/lxc-usernet
sysfsdir=/tmp/lxcnettest ifconfig usernic-br0 down
ifconfig usernic-br1 down
sudo brctl delbr usernic-br0
sudo brctl delbr usernic-br1
sudo deluser usernic-user
su -l usernic-user -c "lxc-stop -P /tmp/usernic-test/lxcbase -n b1"
rm -rf /tmp/usernic-test
exit $1
}
rm -f $conffile $dbfile # create a test user
deluser usernic-user || true
useradd usernic-user
sudo mkdir -p /home/usernic-user
sudo chown usernic-user /home/usernic-user
usermod -v 910000-919999 -w 910000-919999 usernic-user
mkdir -p /tmp/usernic-test/lxcbase
chown usernic-user /tmp/usernic-test/lxcbase
uid=$(id -u usernic-user)
cat > /home/usernic-user/.bashrc << EOF
export XDG_RUNTIME_DIR=/run/user/$uid
EOF
XDG_RUNTIME_DIR=/run/user/$uid
export XDG_RUNTIME_DIR=/run/user/$uid
mkdir -p /run/user/$uid
chown usernic-user /run/user/$uid
env
echo XXX[
su -l usernic-user -c "env"
sleep 20
#
cat > /tmp/lxc-usernic.conf << EOF
lxc.network.type = empty
lxc.id_map = u 0 911000 10000
lxc.id_map = g 0 911000 10000
EOF
rm -rf $sysfsdir # Create two test bridges
mkdir -p $sysfsdir
# there is no conffile, so we have no permissions brctl addbr usernic-br0
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 brctl addbr usernic-br1
ifconfig usernic-br0 0.0.0.0 up
ifconfig usernic-br1 0.0.0.0 up
# Create three containers
su -l usernic-user -c "lxc-create -P /tmp/usernic-test/lxcbase -t busybox -n b1 -f /tmp/lxc-usernic.conf"
su -l usernic-user -c "lxc-start -P /tmp/usernic-test/lxcbase -n b1 -d"
p1=`lxc-info -P /tmp/usernic-test/lxcbase -n b1 -p | awk -F: '{ print $2 }'`
# Assign one veth, should fail as no allowed entries yet
su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br0 xx1"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "Fail: empty conffile should not allow me a nic" echo "FAIL: able to create nic with no entries"
exit 1 cleanup 1
fi fi
cat > $conffile << EOF # Give him a quota of two
$(id -un) veth lxcbr0 1 echo "lxc-usernet veth usernic-br0 2" >> /etc/lxc/lxc-usernet
EOF
# Assign one veth to second bridge, should fail
su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br1 xx1"
if [ $? -eq 0 ]; then
echo "FAIL: able to create nic with no entries"
cleanup 1
fi
# Should be allowed one but not two # Assign two veths, should succeed
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br0 xx2"
if [ $? -ne 0 ]; then
echo "FAIL: unable to create first nic"
cleanup 1
fi
su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br0 xx3"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Failed to get one allowed nic" echo "FAIL: unable to create second nic"
exit 1 cleanup 1
fi fi
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 # Assign one more veth, should fail.
su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br0 xx4"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "Fail: was able to get a second nic" echo "FAIL: able to create third nic"
exit 1 cleanup 1
fi fi
# now remove the 'existing nic' and make sure we're allowed to create # Shut down and restart the container, should be able to assign more nics
# a new one su -l usernic-user -c "lxc-stop -P /tmp/usernic-test/lxcbase -n b1"
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 su -l usernic-user -c "lxc-start -P /tmp/usernic-test/lxcbase -n b1 -d"
rm -rf $sysfsdir p1=`lxc-info -P /tmp/usernic-test/lxcbase -n b1 -p | awk -F: '{ print $2 }'`
mkdir -p $sysfsdir su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br0 xx5"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Fail: was unable to get a replacement nic" echo "FAIL: unable to create nic after destroying the old"
exit 1 cleanup 1
fi
su -l usernic-user -c "lxc-stop -P /tmp/usernic-test/lxcbase -n b1"
# Create a root-owned ns
lxc-create -t busybox -n usernic-c1
lxc-start -n usernic-c1 -d
p2=`lxc-info -n usernic-c1 -p | awk -F: '{ print $2}'`
# assign veth to it - should fail
su -l usernic-user -c "lxc-user-nic $p2 veth usernic-br0 xx6"
ret=$?
lxc-stop -n usernic-c1
lxc-destroy -n usernic-c1
if [ $ret -eq 0 ]; then
echo "FAIL: able to attach nic to root-owned container"
cleanup 1
fi fi
echo "All tests passed" echo "All tests passed"
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