[lxc-devel] [PATCH] add lxc.network.veth.script configuration hook

Stefan Tomanek stefan at pico.ruhr.de
Thu Oct 7 07:30:54 UTC 2010


This commit adds an lxc.network.veth.script configuration option to
specify a script to be executed after creating or configuring the pair
of veth devices. The name of the host sided device is passed as first
argument, so the script can be used to configures routes or firewall
rules related to the container.
---
 src/lxc/conf.c    |   30 ++++++++++++++++++++++++++++++
 src/lxc/conf.h    |   12 +++++++-----
 src/lxc/confile.c |   20 ++++++++++++++++++++
 3 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index adfe862..be12499 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -29,6 +29,7 @@
 #include <dirent.h>
 #include <mntent.h>
 #include <unistd.h>
+#include <sys/wait.h>
 #include <pty.h>
 
 #include <sys/types.h>
@@ -1061,6 +1062,26 @@ static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
 	return 0;
 }
 
+static int run_network_script(char *script, const char *ifname)
+{
+	INFO("Executing network script '%s' for interface '%s'", script, ifname);
+	int pid = fork();
+	if (pid < 0) {
+		ERROR("Error forking");
+	} else if (pid == 0) {
+		// child
+		execl(script, script, ifname, (char *) NULL);
+		// if an error occurs, we terminate
+		exit(1);
+	} else {
+		// parent
+		int status = 0;
+		waitpid( pid, &status, 0 );
+		return status;
+	}
+	return 1;
+}
+
 static int setup_netdev(struct lxc_netdev *netdev)
 {
 	char ifname[IFNAMSIZ];
@@ -1267,6 +1288,15 @@ static int instanciate_veth(struct lxc_netdev *netdev)
 		}
 	}
 
+	if (netdev->vethscript) {
+		err = run_network_script(netdev->vethscript, veth1);
+		if (err) {
+			ERROR("failed to run script '%s' for interface '%s'",
+				      veth1, netdev->vethscript);
+			goto out_delete;
+		}
+	}
+
 	DEBUG("instanciated veth '%s/%s', index is '%d'",
 	      veth1, veth2, netdev->ifindex);
 
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index b12a346..23cf9f8 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -94,11 +94,12 @@ union netdev_p {
 
 /*
  * Defines a structure to configure a network device
- * @link   : lxc.network.link, name of bridge or host iface to attach if any
- * @name   : lxc.network.name, name of iface on the container side
- * @flags  : flag of the network device (IFF_UP, ... )
- * @ipv4   : a list of ipv4 addresses to be set on the network device
- * @ipv6   : a list of ipv6 addresses to be set on the network device
+ * @link       : lxc.network.link, name of bridge or host iface to attach if any
+ * @name       : lxc.network.name, name of iface on the container side
+ * @flags      : flag of the network device (IFF_UP, ... )
+ * @ipv4       : a list of ipv4 addresses to be set on the network device
+ * @ipv6       : a list of ipv6 addresses to be set on the network device
+ * @vethscript : a script filename to be executed on veth configuration
  */
 struct lxc_netdev {
 	int type;
@@ -111,6 +112,7 @@ struct lxc_netdev {
 	union netdev_p priv;
 	struct lxc_list ipv4;
 	struct lxc_list ipv6;
+	char *vethscript;
 };
 
 /*
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 610ca15..dce76b6 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -63,6 +63,7 @@ static int config_network_hwaddr(const char *, char *, struct lxc_conf *);
 static int config_network_vlan_id(const char *, char *, struct lxc_conf *);
 static int config_network_mtu(const char *, char *, struct lxc_conf *);
 static int config_network_ipv4(const char *, char *, struct lxc_conf *);
+static int config_veth_script(const char *, char *, struct lxc_conf *);
 static int config_network_ipv6(const char *, char *, struct lxc_conf *);
 static int config_cap_drop(const char *, char *, struct lxc_conf *);
 static int config_console(const char *, char *, struct lxc_conf *);
@@ -91,6 +92,7 @@ static struct config config[] = {
 	{ "lxc.network.name",         config_network_name         },
 	{ "lxc.network.macvlan.mode", config_network_macvlan_mode },
 	{ "lxc.network.veth.pair",    config_network_veth_pair    },
+	{ "lxc.network.veth.script",  config_veth_script          },
 	{ "lxc.network.hwaddr",       config_network_hwaddr       },
 	{ "lxc.network.mtu",          config_network_mtu          },
 	{ "lxc.network.vlan.id",      config_network_vlan_id      },
@@ -478,6 +480,24 @@ static int config_network_ipv6(const char *key, char *value,
 	return 0;
 }
 
+static int config_veth_script(const char *key, char *value,
+				 struct lxc_conf *lxc_conf)
+{
+	struct lxc_netdev *netdev;
+
+	netdev = network_netdev(key, value, &lxc_conf->network);
+	if (!netdev)
+		return -1;
+
+	netdev->vethscript = strdup(value);
+	if (!netdev->vethscript) {
+		SYSERROR("failed to dup string '%s'", value);
+		return -1;
+	}
+
+	return 0;
+}
+
 static int config_personality(const char *key, char *value,
 			      struct lxc_conf *lxc_conf)
 {
-- 
1.7.1




More information about the lxc-devel mailing list