summaryrefslogtreecommitdiffstats
path: root/main/lxc/0001-Support-openvswitch-bridges.patch
blob: 09f91349f5173fa0726c1bb7b756c5c9a6ddf53f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From 8acaf18100f3c974cd4a204d531fe0077e95829c Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@ubuntu.com>
Date: Mon, 21 Jul 2014 17:48:55 -0500
Subject: [PATCH 1/3] Support openvswitch bridges

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>
(cherry picked from commit 0d2047716ad6967eb4714b2448a89593dc266cef)
---
 configure.ac        | 11 +++++++++++
 src/lxc/Makefile.am |  4 ++++
 src/lxc/network.c   | 43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/configure.ac b/configure.ac
index 6ec5740..e0efae7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -192,6 +192,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]])],
@@ -740,6 +750,7 @@ Environment:
  - rpath: $enable_rpath
  - GnuTLS: $enable_gnutls
  - Bash integration: $enable_bash
+ - Openvswitch: $enable_ovs
 
 Security features:
  - Apparmor: $enable_apparmor
diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 92841aa..ddeb37e 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -129,6 +129,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
diff --git a/src/lxc/network.c b/src/lxc/network.c
index a9900de..4270619 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -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;
-- 
2.1.2