summaryrefslogtreecommitdiffstats
path: root/src/nspawn/nspawn-network.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-04-25 13:42:20 +0200
committerLennart Poettering <lennart@poettering.net>2016-04-25 13:44:24 +0200
commitef3b2aa7a16cae897390feda791675c9fb2e8116 (patch)
treed971c138bb0cbf5a421a6e4ebe7c41330685a361 /src/nspawn/nspawn-network.c
parentsd-netlink: permit RTM_DELLINK messages with no ifindex (diff)
downloadsystemd-ef3b2aa7a16cae897390feda791675c9fb2e8116.tar.xz
systemd-ef3b2aa7a16cae897390feda791675c9fb2e8116.zip
nspawn: explicitly remove veth links we created after use
Sometimes the kernel keeps veth links pinned after the namespace they have been joined to died. Let's hence explicitly remove veth links after use. Fixes: #2173
Diffstat (limited to 'src/nspawn/nspawn-network.c')
-rw-r--r--src/nspawn/nspawn-network.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c
index 74a0ae865b..f2b7e4dd79 100644
--- a/src/nspawn/nspawn-network.c
+++ b/src/nspawn/nspawn-network.c
@@ -538,3 +538,50 @@ int veth_extra_parse(char ***l, const char *p) {
a = b = NULL;
return 0;
}
+
+static int remove_one_veth_link(sd_netlink *rtnl, const char *name) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+ int r;
+
+ if (isempty(name))
+ return 0;
+
+ r = sd_rtnl_message_new_link(rtnl, &m, RTM_DELLINK, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate netlink message: %m");
+
+ r = sd_netlink_message_append_string(m, IFLA_IFNAME, name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add netlink interface name: %m");
+
+ r = sd_netlink_call(rtnl, m, 0, NULL);
+ if (r == -ENODEV) /* Already gone */
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to remove veth interface %s: %m", name);
+
+ return 1;
+}
+
+int remove_veth_links(const char *primary, char **pairs) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ char **a, **b;
+ int r;
+
+ /* In some cases the kernel might pin the veth links between host and container even after the namespace
+ * died. Hence, let's better remove them explicitly too. */
+
+ if (isempty(primary) && strv_isempty(pairs))
+ return 0;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ remove_one_veth_link(rtnl, primary);
+
+ STRV_FOREACH_PAIR(a, b, pairs)
+ remove_one_veth_link(rtnl, *a);
+
+ return 0;
+}