]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Support openvswitch bridges
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 21 Jul 2014 22:48:55 +0000 (17:48 -0500)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Wed, 23 Jul 2014 14:43:10 +0000 (09:43 -0500)
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>
configure.ac
src/lxc/Makefile.am
src/lxc/network.c

index a9393a2ca0b12b7954799e5c12d4d8aeb4d780c9..23a5b012f759d26a007ac60d9586d5d2722fe569 100644 (file)
@@ -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]])],
@@ -755,6 +765,7 @@ Environment:
  - rpath: $enable_rpath
  - GnuTLS: $enable_gnutls
  - Bash integration: $enable_bash
+ - Openvswitch: $enable_ovs
 
 Security features:
  - Apparmor: $enable_apparmor
index 310d3e8a2340a6e394f3443b475abbb4d731099d..cdc6833fb292700e25e77bfb59a66c449dcf7e7c 100644 (file)
@@ -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
index a9900def335a21a75c5da2fa47f33beaa47a682b..42706196a5b7f00e04cc7fb4c8247b40f260cc6b 100644 (file)
@@ -48,6 +48,7 @@
 #include "nl.h"
 #include "network.h"
 #include "conf.h"
+#include "utils.h"
 
 #if HAVE_IFADDRS_H
 #include <ifaddrs.h>
@@ -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.
@@ -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;