network: port ipv4 to new list type

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2021-08-26 18:15:23 +02:00
parent 19202d882b
commit 2ec31bbde7
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
4 changed files with 40 additions and 50 deletions

View File

@ -790,7 +790,6 @@ static int set_config_net_ipv4_address(const char *key, const char *value,
{ {
__do_free char *addr = NULL; __do_free char *addr = NULL;
__do_free struct lxc_inetdev *inetdev = NULL; __do_free struct lxc_inetdev *inetdev = NULL;
__do_free struct lxc_list *list = NULL;
int ret; int ret;
struct lxc_netdev *netdev = data; struct lxc_netdev *netdev = data;
char *cursor, *slash; char *cursor, *slash;
@ -806,10 +805,6 @@ static int set_config_net_ipv4_address(const char *key, const char *value,
if (!inetdev) if (!inetdev)
return ret_errno(ENOMEM); return ret_errno(ENOMEM);
list = lxc_list_new();
if (!list)
return ret_errno(ENOMEM);
addr = strdup(value); addr = strdup(value);
if (!addr) if (!addr)
return ret_errno(ENOMEM); return ret_errno(ENOMEM);
@ -856,10 +851,8 @@ static int set_config_net_ipv4_address(const char *key, const char *value,
inetdev->bcast.s_addr |= htonl(INADDR_BROADCAST >> shift); inetdev->bcast.s_addr |= htonl(INADDR_BROADCAST >> shift);
} }
list->elem = inetdev; list_add_tail(&inetdev->head, &netdev->ipv4_list);
lxc_list_add_tail(&netdev->ipv4, list);
move_ptr(inetdev); move_ptr(inetdev);
move_ptr(list);
return 0; return 0;
} }
@ -5730,15 +5723,14 @@ static int clr_config_net_ipv4_address(const char *key,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
struct lxc_netdev *netdev = data; struct lxc_netdev *netdev = data;
struct lxc_list *cur, *next; struct lxc_inetdev *inetdev, *ninetdev;
if (!netdev) if (!netdev)
return ret_errno(EINVAL); return ret_errno(EINVAL);
lxc_list_for_each_safe(cur, &netdev->ipv4, next) { list_for_each_entry_safe(inetdev, ninetdev, &netdev->ipv4_list, head) {
lxc_list_del(cur); list_del(&inetdev->head);
free(cur->elem); free(inetdev);
free(cur);
} }
return 0; return 0;
@ -6304,12 +6296,12 @@ static int get_config_net_ipv4_gateway(const char *key, char *retv, int inlen,
static int get_config_net_ipv4_address(const char *key, char *retv, int inlen, static int get_config_net_ipv4_address(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
int fulllen = 0;
struct lxc_netdev *netdev = data;
int len; int len;
size_t listlen; size_t listlen;
char buf[INET_ADDRSTRLEN]; char buf[INET_ADDRSTRLEN];
struct lxc_list *it; struct lxc_inetdev *inetdev;
int fulllen = 0;
struct lxc_netdev *netdev = data;
if (!netdev) if (!netdev)
return ret_errno(EINVAL); return ret_errno(EINVAL);
@ -6319,13 +6311,12 @@ static int get_config_net_ipv4_address(const char *key, char *retv, int inlen,
else else
memset(retv, 0, inlen); memset(retv, 0, inlen);
listlen = lxc_list_len(&netdev->ipv4); listlen = list_len(&netdev->ipv4_list);
lxc_list_for_each(it, &netdev->ipv4) { list_for_each_entry(inetdev, &netdev->ipv4_list, head) {
struct lxc_inetdev *i = it->elem; if (!inet_ntop(AF_INET, &inetdev->addr, buf, sizeof(buf)))
if (!inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)))
return -errno; return -errno;
strprint(retv, inlen, "%s/%u%s", buf, i->prefix, strprint(retv, inlen, "%s/%u%s", buf, inetdev->prefix,
(listlen-- > 1) ? "\n" : ""); (listlen-- > 1) ? "\n" : "");
} }

View File

@ -168,7 +168,7 @@ static struct lxc_netdev *lxc_network_add(struct list_head *head, int idx, bool
if (!netdev) if (!netdev)
return ret_set_errno(NULL, ENOMEM); return ret_set_errno(NULL, ENOMEM);
lxc_list_init(&netdev->ipv4); INIT_LIST_HEAD(&netdev->ipv4_list);
lxc_list_init(&netdev->ipv6); lxc_list_init(&netdev->ipv6);
/* give network a unique index */ /* give network a unique index */
@ -343,8 +343,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("ipv4 gateway: %s", bufinet4); TRACE("ipv4 gateway: %s", bufinet4);
} }
lxc_list_for_each_safe(cur, &netdev->ipv4, next) { list_for_each_entry(inet4dev, &netdev->ipv4_list, head) {
inet4dev = cur->elem;
inet_ntop(AF_INET, &inet4dev->addr, bufinet4, inet_ntop(AF_INET, &inet4dev->addr, bufinet4,
sizeof(bufinet4)); sizeof(bufinet4));
TRACE("ipv4 addr: %s", bufinet4); TRACE("ipv4 addr: %s", bufinet4);
@ -398,6 +397,7 @@ void lxc_clear_netdev(struct lxc_netdev *netdev)
{ {
struct lxc_list *cur, *next; struct lxc_list *cur, *next;
struct list_head head; struct list_head head;
struct lxc_inetdev *inetdev, *ninetdev;
ssize_t idx; ssize_t idx;
if (!netdev) if (!netdev)
@ -411,10 +411,9 @@ void lxc_clear_netdev(struct lxc_netdev *netdev)
free_disarm(netdev->mtu); free_disarm(netdev->mtu);
free_disarm(netdev->ipv4_gateway); free_disarm(netdev->ipv4_gateway);
lxc_list_for_each_safe(cur, &netdev->ipv4, next) { list_for_each_entry_safe(inetdev, ninetdev, &netdev->ipv4_list, head) {
lxc_list_del(cur); list_del(&inetdev->head);
free(cur->elem); free(inetdev);
free(cur);
} }
free_disarm(netdev->ipv6_gateway); free_disarm(netdev->ipv6_gateway);
@ -446,7 +445,7 @@ void lxc_clear_netdev(struct lxc_netdev *netdev)
head = netdev->head; head = netdev->head;
memset(netdev, 0, sizeof(struct lxc_netdev)); memset(netdev, 0, sizeof(struct lxc_netdev));
netdev->head = head; netdev->head = head;
lxc_list_init(&netdev->ipv4); INIT_LIST_HEAD(&netdev->ipv4_list);
lxc_list_init(&netdev->ipv6); lxc_list_init(&netdev->ipv6);
netdev->type = -1; netdev->type = -1;
netdev->idx = idx; netdev->idx = idx;

View File

@ -216,16 +216,18 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
return 0; return 0;
} }
static int setup_ipv4_addr_routes(struct lxc_list *ip, int ifindex) static int setup_ipv4_addr_routes(struct lxc_netdev *netdev)
{ {
struct lxc_list *iterator;
int err; int err;
struct lxc_inetdev *inetdev;
int ifindex;
lxc_list_for_each(iterator, ip) { if (netdev->type != LXC_NET_VETH)
struct lxc_inetdev *inetdev = iterator->elem; return ret_errno(EINVAL);
ifindex = netdev->priv.veth_attr.ifindex;
list_for_each_entry(inetdev, &netdev->ipv4_list, head) {
err = lxc_ipv4_dest_add(ifindex, &inetdev->addr, 32); err = lxc_ipv4_dest_add(ifindex, &inetdev->addr, 32);
if (err) if (err)
return log_error_errno(-1, err, "Failed to setup ipv4 address route for network device with eifindex %d", ifindex); return log_error_errno(-1, err, "Failed to setup ipv4 address route for network device with eifindex %d", ifindex);
} }
@ -817,7 +819,7 @@ static int netdev_configure_server_veth(struct lxc_handler *handler, struct lxc_
} }
/* setup ipv4 address routes on the host interface */ /* setup ipv4 address routes on the host interface */
err = setup_ipv4_addr_routes(&netdev->ipv4, netdev->priv.veth_attr.ifindex); err = setup_ipv4_addr_routes(netdev);
if (err) { if (err) {
SYSERROR("Failed to setup ip address routes for network device \"%s\"", veth1); SYSERROR("Failed to setup ip address routes for network device \"%s\"", veth1);
goto out_delete; goto out_delete;
@ -3229,7 +3231,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* If IPv4 addresses are specified, then check that sysctl is configured correctly. */ /* If IPv4 addresses are specified, then check that sysctl is configured correctly. */
if (!lxc_list_empty(&netdev->ipv4)) { if (!list_empty(&netdev->ipv4_list)) {
/* Check for net.ipv4.conf.[link].forwarding=1 */ /* Check for net.ipv4.conf.[link].forwarding=1 */
if (lxc_is_ip_forwarding_enabled(netdev->link, AF_INET) < 0) if (lxc_is_ip_forwarding_enabled(netdev->link, AF_INET) < 0)
return log_error_errno(-1, EINVAL, "Requires sysctl net.ipv4.conf.%s.forwarding=1", netdev->link); return log_error_errno(-1, EINVAL, "Requires sysctl net.ipv4.conf.%s.forwarding=1", netdev->link);
@ -3258,8 +3260,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
return log_error_errno(-1, EINVAL, "Failed to retrieve ifindex for \"%s\" routing cleanup", loop_device); return log_error_errno(-1, EINVAL, "Failed to retrieve ifindex for \"%s\" routing cleanup", loop_device);
} }
lxc_list_for_each_safe(cur, &netdev->ipv4, next) { list_for_each_entry(inet4dev, &netdev->ipv4_list, head) {
inet4dev = cur->elem;
if (!inet_ntop(AF_INET, &inet4dev->addr, bufinet4, sizeof(bufinet4))) if (!inet_ntop(AF_INET, &inet4dev->addr, bufinet4, sizeof(bufinet4)))
return ret_set_errno(-1, -errno); return ret_set_errno(-1, -errno);
@ -3378,8 +3379,7 @@ static int lxc_delete_l2proxy(struct lxc_netdev *netdev) {
} }
} }
lxc_list_for_each_safe(cur, &netdev->ipv4, next) { list_for_each_entry(inet4dev, &netdev->ipv4_list, head) {
inet4dev = cur->elem;
if (lxc_delete_ipv4_l2proxy(&inet4dev->addr, netdev->link, lo_ifindex) < 0) if (lxc_delete_ipv4_l2proxy(&inet4dev->addr, netdev->link, lo_ifindex) < 0)
errCount++; errCount++;
} }
@ -3810,16 +3810,15 @@ static int setup_hw_addr(char *hwaddr, const char *ifname)
return ret; return ret;
} }
static int setup_ipv4_addr(struct lxc_list *ip, int ifindex) static int setup_ipv4_addr(struct lxc_netdev *netdev)
{ {
struct lxc_list *iterator; int ifindex = netdev->ifindex;
int err; int err;
struct lxc_inetdev *inet4dev;
lxc_list_for_each(iterator, ip) { list_for_each_entry(inet4dev, &netdev->ipv4_list, head) {
struct lxc_inetdev *inetdev = iterator->elem; err = lxc_ipv4_addr_add(ifindex, &inet4dev->addr,
&inet4dev->bcast, inet4dev->prefix);
err = lxc_ipv4_addr_add(ifindex, &inetdev->addr,
&inetdev->bcast, inetdev->prefix);
if (err) if (err)
return log_error_errno(-1, -err, "Failed to setup ipv4 address for network device with ifindex %d", ifindex); return log_error_errno(-1, -err, "Failed to setup ipv4 address for network device with ifindex %d", ifindex);
} }
@ -3855,7 +3854,7 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
return log_error_errno(-1, errno, "Failed to setup hw address for network device \"%s\"", netdev->name); return log_error_errno(-1, errno, "Failed to setup hw address for network device \"%s\"", netdev->name);
/* setup ipv4 addresses on the interface */ /* setup ipv4 addresses on the interface */
if (setup_ipv4_addr(&netdev->ipv4, netdev->ifindex)) if (setup_ipv4_addr(netdev))
return log_error_errno(-1, errno, "Failed to setup ip addresses for network device \"%s\"", netdev->name); return log_error_errno(-1, errno, "Failed to setup ip addresses for network device \"%s\"", netdev->name);
/* setup ipv6 addresses on the interface */ /* setup ipv6 addresses on the interface */
@ -3879,7 +3878,7 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
if (!(netdev->flags & IFF_UP)) if (!(netdev->flags & IFF_UP))
return log_error(-1, "Cannot add ipv4 gateway for network device \"%s\" when not bringing up the interface", netdev->name); return log_error(-1, "Cannot add ipv4 gateway for network device \"%s\" when not bringing up the interface", netdev->name);
if (lxc_list_empty(&netdev->ipv4)) if (list_empty(&netdev->ipv4_list))
return log_error(-1, "Cannot add ipv4 gateway for network device \"%s\" when not assigning an address", netdev->name); return log_error(-1, "Cannot add ipv4 gateway for network device \"%s\" when not assigning an address", netdev->name);
/* Setup device route if ipv4_gateway_dev is enabled */ /* Setup device route if ipv4_gateway_dev is enabled */

View File

@ -39,6 +39,7 @@ struct lxc_inetdev {
struct in_addr addr; struct in_addr addr;
struct in_addr bcast; struct in_addr bcast;
unsigned int prefix; unsigned int prefix;
struct list_head head;
}; };
struct lxc_route { struct lxc_route {
@ -171,7 +172,7 @@ struct lxc_netdev {
char *hwaddr; char *hwaddr;
char *mtu; char *mtu;
union netdev_p priv; union netdev_p priv;
struct lxc_list ipv4; struct list_head ipv4_list;
struct lxc_list ipv6; struct lxc_list ipv6;
bool ipv4_gateway_auto; bool ipv4_gateway_auto;
bool ipv4_gateway_dev; bool ipv4_gateway_dev;