]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
tree-wide: port network handling to new list type
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 25 Aug 2021 10:13:40 +0000 (12:13 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 25 Aug 2021 11:25:03 +0000 (13:25 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/confile_utils.c
src/lxc/confile_utils.h
src/lxc/criu.c
src/lxc/hlist.h
src/lxc/network.c
src/lxc/network.h

index b11737bdbcac9b673b2fac625cd524942dce1034..c086f4c81c29f9befeedeef829e7ca1cbcedd79d 100644 (file)
@@ -3379,7 +3379,6 @@ struct lxc_conf *lxc_conf_init(void)
        /* Block ("allowlist") all devices by default. */
        new->bpf_devices.list_type = LXC_BPF_DEVICE_CGROUP_ALLOWLIST;
        lxc_list_init(&(new->bpf_devices).device_item);
-       lxc_list_init(&new->network);
        lxc_list_init(&new->mount_list);
        lxc_list_init(&new->caps);
        lxc_list_init(&new->keepcaps);
@@ -3416,6 +3415,8 @@ struct lxc_conf *lxc_conf_init(void)
        memset(&new->timens, 0, sizeof(struct timens_offsets));
        seccomp_conf_init(new);
 
+       INIT_LIST_HEAD(&new->netdevs);
+
        return new;
 }
 
@@ -4312,8 +4313,7 @@ int lxc_setup(struct lxc_handler *handler)
                if (ret < 0)
                        return log_error(-1, "Failed to receive veth names from parent");
 
-               ret = lxc_setup_network_in_child_namespaces(lxc_conf,
-                                                           &lxc_conf->network);
+               ret = lxc_setup_network_in_child_namespaces(lxc_conf);
                if (ret < 0)
                        return log_error(-1, "Failed to setup network");
        }
@@ -4831,7 +4831,7 @@ void lxc_conf_free(struct lxc_conf *conf)
        free(conf->init_cwd);
        free(conf->unexpanded_config);
        free(conf->syslog);
-       lxc_free_networks(&conf->network);
+       lxc_free_networks(conf);
        free(conf->lsm_aa_profile);
        free(conf->lsm_aa_profile_computed);
        free(conf->lsm_se_context);
index c5bf3a702b1d0e4b9575dc2cdfc1cb8c1ebb26b8..696ebd74161ddfffcea7a3936e69f91f1a4945f7 100644 (file)
@@ -19,6 +19,7 @@
 #include "caps.h"
 #include "compiler.h"
 #include "config.h"
+#include "hlist.h"
 #include "list.h"
 #include "lxcseccomp.h"
 #include "memory_utils.h"
@@ -358,7 +359,7 @@ struct lxc_conf {
                const struct id_map *root_nsgid_map;
        };
 
-       struct lxc_list network;
+       struct list_head netdevs;
 
        struct {
                char *fstab;
index bf190e08bf1977b6fcd6ba525301a06302aa4a1b..d63b6b60a8bf2c958a428542cbb71d66a9e91b2c 100644 (file)
@@ -3600,7 +3600,6 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
 bool network_new_hwaddrs(struct lxc_conf *conf)
 {
        char *lend, *p, *p2;
-       struct lxc_list *it;
        char *lstart = conf->unexpanded_config;
 
        if (!conf->unexpanded_config)
@@ -3608,6 +3607,7 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
 
        while (*lstart) {
                char newhwaddr[18], oldhwaddr[17];
+               struct lxc_netdev *netdev;
 
                lend = strchr(lstart, '\n');
                if (!lend)
@@ -3648,11 +3648,9 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
                        return false;
 
                memcpy(p, newhwaddr, 17);
-               lxc_list_for_each(it, &conf->network) {
-                       struct lxc_netdev *n = it->elem;
-
-                       if (n->hwaddr && memcmp(oldhwaddr, n->hwaddr, 17) == 0)
-                               memcpy(n->hwaddr, newhwaddr, 17);
+               list_for_each_entry(netdev, &conf->netdevs, head) {
+                       if (netdev->hwaddr && memcmp(oldhwaddr, netdev->hwaddr, 17) == 0)
+                               memcpy(netdev->hwaddr, newhwaddr, 17);
                }
 
                lstart = lend;
@@ -4267,16 +4265,15 @@ static int get_config_net(const char *key, char *retv, int inlen,
                          struct lxc_conf *c, void *data)
 {
        int len, fulllen = 0;
-       struct lxc_list *it;
+       struct lxc_netdev *netdev;
 
        if (!retv)
                inlen = 0;
        else
                memset(retv, 0, inlen);
 
-       lxc_list_for_each(it, &c->network) {
-               struct lxc_netdev *n = it->elem;
-               const char *t = lxc_net_type_to_str(n->type);
+       list_for_each_entry(netdev, &c->netdevs, head) {
+               const char *t = lxc_net_type_to_str(netdev->type);
                strprint(retv, inlen, "%s\n", t ? t : "(invalid)");
        }
 
@@ -5047,7 +5044,7 @@ static inline int clr_config_hooks_version(const char *key, struct lxc_conf *c,
 static inline int clr_config_net(const char *key, struct lxc_conf *c,
                                 void *data)
 {
-       lxc_free_networks(&c->network);
+       lxc_free_networks(c);
 
        return 0;
 }
index df25c031aad534621fedfeb7e03e4846faa954c0..3c46b3c56c474819bcab72a0eb84a831b918ea6f 100644 (file)
@@ -159,9 +159,8 @@ bool lxc_config_value_empty(const char *value)
        return true;
 }
 
-struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail)
+static struct lxc_netdev *lxc_network_add(struct list_head *head, int idx, bool tail)
 {
-       __do_free struct lxc_list *newlist = NULL;
        __do_free struct lxc_netdev *netdev = NULL;
 
        /* network does not exist */
@@ -175,17 +174,10 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
        /* give network a unique index */
        netdev->idx = idx;
 
-       /* prepare new list */
-       newlist = lxc_list_new();
-       if (!newlist)
-               return ret_set_errno(NULL, ENOMEM);
-       newlist->elem = netdev;
-
        if (tail)
-               lxc_list_add_tail(networks, newlist);
+               list_add_tail(&netdev->head, head);
        else
-               lxc_list_add(networks, newlist);
-       move_ptr(newlist);
+               list_add(&netdev->head, head);
 
        return move_ptr(netdev);
 }
@@ -196,25 +188,26 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
 struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf,
                                         unsigned int idx, bool allocate)
 {
-       struct lxc_list *networks = &conf->network;
-       struct lxc_list *insert = networks;
+       struct list_head *netdevs = &conf->netdevs;
+       struct list_head *head = netdevs;
+       struct lxc_netdev *netdev;
 
        /* lookup network */
-       if (!lxc_list_empty(networks)) {
-               lxc_list_for_each(insert, networks) {
-                       struct lxc_netdev *netdev = insert->elem;
-
+       if (!list_empty(netdevs)) {
+               list_for_each_entry(netdev, netdevs, head) {
                        /* found network device */
                        if (netdev->idx == idx)
                                return netdev;
 
-                       if (netdev->idx > idx)
+                       if (netdev->idx > idx) {
+                               head = &netdev->head;
                                break;
+                       }
                }
        }
 
        if (allocate)
-               return lxc_network_add(insert, idx, true);
+               return lxc_network_add(head, idx, true);
 
        return NULL;
 }
@@ -222,24 +215,22 @@ struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf,
 void lxc_log_configured_netdevs(const struct lxc_conf *conf)
 {
        struct lxc_netdev *netdev;
-       struct lxc_list *it = (struct lxc_list *)&conf->network;;
+       const struct list_head *netdevs = &conf->netdevs;
 
        if (!lxc_log_trace())
                return;
 
-       if (lxc_list_empty(it)) {
+       if (list_empty(netdevs)) {
                TRACE("container has no networks configured");
                return;
        }
 
-       lxc_list_for_each(it, &conf->network) {
+       list_for_each_entry(netdev, netdevs, head) {
                struct lxc_list *cur, *next;
                struct lxc_inetdev *inet4dev;
                struct lxc_inet6dev *inet6dev;
                char bufinet4[INET_ADDRSTRLEN], bufinet6[INET6_ADDRSTRLEN];
 
-               netdev = it->elem;
-
                TRACE("index: %zd", netdev->idx);
                TRACE("ifindex: %d", netdev->ifindex);
 
@@ -406,6 +397,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
 void lxc_clear_netdev(struct lxc_netdev *netdev)
 {
        struct lxc_list *cur, *next;
+       struct list_head head;
        ssize_t idx;
 
        if (!netdev)
@@ -451,7 +443,9 @@ void lxc_clear_netdev(struct lxc_netdev *netdev)
                }
        }
 
+       head = netdev->head;
        memset(netdev, 0, sizeof(struct lxc_netdev));
+       netdev->head = head;
        lxc_list_init(&netdev->ipv4);
        lxc_list_init(&netdev->ipv6);
        netdev->type = -1;
@@ -468,40 +462,37 @@ static void lxc_free_netdev(struct lxc_netdev *netdev)
 
 bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx)
 {
-       struct lxc_list *cur, *next;
+       struct lxc_netdev *netdev;
 
-       if (lxc_list_empty(&conf->network))
+       if (list_empty(&conf->netdevs))
                return false;
 
-       lxc_list_for_each_safe(cur, &conf->network, next) {
-               struct lxc_netdev *netdev = cur->elem;
-
+       list_for_each_entry(netdev, &conf->netdevs, head) {
                if (netdev->idx != idx)
                        continue;
 
-               lxc_list_del(cur);
+               list_del(&netdev->head);
                lxc_free_netdev(netdev);
-               free(cur);
                return true;
        }
 
        return false;
 }
 
-void lxc_free_networks(struct lxc_list *networks)
+void lxc_free_networks(struct lxc_conf *conf)
 {
-       struct lxc_list *cur, *next;
+       struct lxc_netdev *netdev, *n;
 
-       lxc_list_for_each_safe (cur, networks, next) {
-               struct lxc_netdev *netdev = cur->elem;
+       if (list_empty(&conf->netdevs))
+               return;
 
-               lxc_list_del(cur);
+       list_for_each_entry_safe(netdev, n, &conf->netdevs, head) {
+               list_del(&netdev->head);
                lxc_free_netdev(netdev);
-               free(cur);
        }
 
        /* prevent segfaults */
-       lxc_list_init(networks);
+       INIT_LIST_HEAD(&conf->netdevs);
 }
 
 static struct lxc_veth_mode {
index f675ac176f8ac907fe0d23c00e31551c9ea4cd69..7dae2aec7fcb085c1252626f483f991315107dba 100644 (file)
@@ -31,12 +31,11 @@ __hidden extern int parse_idmaps(const char *idmap, char *type, unsigned long *n
                                 unsigned long *hostid, unsigned long *range);
 
 __hidden extern bool lxc_config_value_empty(const char *value);
-__hidden extern struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail);
 __hidden extern struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf, unsigned int idx,
                                                         bool allocate);
 __hidden extern void lxc_log_configured_netdevs(const struct lxc_conf *conf);
 __hidden extern bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx);
-__hidden extern void lxc_free_networks(struct lxc_list *networks);
+__hidden extern void lxc_free_networks(struct lxc_conf *conf);
 __hidden extern void lxc_clear_netdev(struct lxc_netdev *netdev);
 __hidden extern int lxc_veth_mode_to_flag(int *mode, const char *value);
 __hidden extern char *lxc_veth_flag_to_mode(int mode);
index 2ad2ef4c1badbf5c3c5cc0f08046fee03232e3ef..f936bea1441889d3e9b17c1264bce4b1b95e70c6 100644 (file)
@@ -168,7 +168,6 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
        char log[PATH_MAX];
        int static_args = 23, ret;
        int netnr = 0;
-       struct lxc_list *it;
        struct mntent mntent;
 
        char buf[4096], ttys[32];
@@ -233,7 +232,7 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                if (ttys[0])
                        static_args += 2;
 
-               static_args += lxc_list_len(&opts->c->lxc_conf->network) * 2;
+               static_args += list_len(&opts->c->lxc_conf->netdevs) * 2;
        } else {
                return log_error_errno(-EINVAL, EINVAL, "Invalid criu operation specified");
        }
@@ -454,6 +453,7 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                        DECLARE_ARG("--leave-running");
        } else if (strequal(opts->action, "restore")) {
                struct lxc_conf *lxc_conf = opts->c->lxc_conf;
+               struct lxc_netdev *netdev;
 
                DECLARE_ARG("--root");
                DECLARE_ARG(opts->c->lxc_conf->rootfs.mount);
@@ -492,10 +492,9 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                        DECLARE_ARG(buf);
                }
 
-               lxc_list_for_each(it, &opts->c->lxc_conf->network) {
+               list_for_each_entry(netdev, &opts->c->lxc_conf->netdevs, head) {
                        size_t retlen;
                        char eth[128], *veth;
-                       struct lxc_netdev *n = it->elem;
                        bool external_not_veth;
 
                        if (cmp_version(opts->criu_version, CRIU_EXTERNAL_NOT_VETH) >= 0) {
@@ -508,8 +507,8 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                                external_not_veth = false;
                        }
 
-                       if (n->name[0] != '\0') {
-                               retlen = strlcpy(eth, n->name, sizeof(eth));
+                       if (netdev->name[0] != '\0') {
+                               retlen = strlcpy(eth, netdev->name, sizeof(eth));
                                if (retlen >= sizeof(eth))
                                        return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name");
                        } else {
@@ -518,17 +517,17 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                                        return log_error_errno(-E2BIG, E2BIG, "Failed to append veth device name");
                        }
 
-                       switch (n->type) {
+                       switch (netdev->type) {
                        case LXC_NET_VETH:
-                               veth = n->priv.veth_attr.pair;
+                               veth = netdev->priv.veth_attr.pair;
                                if (veth[0] == '\0')
-                                       veth = n->priv.veth_attr.veth1;
+                                       veth = netdev->priv.veth_attr.veth1;
 
-                               if (n->link[0] != '\0') {
+                               if (netdev->link[0] != '\0') {
                                        if (external_not_veth)
-                                               ret = strnprintf(buf, sizeof(buf), "veth[%s]:%s@%s", eth, veth, n->link);
+                                               ret = strnprintf(buf, sizeof(buf), "veth[%s]:%s@%s", eth, veth, netdev->link);
                                        else
-                                               ret = strnprintf(buf, sizeof(buf), "%s=%s@%s", eth, veth, n->link);
+                                               ret = strnprintf(buf, sizeof(buf), "%s=%s@%s", eth, veth, netdev->link);
                                } else {
                                        if (external_not_veth)
                                                ret = strnprintf(buf, sizeof(buf), "veth[%s]:%s", eth, veth);
@@ -541,10 +540,10 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                                TRACE("Added veth device entry %s", buf);
                                break;
                        case LXC_NET_MACVLAN:
-                               if (n->link[0] == '\0')
-                                       return log_error_errno(-EINVAL, EINVAL, "Failed to find host interface for macvlan %s", n->name);
+                               if (netdev->link[0] == '\0')
+                                       return log_error_errno(-EINVAL, EINVAL, "Failed to find host interface for macvlan %s", netdev->name);
 
-                               ret = strnprintf(buf, sizeof(buf), "macvlan[%s]:%s", eth, n->link);
+                               ret = strnprintf(buf, sizeof(buf), "macvlan[%s]:%s", eth, netdev->link);
                                if (ret < 0)
                                        return log_error_errno(-EIO, EIO, "Failed to add macvlan entry");
 
@@ -556,7 +555,7 @@ static int exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf,
                                break;
                        default:
                                /* we have screened for this earlier... */
-                               return log_error_errno(-EINVAL, EINVAL, "Unsupported network type %d", n->type);
+                               return log_error_errno(-EINVAL, EINVAL, "Unsupported network type %d", netdev->type);
                        }
 
                        if (external_not_veth)
@@ -809,7 +808,7 @@ version_error:
  * dump. */
 static bool criu_ok(struct lxc_container *c, char **criu_version)
 {
-       struct lxc_list *it;
+       struct lxc_netdev *netdev;
 
        if (geteuid()) {
                ERROR("Must be root to checkpoint");
@@ -820,16 +819,15 @@ static bool criu_ok(struct lxc_container *c, char **criu_version)
                return false;
 
        /* We only know how to restore containers with veth networks. */
-       lxc_list_for_each(it, &c->lxc_conf->network) {
-               struct lxc_netdev *n = it->elem;
-               switch(n->type) {
+       list_for_each_entry(netdev, &c->lxc_conf->netdevs, head) {
+               switch(netdev->type) {
                case LXC_NET_VETH:
                case LXC_NET_NONE:
                case LXC_NET_EMPTY:
                case LXC_NET_MACVLAN:
                        break;
                default:
-                       ERROR("Found un-dumpable network: %s (%s)", lxc_net_type_to_str(n->type), n->name);
+                       ERROR("Found un-dumpable network: %s (%s)", lxc_net_type_to_str(netdev->type), netdev->name);
                        if (criu_version) {
                                free(*criu_version);
                                *criu_version = NULL;
@@ -844,14 +842,13 @@ static bool criu_ok(struct lxc_container *c, char **criu_version)
 static bool restore_net_info(struct lxc_container *c)
 {
        int ret;
-       struct lxc_list *it;
        bool has_error = true;
+       struct lxc_netdev *netdev;
 
        if (container_mem_lock(c))
                return false;
 
-       lxc_list_for_each(it, &c->lxc_conf->network) {
-               struct lxc_netdev *netdev = it->elem;
+       list_for_each_entry(netdev, &c->lxc_conf->netdevs, head) {
                char template[IFNAMSIZ];
 
                if (netdev->type != LXC_NET_VETH)
index 3120144282cde86f20e98e8225c2ae560ac0f2d5..9a088f0d478fed341b1b463894342faea5503579 100644 (file)
@@ -961,4 +961,15 @@ static inline void hlist_move_list(struct hlist_head *old,
             pos && ({ n = pos->member.next; 1; });                     \
             pos = hlist_entry_safe(n, typeof(*pos), member))
 
+static inline size_t list_len(struct list_head *list)
+{
+       size_t i = 0;
+
+       list_for_each(list, list) {
+               i++;
+       }
+
+       return i;
+}
+
 #endif /* __LXC_HLIST_H */
index 54fe61550f2708c0a4ea08933faa61e44f2e6377..5e3743bc4524446574e6822b20630767a1da8b2c 100644 (file)
@@ -2852,23 +2852,18 @@ int setup_private_host_hw_addr(char *veth1)
 
 int lxc_find_gateway_addresses(struct lxc_handler *handler)
 {
-       struct lxc_list *network = &handler->conf->network;
-       struct lxc_list *iterator;
        struct lxc_netdev *netdev;
        int link_index;
 
-       lxc_list_for_each(iterator, network) {
-               netdev = iterator->elem;
-
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                if (!netdev->ipv4_gateway_auto && !netdev->ipv6_gateway_auto)
                        continue;
 
                if (netdev->type != LXC_NET_VETH && netdev->type != LXC_NET_MACVLAN)
                        return log_error_errno(-1, EINVAL, "Automatic gateway detection is only supported for veth and macvlan");
 
-               if (is_empty_string(netdev->link)) {
+               if (is_empty_string(netdev->link))
                        return log_error_errno(-1, errno, "Automatic gateway detection needs a link interface");
-               }
 
                link_index = if_nametoindex(netdev->link);
                if (!link_index)
@@ -3127,8 +3122,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 static bool lxc_delete_network_unpriv(struct lxc_handler *handler)
 {
        int ret;
-       struct lxc_list *iterator;
-       struct lxc_list *network = &handler->conf->network;
+       struct lxc_netdev *netdev;
        /* strlen("/proc/") = 6
         * +
         * INTTYPE_TO_STRLEN(pid_t)
@@ -3151,9 +3145,8 @@ static bool lxc_delete_network_unpriv(struct lxc_handler *handler)
        if (ret < 0)
                return false;
 
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                char *hostveth = NULL;
-               struct lxc_netdev *netdev = iterator->elem;
 
                /* We can only delete devices whose ifindex we have. If we don't
                 * have the index it means that we didn't create it.
@@ -3405,12 +3398,9 @@ static int lxc_delete_l2proxy(struct lxc_netdev *netdev) {
 
 static int lxc_create_network_priv(struct lxc_handler *handler)
 {
-       struct lxc_list *iterator;
-       struct lxc_list *network = &handler->conf->network;
-
-       lxc_list_for_each(iterator, network) {
-               struct lxc_netdev *netdev = iterator->elem;
+       struct lxc_netdev *netdev;
 
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE)
                        return log_error_errno(-1, EINVAL, "Invalid network configuration type %d", netdev->type);
 
@@ -3519,16 +3509,14 @@ static int netdev_requires_move(const struct lxc_netdev *netdev)
 int lxc_network_move_created_netdev_priv(struct lxc_handler *handler)
 {
        pid_t pid = handler->pid;
-       struct lxc_list *network = &handler->conf->network;
-       struct lxc_list *iterator;
+       struct lxc_netdev *netdev;
 
        if (am_guest_unpriv())
                return 0;
 
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                __do_free char *physname = NULL;
                int ret;
-               struct lxc_netdev *netdev = iterator->elem;
 
                if (!netdev_requires_move(netdev))
                        continue;
@@ -3571,13 +3559,10 @@ static int lxc_create_network_unpriv(struct lxc_handler *handler)
        int hooks_version = handler->conf->hooks_version;
        const char *lxcname = handler->name;
        const char *lxcpath = handler->lxcpath;
-       struct lxc_list *network = &handler->conf->network;
        pid_t pid = handler->pid;
-       struct lxc_list *iterator;
-
-       lxc_list_for_each(iterator, network) {
-               struct lxc_netdev *netdev = iterator->elem;
+       struct lxc_netdev *netdev;
 
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                if (!network_requires_advanced_setup(netdev->type))
                        continue;
 
@@ -3599,12 +3584,10 @@ static int lxc_create_network_unpriv(struct lxc_handler *handler)
 static bool lxc_delete_network_priv(struct lxc_handler *handler)
 {
        int ret;
-       struct lxc_list *iterator;
-       struct lxc_list *network = &handler->conf->network;
+       struct lxc_netdev *netdev;
 
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                char *hostveth = NULL;
-               struct lxc_netdev *netdev = iterator->elem;
 
                /* We can only delete devices whose ifindex we have. If we don't
                 * have the index it means that we didn't create it.
@@ -3715,15 +3698,14 @@ clear_ifindices:
 
 int lxc_requests_empty_network(struct lxc_handler *handler)
 {
-       struct lxc_list *network = &handler->conf->network;
-       struct lxc_list *iterator;
+       struct list_head *netdevs = &handler->conf->netdevs;
        bool found_none = false, found_nic = false;
+       struct lxc_netdev *netdev;
 
-       if (lxc_list_empty(network))
+       if (list_empty(netdevs))
                return 0;
 
-       lxc_list_for_each (iterator, network) {
-               struct lxc_netdev *netdev = iterator->elem;
+       list_for_each_entry(netdev, netdevs, head) {
 
                if (netdev->type == LXC_NET_NONE)
                        found_none = true;
@@ -3745,7 +3727,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
        struct lxc_conf *conf = handler->conf;
        int ret;
        char ifname[IFNAMSIZ];
-       struct lxc_list *iterator;
+       struct lxc_netdev *netdev;
 
        /*
         * If we weren't asked to clone a new network namespace, there's
@@ -3771,9 +3753,7 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
        if (ret < 0)
                return log_error_errno(-1, errno, "Failed to enter network namespace");
 
-       lxc_list_for_each(iterator, &conf->network) {
-               struct lxc_netdev *netdev = iterator->elem;
-
+       list_for_each_entry(netdev, &conf->netdevs, head) {
                if (netdev->type != LXC_NET_PHYS)
                        continue;
 
@@ -4001,18 +3981,17 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
  *
  * That'll brutally fail of course but there's nothing we can do about it.
  */
-int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
-                                         struct lxc_list *network)
+int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf)
 {
-       struct lxc_list *iterator;
        bool needs_second_pass = false;
+       struct lxc_netdev *netdev;
+       const struct list_head *netdevs = &conf->netdevs;
 
-       if (lxc_list_empty(network))
+       if (list_empty(netdevs))
                return 0;
 
        /* Configure all devices that have a specific target name. */
-       lxc_list_for_each(iterator, network) {
-               struct lxc_netdev *netdev = iterator->elem;
+       list_for_each_entry(netdev, netdevs, head) {
                int ret;
 
                if (is_empty_string(netdev->name) || strequal(netdev->name, "eth%d")) {
@@ -4030,8 +4009,7 @@ int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
 
        if (needs_second_pass) {
                /* Configure all devices that have a kernel assigned name. */
-               lxc_list_for_each(iterator, network) {
-                       struct lxc_netdev *netdev = iterator->elem;
+                       list_for_each_entry(netdev, netdevs, head) {
                        int ret;
 
                        if (!is_empty_string(netdev->name) && !strequal(netdev->name, "eth%d"))
@@ -4051,13 +4029,11 @@ int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
 
 int lxc_network_send_to_child(struct lxc_handler *handler)
 {
-       struct lxc_list *iterator;
-       struct lxc_list *network = &handler->conf->network;
        int data_sock = handler->data_sock[0];
+       struct lxc_netdev *netdev;
 
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                int ret;
-               struct lxc_netdev *netdev = iterator->elem;
 
                if (!network_requires_advanced_setup(netdev->type))
                        continue;
@@ -4078,13 +4054,11 @@ int lxc_network_send_to_child(struct lxc_handler *handler)
 
 int lxc_network_recv_from_parent(struct lxc_handler *handler)
 {
-       struct lxc_list *iterator;
-       struct lxc_list *network = &handler->conf->network;
        int data_sock = handler->data_sock[1];
+       struct lxc_netdev *netdev;
 
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                int ret;
-               struct lxc_netdev *netdev = iterator->elem;
 
                if (!network_requires_advanced_setup(netdev->type))
                        continue;
@@ -4105,16 +4079,15 @@ int lxc_network_recv_from_parent(struct lxc_handler *handler)
 
 int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handler)
 {
-       struct lxc_list *iterator, *network;
        int data_sock = handler->data_sock[0];
+       struct lxc_netdev *netdev;
+       struct list_head *netdevs = &handler->conf->netdevs;
 
        if (!handler->am_root)
                return 0;
 
-       network = &handler->conf->network;
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, netdevs, head) {
                int ret;
-               struct lxc_netdev *netdev = iterator->elem;
 
                /* Send network device name in the child's namespace to parent. */
                ret = lxc_send_nointr(data_sock, netdev->name, IFNAMSIZ, MSG_NOSIGNAL);
@@ -4131,7 +4104,7 @@ int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handler)
                TRACE("Sent network device %s with ifindex %d to parent", maybe_empty(netdev->name), netdev->ifindex);
        }
 
-       if (!lxc_list_empty(network))
+       if (!list_empty(netdevs))
                TRACE("Sent network device names and ifindices to parent");
 
        return 0;
@@ -4139,16 +4112,14 @@ int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handler)
 
 int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler)
 {
-       struct lxc_list *iterator, *network;
        int data_sock = handler->data_sock[1];
+       struct lxc_netdev *netdev;
 
        if (!handler->am_root)
                return 0;
 
-       network = &handler->conf->network;
-       lxc_list_for_each(iterator, network) {
+       list_for_each_entry(netdev, &handler->conf->netdevs, head) {
                int ret;
-               struct lxc_netdev *netdev = iterator->elem;
 
                /* Receive network device name in the child's namespace to
                 * parent.
index 3526f106fa4b610ae489b35ba6b2bfa3d3a63618..7a8bf68b91b221c4f3afd9b4fa97bde8a0ef074e 100644 (file)
@@ -11,6 +11,7 @@
 #include <unistd.h>
 
 #include "compiler.h"
+#include "hlist.h"
 #include "list.h"
 
 struct lxc_conf;
@@ -180,6 +181,7 @@ struct lxc_netdev {
        struct in6_addr *ipv6_gateway;
        char *upscript;
        char *downscript;
+       struct list_head head;
 };
 
 /* Convert a string mac address to a socket structure. */
@@ -267,8 +269,7 @@ __hidden extern void lxc_delete_network(struct lxc_handler *handler);
 __hidden extern int lxc_find_gateway_addresses(struct lxc_handler *handler);
 __hidden extern int lxc_requests_empty_network(struct lxc_handler *handler);
 __hidden extern int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler);
-__hidden extern int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
-                                                         struct lxc_list *network);
+__hidden extern int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf);
 __hidden extern int lxc_network_send_to_child(struct lxc_handler *handler);
 __hidden extern int lxc_network_recv_from_parent(struct lxc_handler *handler);
 __hidden extern int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handler);