Skip to content

Commit

Permalink
Support openvswitch bridges
Browse files Browse the repository at this point in the history
We detect whether ovs-vsctl is available.  If so, then we support
adding network interfaces to openvswitch bridges with it.

Note that with this patch, veths do not appear to be removed from the
openvswitch bridge.  This seems a bug in openvswitch, as the veths
in fact do disappear from the system.  If lxc is required to remove
the port from the bridge manually, that becomes more complicated
for unprivileged containers, as it would require a setuid-root
wrapper to be called at shutdown.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
  • Loading branch information
hallyn committed Jul 23, 2014
1 parent 8aecd66 commit 0d20477
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
11 changes: 11 additions & 0 deletions configure.ac
Expand Up @@ -190,6 +190,16 @@ fi

AM_CONDITIONAL([ENABLE_API_DOCS], [test "x$HAVE_DOXYGEN" != "x"])

# Openvswitch
AC_PATH_PROG([OVS_CTL_PATH],[ovs-vsctl])
if test "x$OVS_CTL_PATH" != "x"; then
enable_ovs="yes"
AS_AC_EXPAND(OVS_CTL_PATH, "$OVS_CTL_PATH")
else
enable_ovs="no"
fi
AM_CONDITIONAL([HAVE_OVS], [test "x$enable_ovs" = "xyes"])

# Apparmor
AC_ARG_ENABLE([apparmor],
[AC_HELP_STRING([--enable-apparmor], [enable apparmor support [default=auto]])],
Expand Down Expand Up @@ -755,6 +765,7 @@ Environment:
- rpath: $enable_rpath
- GnuTLS: $enable_gnutls
- Bash integration: $enable_bash
- Openvswitch: $enable_ovs

Security features:
- Apparmor: $enable_apparmor
Expand Down
4 changes: 4 additions & 0 deletions src/lxc/Makefile.am
Expand Up @@ -128,6 +128,10 @@ if ENABLE_APPARMOR
AM_CFLAGS += -DHAVE_APPARMOR
endif

if HAVE_OVS
AM_CFLAGS += -DHAVE_OVS -DOVS_CTL_PATH=\"$(OVS_CTL_PATH)\"
endif

if ENABLE_CGMANAGER
AM_CFLAGS += -DHAVE_CGMANAGER
endif
Expand Down
43 changes: 43 additions & 0 deletions src/lxc/network.c
Expand Up @@ -48,6 +48,7 @@
#include "nl.h"
#include "network.h"
#include "conf.h"
#include "utils.h"

#if HAVE_IFADDRS_H
#include <ifaddrs.h>
Expand Down Expand Up @@ -1170,6 +1171,45 @@ int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
return ip_route_dest_add(AF_INET6, ifindex, dest);
}

#ifdef HAVE_OVS
static bool is_ovs_bridge(const char *bridge)
{
char brdirname[22 + IFNAMSIZ + 1] = {0};
struct stat sb;

snprintf(brdirname, 22 +IFNAMSIZ + 1, "/sys/class/net/%s/bridge", bridge);
if (stat(brdirname, &sb) == -1 && errno == ENOENT)
return true;
return false;
}

static int attach_to_ovs_bridge(const char *bridge, const char *nic)
{
pid_t pid;
const char *progname;

pid = fork();
if (pid < 0)
return -1;
if (pid > 0)
return wait_for_pid(pid);

progname = strrchr(OVS_CTL_PATH, '/');
if (!progname) // not sane, should we just fail?
progname = OVS_CTL_PATH;
if (execl(OVS_CTL_PATH, progname, "add-port", bridge, nic, NULL))
exit(1);
// not reached
exit(1);
}
#else
static inline bool is_ovs_bridge(const char *bridge) { return false; }
static inline int attach_to_ovs_bridge(const char *bridge, const char *nic)
{
retun -1;
}
#endif

/*
* There is a lxc_bridge_attach, but no need of a bridge detach
* as automatically done by kernel when a netdev is deleted.
Expand All @@ -1186,6 +1226,9 @@ int lxc_bridge_attach(const char *bridge, const char *ifname)
if (!index)
return -EINVAL;

if (is_ovs_bridge(bridge))
return attach_to_ovs_bridge(bridge, ifname);

fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
return -errno;
Expand Down

0 comments on commit 0d20477

Please sign in to comment.