# HG changeset patch # User Dave Leskovec <dlesko@xxxxxxxxxxxxxxxxxx> # Date 1213891164 25200 # Node ID 386c067de8995028dd11f70602081c31682dd293 # Parent 8d2afc533c91c4796512e1e71c8283e86eafd18a [LXC] Add functions to manage veth device pairs This gives us the ability to create a veth pair so that we can move one into the network namespace of an LXC container. diff -r 8d2afc533c91 -r 386c067de899 configure.in --- a/configure.in Tue Jun 17 15:55:03 2008 +0000 +++ b/configure.in Thu Jun 19 08:59:24 2008 -0700 @@ -301,6 +301,20 @@ if test "$with_qemu" = "yes" ; then AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h linux/if_tun.h],, AC_MSG_ERROR([You must install kernel-headers in order to compile libvirt])) +fi + +dnl +dnl check for patched iproute2 for lxc network support +dnl +if test "$with_lxc" = "yes" ; then + AC_MSG_CHECKING([for NETNS support]) + if ip link help 2>&1 | grep -q netns; then + with_lxc_netns="yes" + AC_DEFINE([HAVE_NETNS], [], [Kernel has NETNS support]) + else + with_lxc_netns="no" + fi + AC_MSG_RESULT($with_lxc_netns) fi dnl Need to test if pkg-config exists diff -r 8d2afc533c91 -r 386c067de899 src/Makefile.am --- a/src/Makefile.am Tue Jun 17 15:55:03 2008 +0000 +++ b/src/Makefile.am Thu Jun 19 08:59:24 2008 -0700 @@ -64,6 +64,7 @@ lxc_driver.c lxc_driver.h \ lxc_conf.c lxc_conf.h \ lxc_container.c lxc_container.h \ + veth.c veth.h \ nodeinfo.h nodeinfo.c \ util.c util.h diff -r 8d2afc533c91 -r 386c067de899 src/veth.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/veth.c Thu Jun 19 08:59:24 2008 -0700 @@ -0,0 +1,247 @@ +/* + * Copyright IBM Corp. 2008 + * + * veth.c: file description + * + * Authors: + * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <config.h> + +#ifdef HAVE_NETNS + +#include <string.h> + +#include "veth.h" +#include "internal.h" +#include "memory.h" +#include "util.h" + +#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__) +#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg) + +/* Functions */ +/** + * getFreeVethName: + * @veth: name for veth device (NULL to find first open) + * @maxLen: max length of veth name + * @startDev: device number to start at (x in vethx) + * + * Looks in /sys/class/net/ to find the first available veth device + * name. + * + * Returns 0 on success or -1 in case of error + */ +static int getFreeVethName(char *veth, int maxLen, int startDev) +{ + int rc = -1; + int devNum = startDev; + char path[PATH_MAX]; + + snprintf(path, PATH_MAX, "/sys/class/net/veth%d/", devNum); + while (virFileExists(path)) { + ++devNum; + sprintf(path, "/sys/class/net/veth%d/", devNum); + } + + snprintf(veth, maxLen, "veth%d", devNum); + + rc = devNum; + + return rc; +} + +/** + * vethCreate: + * @veth1: name for one end of veth pair + * @veth1MaxLen: max length of veth1 name + * @veth2: name for one end of veth pair + * @veth2MaxLen: max length of veth1 name + * + * Creates a veth device pair using the ip command: + * ip link add veth1 type veth peer name veth2 + * NOTE: If veth1 and veth2 names are not specified, ip will auto assign + * names. There seems to be two problems here - + * 1) There doesn't seem to be a way to determine the names of the + * devices that it creates. They show up in ip link show and + * under /sys/class/net/ however there is no guarantee that they + * are the devices that this process just created. + * 2) Once one of the veth devices is moved to another namespace, it + * is no longer visible in the parent namespace. This seems to + * confuse the name assignment causing it to fail with File exists. + * Because of these issues, this function currently forces the caller + * to fully specify the veth device names. + * + * Returns 0 on success or -1 in case of error + */ +int vethCreate(char* veth1, int veth1MaxLen, + char* veth2, int veth2MaxLen) +{ + int rc = -1; + const char *argv[] = { + "ip", "link", "add", veth1, "type", "veth", "peer", "name", veth2, NULL + }; + int cmdResult; + int vethDev = 0; + + if ((NULL == veth1) || (NULL == veth2)) { + goto error_out; + } + + DEBUG("veth1: %s veth2: %s", veth1, veth2); + + if (1 > strlen(veth1)) { + vethDev = getFreeVethName(veth1, veth1MaxLen, 0); + ++vethDev; + DEBUG("assigned veth1: %s", veth1); + } + + if (1 > strlen(veth2)) { + vethDev = getFreeVethName(veth2, veth2MaxLen, vethDev); + DEBUG("assigned veth2: %s", veth2); + } + + rc = virRun(NULL, (char**)argv, &cmdResult); + + if (0 == rc) { + rc = cmdResult; + } + +error_out: + return rc; +} + +/** + * vethDelete: + * @veth: name for one end of veth pair + * + * This will delete both veth devices in a pair. Only one end needs to + * be specified. The ip command will identify and delete the other veth + * device as well. + * ip link del veth + * + * Returns 0 on success or -1 in case of error + */ +int vethDelete(const char *veth) +{ + int rc = -1; + const char *argv[] = {"ip", "link", "del", veth, NULL}; + int cmdResult; + + if (NULL == veth) { + goto error_out; + } + + DEBUG("veth: %s", veth); + + rc = virRun(NULL, (char**)argv, &cmdResult); + + if (0 == rc) { + rc = cmdResult; + } + +error_out: + return rc; +} + +/** + * vethInterfaceUpOrDown: + * @veth: name of veth device + * @upOrDown: 0 => down, 1 => up + * + * Enables a veth device using the ifconfig command. A NULL inetAddress + * will cause it to be left off the command line. + * + * Returns 0 on success or -1 in case of error + */ +int vethInterfaceUpOrDown(const char* veth, int upOrDown) +{ + int rc = -1; + char upOrDownString[8]; + const char *argv[] = {"ifconfig", veth, upOrDownString, NULL}; + int cmdResult; + + if (NULL == veth) { + goto error_out; + } + + if (0 == upOrDown) { + strcpy(upOrDownString, "down"); + } else { + strcpy(upOrDownString, "up"); + } + + rc = virRun(NULL, (char**)argv, &cmdResult); + + if (0 == rc) { + rc = cmdResult; + } + +error_out: + return rc; +} + +/** + * moveInterfaceToNetNs: + * @interface: name of device + * @pidInNs: PID of process in target net namespace + * + * Moves the given device into the target net namespace specified by the given + * pid using this command: + * ip link set interface netns pidInNs + * + * Returns 0 on success or -1 in case of error + */ +int moveInterfaceToNetNs(const char* interface, int pidInNs) +{ + int rc; + /* offset of the pid field in the following args */ + const int pidArgvOffset = 5; + const char *argv[] = { + "ip", "link", "set", interface, "netns", NULL, NULL + }; + int cmdResult; + int len; + + if (NULL == interface) { + goto error_out; + } + + if (0 != VIR_ALLOC_N(argv[pidArgvOffset], (sizeof(int) * 3) + 1)) { + goto error_out; + } + len = snprintf(argv[pidArgvOffset], (sizeof(int) * 3) + 1, "%d", pidInNs); + if (len >= (sizeof(int) * 3) + 1) { + goto cleanup; + } + + rc = virRun(NULL, (char**)argv, &cmdResult); + + if (0 == rc) { + rc = cmdResult; + } + +cleanup: + VIR_FREE(argv[pidArgvOffset]); + +error_out: + return rc; +} + +#endif /* HAVE_NETNS */ + diff -r 8d2afc533c91 -r 386c067de899 src/veth.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/veth.h Thu Jun 19 08:59:24 2008 -0700 @@ -0,0 +1,39 @@ +/* + * Copyright IBM Corp. 2008 + * + * veth.h: file description + * + * Authors: + * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef VETH_H +#define VETH_H + +#include <config.h> + +#ifdef HAVE_NETNS + +/* Function declarations */ +int vethCreate(char* veth1, int veth1MaxLen, char* veth2, + int veth2MaxLen); +int vethDelete(const char* veth); +int vethInterfaceUpOrDown(const char* veth, int upOrDown); +int moveInterfaceToNetNs(const char *interface, int pidInNs); + +#endif /* HAVE_NETNS */ +#endif /* VETH_H */ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list