From: Christian Brauner Date: Wed, 25 Aug 2021 10:13:40 +0000 (+0200) Subject: tree-wide: port network handling to new list type X-Git-Tag: lxc-5.0.0~103^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=87d0990c1a8da4ed4d0f63535f1221e0871c1591;p=thirdparty%2Flxc.git tree-wide: port network handling to new list type Signed-off-by: Christian Brauner --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index b11737bdb..c086f4c81 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -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); diff --git a/src/lxc/conf.h b/src/lxc/conf.h index c5bf3a702..696ebd741 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -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; diff --git a/src/lxc/confile.c b/src/lxc/confile.c index bf190e08b..d63b6b60a 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -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; } diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c index df25c031a..3c46b3c56 100644 --- a/src/lxc/confile_utils.c +++ b/src/lxc/confile_utils.c @@ -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 { diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h index f675ac176..7dae2aec7 100644 --- a/src/lxc/confile_utils.h +++ b/src/lxc/confile_utils.h @@ -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); diff --git a/src/lxc/criu.c b/src/lxc/criu.c index 2ad2ef4c1..f936bea14 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -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) diff --git a/src/lxc/hlist.h b/src/lxc/hlist.h index 312014428..9a088f0d4 100644 --- a/src/lxc/hlist.h +++ b/src/lxc/hlist.h @@ -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 */ diff --git a/src/lxc/network.c b/src/lxc/network.c index 54fe61550..5e3743bc4 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -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. diff --git a/src/lxc/network.h b/src/lxc/network.h index 3526f106f..7a8bf68b9 100644 --- a/src/lxc/network.h +++ b/src/lxc/network.h @@ -11,6 +11,7 @@ #include #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);