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
lxc_create_SOURCES = lxc_create.c
lxc_snapshot_SOURCES = lxc_snapshot.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
mkdir -p $(DESTDIR)$(datadir)/lxc
......
......@@ -2583,47 +2583,6 @@ void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf)
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;
struct lxc_conf *lxc_conf_init(void)
......
......@@ -130,6 +130,17 @@ out:
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)
{
struct nl_handler nlh;
......@@ -233,7 +244,7 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *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 nlmsg *nlmsg = NULL, *answer = NULL;
......@@ -1036,3 +1047,35 @@ const char *lxc_net_type_to_str(int type)
return NULL;
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);
* Move a device between namespaces
*/
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
......@@ -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_index(int ifindex, const char *newname);
extern int netdev_set_flag(const char *name, int flag);
/*
* Set the device network up or down
*/
......@@ -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 const char *lxc_net_type_to_str(int type);
extern int setup_private_host_hw_addr(char *veth1);
#endif
......@@ -15,8 +15,6 @@ lxc_test_lxcpath_SOURCES = lxcpath.c
lxc_test_cgpath_SOURCES = cgpath.c
lxc_test_clonetest_SOURCES = clonetest.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_concurrent_SOURCES = concurrent.c
lxc_test_may_control_SOURCES = may_control.c
......@@ -42,7 +40,7 @@ endif
bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \
lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \
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-reboot lxc-test-list lxc-test-attach
......
......@@ -21,47 +21,119 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
conffile="/tmp/lxc-usernet"
dbfile="/tmp/nics"
sysfsdir=/tmp/lxcnettest
cleanup() {
sed -i '/usernic-user/d' /var/run/lxc/nics /etc/lxc/lxc-usernet
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
mkdir -p $sysfsdir
# Create two test bridges
# there is no conffile, so we have no permissions
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1
brctl addbr usernic-br0
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
echo "Fail: empty conffile should not allow me a nic"
exit 1
echo "FAIL: able to create nic with no entries"
cleanup 1
fi
cat > $conffile << EOF
$(id -un) veth lxcbr0 1
EOF
# Give him a quota of two
echo "lxc-usernet veth usernic-br0 2" >> /etc/lxc/lxc-usernet
# 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
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1
# Assign two veths, should succeed
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
echo "Failed to get one allowed nic"
exit 1
echo "FAIL: unable to create second nic"
cleanup 1
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
echo "Fail: was able to get a second nic"
exit 1
echo "FAIL: able to create third nic"
cleanup 1
fi
# now remove the 'existing nic' and make sure we're allowed to create
# a new one
lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1
rm -rf $sysfsdir
mkdir -p $sysfsdir
# Shut down and restart the container, should be able to assign more nics
su -l usernic-user -c "lxc-stop -P /tmp/usernic-test/lxcbase -n b1"
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 }'`
su -l usernic-user -c "lxc-user-nic $p1 veth usernic-br0 xx5"
if [ $? -ne 0 ]; then
echo "Fail: was unable to get a replacement nic"
exit 1
echo "FAIL: unable to create nic after destroying the old"
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
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