From: Christian Brauner Date: Wed, 14 Jun 2017 11:42:27 +0000 (+0200) Subject: network: implement lxc_get_netdev_by_idx() X-Git-Tag: lxc-2.1.0~96^2~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce2f5ae83f729915c09abdceb94e358662574664;p=thirdparty%2Flxc.git network: implement lxc_get_netdev_by_idx() lxc_get_netdev_by_idx() takes care of checking whether a given netdev struct for a given index is already allocated. If so it returns a pointer to it to the caller. If it doesn't find it it will allocate a new netdev struct and insert it into the network list at the right position. For example, let's say you have the following networks defined in your config file: lxc.network.0.type=veth lxc.network.0.link=lxcbr0 lxc.network.0.name=eth0 lxc.network.0.flags=up lxc.network.3.type=veth lxc.network.3.link=lxcbr0 lxc.network.3.name=eth1 lxc.network.3.flags=up lxc.network.3.hwaddr = 00:16:3e:5d:7d:65 lxc.network.1.type=veth lxc.network.1.link=lxcbr0 lxc.network.1.name=eth0 lxc.network.1.flags=up lxc_get_netdev_by_idx() will take care that the internal network list appears in the order: 0 1 3 The ordering of the keys themselves can also be random, meaning you could do: lxc.network.3.type=veth lxc.network.0.link=lxcbr0 lxc.network.0.name=eth0 lxc.network.3.hwaddr = 00:16:3e:5d:7d:65 lxc.network.0.flags=up lxc.network.3.flags=up lxc.network.0.type=veth lxc.network.3.link=lxcbr0 lxc.network.3.name=eth1 and lxc_get_netdev_by_idx() would still figure out the correct ordering since it keeps track of the index. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c index 8da239129..6118762e1 100644 --- a/src/lxc/confile_utils.c +++ b/src/lxc/confile_utils.c @@ -17,13 +17,22 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "config.h" + #include +#include #include #include "conf.h" +#include "confile.h" +#include "confile_utils.h" +#include "error.h" #include "log.h" +#include "list.h" #include "utils.h" +lxc_log_define(lxc_confile_utils, lxc); + int parse_idmaps(const char *idmap, char *type, unsigned long *nsid, unsigned long *hostid, unsigned long *range) { @@ -156,3 +165,73 @@ bool lxc_config_value_empty(const char *value) return true; } + +struct lxc_netdev *lxc_find_netdev_by_idx(struct lxc_conf *conf, + unsigned int idx) +{ + struct lxc_netdev *netdev = NULL; + struct lxc_list *networks = &conf->network; + struct lxc_list *insert = networks; + + /* lookup network */ + if (lxc_list_empty(networks)) + return NULL; + + lxc_list_for_each(insert, networks) { + netdev = insert->elem; + if (netdev->idx >= idx) + break; + } + + /* network already exists */ + if (netdev->idx == idx) + return netdev; + + return NULL; +} + +/* Takes care of finding the correct netdev struct in the networks list or + * allocates a new one if it couldn't be found. + */ +struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf, + unsigned int idx) +{ + struct lxc_list *newlist; + struct lxc_netdev *netdev = NULL; + struct lxc_list *networks = &conf->network; + struct lxc_list *insert = networks; + + /* lookup network */ + netdev = lxc_find_netdev_by_idx(conf, idx); + if (netdev) + return netdev; + + /* network does not exist */ + netdev = malloc(sizeof(*netdev)); + if (!netdev) + return NULL; + + memset(netdev, 0, sizeof(*netdev)); + lxc_list_init(&netdev->ipv4); + lxc_list_init(&netdev->ipv6); + + /* give network a unique index */ + netdev->idx = idx; + + /* prepare new list */ + newlist = malloc(sizeof(*newlist)); + if (!newlist) { + free(netdev); + return NULL; + } + + lxc_list_init(newlist); + newlist->elem = netdev; + + /* Insert will now point to the correct position to insert the new + * netdev. + */ + lxc_list_add_tail(insert, newlist); + + return netdev; +} diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h index 35ac10b2e..7b41af156 100644 --- a/src/lxc/confile_utils.h +++ b/src/lxc/confile_utils.h @@ -22,9 +22,15 @@ #include +#include "conf.h" + extern int parse_idmaps(const char *idmap, char *type, unsigned long *nsid, unsigned long *hostid, unsigned long *range); extern bool lxc_config_value_empty(const char *value); +extern struct lxc_netdev *lxc_find_netdev_by_idx(struct lxc_conf *conf, + unsigned int idx); +extern struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf, + unsigned int idx); #endif /* __LXC_CONFILE_UTILS_H */