mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 12:37:35 +00:00
network: port ipv6 addresses to new list type
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
e356020443
commit
cd32fc7300
@ -959,7 +959,6 @@ static int set_config_net_ipv6_address(const char *key, const char *value,
|
|||||||
{
|
{
|
||||||
__do_free char *valdup = NULL;
|
__do_free char *valdup = NULL;
|
||||||
__do_free struct lxc_inet6dev *inet6dev = NULL;
|
__do_free struct lxc_inet6dev *inet6dev = NULL;
|
||||||
__do_free struct lxc_list *list = NULL;
|
|
||||||
int ret;
|
int ret;
|
||||||
struct lxc_netdev *netdev = data;
|
struct lxc_netdev *netdev = data;
|
||||||
char *slash, *netmask;
|
char *slash, *netmask;
|
||||||
@ -974,10 +973,6 @@ static int set_config_net_ipv6_address(const char *key, const char *value,
|
|||||||
if (!inet6dev)
|
if (!inet6dev)
|
||||||
return ret_errno(ENOMEM);
|
return ret_errno(ENOMEM);
|
||||||
|
|
||||||
list = lxc_list_new();
|
|
||||||
if (!list)
|
|
||||||
return ret_errno(ENOMEM);
|
|
||||||
|
|
||||||
valdup = strdup(value);
|
valdup = strdup(value);
|
||||||
if (!valdup)
|
if (!valdup)
|
||||||
return ret_errno(ENOMEM);
|
return ret_errno(ENOMEM);
|
||||||
@ -997,10 +992,8 @@ static int set_config_net_ipv6_address(const char *key, const char *value,
|
|||||||
if (!ret || ret < 0)
|
if (!ret || ret < 0)
|
||||||
return log_error_errno(-EINVAL, EINVAL, "Invalid ipv6 address \"%s\"", valdup);
|
return log_error_errno(-EINVAL, EINVAL, "Invalid ipv6 address \"%s\"", valdup);
|
||||||
|
|
||||||
list->elem = inet6dev;
|
list_add_tail(&inet6dev->head, &netdev->ipv6_list);
|
||||||
lxc_list_add_tail(&netdev->ipv6, list);
|
|
||||||
move_ptr(inet6dev);
|
move_ptr(inet6dev);
|
||||||
move_ptr(list);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -5774,15 +5767,14 @@ static int clr_config_net_ipv6_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_inet6dev *inet6dev, *ninet6dev;
|
||||||
|
|
||||||
if (!netdev)
|
if (!netdev)
|
||||||
return ret_errno(EINVAL);
|
return ret_errno(EINVAL);
|
||||||
|
|
||||||
lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
|
list_for_each_entry_safe(inet6dev, ninet6dev, &netdev->ipv6_list, head) {
|
||||||
lxc_list_del(cur);
|
list_del(&inet6dev->head);
|
||||||
free(cur->elem);
|
free(inet6dev);
|
||||||
free(cur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -6392,9 +6384,9 @@ static int get_config_net_ipv6_address(const char *key, char *retv, int inlen,
|
|||||||
int len;
|
int len;
|
||||||
size_t listlen;
|
size_t listlen;
|
||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
struct lxc_list *it;
|
|
||||||
int fulllen = 0;
|
int fulllen = 0;
|
||||||
struct lxc_netdev *netdev = data;
|
struct lxc_netdev *netdev = data;
|
||||||
|
struct lxc_inet6dev *inet6dev;
|
||||||
|
|
||||||
if (!netdev)
|
if (!netdev)
|
||||||
return ret_errno(EINVAL);
|
return ret_errno(EINVAL);
|
||||||
@ -6404,13 +6396,11 @@ static int get_config_net_ipv6_address(const char *key, char *retv, int inlen,
|
|||||||
else
|
else
|
||||||
memset(retv, 0, inlen);
|
memset(retv, 0, inlen);
|
||||||
|
|
||||||
listlen = lxc_list_len(&netdev->ipv6);
|
listlen = list_len(&netdev->ipv6_list);
|
||||||
|
list_for_each_entry(inet6dev, &netdev->ipv6_list, head) {
|
||||||
lxc_list_for_each(it, &netdev->ipv6) {
|
if (!inet_ntop(AF_INET6, &inet6dev->addr, buf, sizeof(buf)))
|
||||||
struct lxc_inet6dev *i = it->elem;
|
|
||||||
if (!inet_ntop(AF_INET6, &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, inet6dev->prefix,
|
||||||
(listlen-- > 1) ? "\n" : "");
|
(listlen-- > 1) ? "\n" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ static struct lxc_netdev *lxc_network_add(struct list_head *head, int idx, bool
|
|||||||
return ret_set_errno(NULL, ENOMEM);
|
return ret_set_errno(NULL, ENOMEM);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&netdev->ipv4_list);
|
INIT_LIST_HEAD(&netdev->ipv4_list);
|
||||||
lxc_list_init(&netdev->ipv6);
|
INIT_LIST_HEAD(&netdev->ipv6_list);
|
||||||
|
|
||||||
/* give network a unique index */
|
/* give network a unique index */
|
||||||
netdev->idx = idx;
|
netdev->idx = idx;
|
||||||
@ -361,8 +361,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
|
|||||||
TRACE("ipv6 gateway: %s", bufinet6);
|
TRACE("ipv6 gateway: %s", bufinet6);
|
||||||
}
|
}
|
||||||
|
|
||||||
lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
|
list_for_each_entry(inet6dev, &netdev->ipv6_list, head) {
|
||||||
inet6dev = cur->elem;
|
|
||||||
inet_ntop(AF_INET6, &inet6dev->addr, bufinet6,
|
inet_ntop(AF_INET6, &inet6dev->addr, bufinet6,
|
||||||
sizeof(bufinet6));
|
sizeof(bufinet6));
|
||||||
TRACE("ipv6 addr: %s", bufinet6);
|
TRACE("ipv6 addr: %s", bufinet6);
|
||||||
@ -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;
|
struct lxc_inetdev *inetdev, *ninetdev;
|
||||||
|
struct lxc_inet6dev *inet6dev, *ninet6dev;
|
||||||
ssize_t idx;
|
ssize_t idx;
|
||||||
|
|
||||||
if (!netdev)
|
if (!netdev)
|
||||||
@ -417,10 +417,9 @@ void lxc_clear_netdev(struct lxc_netdev *netdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free_disarm(netdev->ipv6_gateway);
|
free_disarm(netdev->ipv6_gateway);
|
||||||
lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
|
list_for_each_entry_safe(inet6dev, ninet6dev, &netdev->ipv6_list, head) {
|
||||||
lxc_list_del(cur);
|
list_del(&inet6dev->head);
|
||||||
free(cur->elem);
|
free(inet6dev);
|
||||||
free(cur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->type == LXC_NET_VETH) {
|
if (netdev->type == LXC_NET_VETH) {
|
||||||
@ -446,7 +445,7 @@ void lxc_clear_netdev(struct lxc_netdev *netdev)
|
|||||||
memset(netdev, 0, sizeof(struct lxc_netdev));
|
memset(netdev, 0, sizeof(struct lxc_netdev));
|
||||||
netdev->head = head;
|
netdev->head = head;
|
||||||
INIT_LIST_HEAD(&netdev->ipv4_list);
|
INIT_LIST_HEAD(&netdev->ipv4_list);
|
||||||
lxc_list_init(&netdev->ipv6);
|
INIT_LIST_HEAD(&netdev->ipv6_list);
|
||||||
netdev->type = -1;
|
netdev->type = -1;
|
||||||
netdev->idx = idx;
|
netdev->idx = idx;
|
||||||
}
|
}
|
||||||
|
@ -235,13 +235,17 @@ static int setup_ipv4_addr_routes(struct lxc_netdev *netdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_ipv6_addr_routes(struct lxc_list *ip, int ifindex)
|
static int setup_ipv6_addr_routes(struct lxc_netdev *netdev)
|
||||||
{
|
{
|
||||||
struct lxc_list *iterator;
|
|
||||||
int err;
|
int err;
|
||||||
|
struct lxc_inet6dev *inet6dev;
|
||||||
|
int ifindex;
|
||||||
|
|
||||||
lxc_list_for_each(iterator, ip) {
|
if (netdev->type != LXC_NET_VETH)
|
||||||
struct lxc_inet6dev *inet6dev = iterator->elem;
|
return ret_errno(EINVAL);
|
||||||
|
|
||||||
|
ifindex = netdev->priv.veth_attr.ifindex;
|
||||||
|
list_for_each_entry(inet6dev, &netdev->ipv6_list, head) {
|
||||||
|
|
||||||
err = lxc_ipv6_dest_add(ifindex, &inet6dev->addr, 128);
|
err = lxc_ipv6_dest_add(ifindex, &inet6dev->addr, 128);
|
||||||
if (err)
|
if (err)
|
||||||
@ -826,7 +830,7 @@ static int netdev_configure_server_veth(struct lxc_handler *handler, struct lxc_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* setup ipv6 address routes on the host interface */
|
/* setup ipv6 address routes on the host interface */
|
||||||
err = setup_ipv6_addr_routes(&netdev->ipv6, netdev->priv.veth_attr.ifindex);
|
err = setup_ipv6_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;
|
||||||
@ -3218,7 +3222,6 @@ clear_ifindices:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
|
static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
|
||||||
struct lxc_list *cur, *next;
|
|
||||||
struct lxc_inetdev *inet4dev;
|
struct lxc_inetdev *inet4dev;
|
||||||
struct lxc_inet6dev *inet6dev;
|
struct lxc_inet6dev *inet6dev;
|
||||||
char bufinet4[INET_ADDRSTRLEN], bufinet6[INET6_ADDRSTRLEN];
|
char bufinet4[INET_ADDRSTRLEN], bufinet6[INET6_ADDRSTRLEN];
|
||||||
@ -3238,7 +3241,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If IPv6 addresses are specified, then check that sysctl is configured correctly. */
|
/* If IPv6 addresses are specified, then check that sysctl is configured correctly. */
|
||||||
if (!lxc_list_empty(&netdev->ipv6)) {
|
if (!list_empty(&netdev->ipv6_list)) {
|
||||||
/* Check for net.ipv6.conf.[link].proxy_ndp=1 */
|
/* Check for net.ipv6.conf.[link].proxy_ndp=1 */
|
||||||
if (lxc_is_ip_neigh_proxy_enabled(netdev->link, AF_INET6) < 0)
|
if (lxc_is_ip_neigh_proxy_enabled(netdev->link, AF_INET6) < 0)
|
||||||
return log_error_errno(-1, EINVAL, "Requires sysctl net.ipv6.conf.%s.proxy_ndp=1", netdev->link);
|
return log_error_errno(-1, EINVAL, "Requires sysctl net.ipv6.conf.%s.proxy_ndp=1", netdev->link);
|
||||||
@ -3275,8 +3278,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
|
list_for_each_entry(inet6dev, &netdev->ipv6_list, head) {
|
||||||
inet6dev = cur->elem;
|
|
||||||
if (!inet_ntop(AF_INET6, &inet6dev->addr, bufinet6, sizeof(bufinet6)))
|
if (!inet_ntop(AF_INET6, &inet6dev->addr, bufinet6, sizeof(bufinet6)))
|
||||||
return ret_set_errno(-1, -errno);
|
return ret_set_errno(-1, -errno);
|
||||||
|
|
||||||
@ -3362,10 +3364,10 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lxc_delete_l2proxy(struct lxc_netdev *netdev) {
|
static int lxc_delete_l2proxy(struct lxc_netdev *netdev)
|
||||||
|
{
|
||||||
unsigned int lo_ifindex = 0;
|
unsigned int lo_ifindex = 0;
|
||||||
unsigned int errCount = 0;
|
unsigned int err = 0;
|
||||||
struct lxc_list *cur, *next;
|
|
||||||
struct lxc_inetdev *inet4dev;
|
struct lxc_inetdev *inet4dev;
|
||||||
struct lxc_inet6dev *inet6dev;
|
struct lxc_inet6dev *inet6dev;
|
||||||
|
|
||||||
@ -3374,24 +3376,23 @@ static int lxc_delete_l2proxy(struct lxc_netdev *netdev) {
|
|||||||
/* Retrieve local-loopback interface index for use with IPVLAN static routes. */
|
/* Retrieve local-loopback interface index for use with IPVLAN static routes. */
|
||||||
lo_ifindex = if_nametoindex(loop_device);
|
lo_ifindex = if_nametoindex(loop_device);
|
||||||
if (lo_ifindex == 0) {
|
if (lo_ifindex == 0) {
|
||||||
errCount++;
|
err++;
|
||||||
ERROR("Failed to retrieve ifindex for \"%s\" routing cleanup", loop_device);
|
ERROR("Failed to retrieve ifindex for \"%s\" routing cleanup", loop_device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(inet4dev, &netdev->ipv4_list, head) {
|
list_for_each_entry(inet4dev, &netdev->ipv4_list, head) {
|
||||||
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++;
|
err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
|
list_for_each_entry(inet6dev, &netdev->ipv6_list, head) {
|
||||||
inet6dev = cur->elem;
|
|
||||||
if (lxc_delete_ipv6_l2proxy(&inet6dev->addr, netdev->link, lo_ifindex) < 0)
|
if (lxc_delete_ipv6_l2proxy(&inet6dev->addr, netdev->link, lo_ifindex) < 0)
|
||||||
errCount++;
|
err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errCount > 0)
|
if (err > 0)
|
||||||
return ret_set_errno(-1, EINVAL);
|
return ret_errno(EINVAL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3826,14 +3827,13 @@ static int setup_ipv4_addr(struct lxc_netdev *netdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
|
static int setup_ipv6_addr(struct lxc_netdev *netdev)
|
||||||
{
|
{
|
||||||
struct lxc_list *iterator;
|
|
||||||
int err;
|
int err;
|
||||||
|
struct lxc_inet6dev *inet6dev;
|
||||||
|
int ifindex = netdev->ifindex;
|
||||||
|
|
||||||
lxc_list_for_each(iterator, ip) {
|
list_for_each_entry(inet6dev, &netdev->ipv6_list, head) {
|
||||||
struct lxc_inet6dev *inet6dev = iterator->elem;
|
|
||||||
|
|
||||||
err = lxc_ipv6_addr_add(ifindex, &inet6dev->addr,
|
err = lxc_ipv6_addr_add(ifindex, &inet6dev->addr,
|
||||||
&inet6dev->mcast, &inet6dev->acast,
|
&inet6dev->mcast, &inet6dev->acast,
|
||||||
inet6dev->prefix);
|
inet6dev->prefix);
|
||||||
@ -3858,7 +3858,7 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
|
|||||||
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 */
|
||||||
if (setup_ipv6_addr(&netdev->ipv6, netdev->ifindex))
|
if (setup_ipv6_addr(netdev))
|
||||||
return log_error_errno(-1, errno, "Failed to setup ipv6 addresses for network device \"%s\"", netdev->name);
|
return log_error_errno(-1, errno, "Failed to setup ipv6 addresses for network device \"%s\"", netdev->name);
|
||||||
|
|
||||||
/* set the network device up */
|
/* set the network device up */
|
||||||
@ -3915,7 +3915,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 ipv6 gateway for network device \"%s\" when not bringing up the interface", netdev->name);
|
return log_error(-1, "Cannot add ipv6 gateway for network device \"%s\" when not bringing up the interface", netdev->name);
|
||||||
|
|
||||||
if (lxc_list_empty(&netdev->ipv6) && !IN6_IS_ADDR_LINKLOCAL(netdev->ipv6_gateway))
|
if (list_empty(&netdev->ipv6_list) && !IN6_IS_ADDR_LINKLOCAL(netdev->ipv6_gateway))
|
||||||
return log_error(-1, "Cannot add ipv6 gateway for network device \"%s\" when not assigning an address", netdev->name);
|
return log_error(-1, "Cannot add ipv6 gateway for network device \"%s\" when not assigning an address", netdev->name);
|
||||||
|
|
||||||
/* Setup device route if ipv6_gateway_dev is enabled */
|
/* Setup device route if ipv6_gateway_dev is enabled */
|
||||||
|
@ -58,6 +58,7 @@ struct lxc_inet6dev {
|
|||||||
struct in6_addr mcast;
|
struct in6_addr mcast;
|
||||||
struct in6_addr acast;
|
struct in6_addr acast;
|
||||||
unsigned int prefix;
|
unsigned int prefix;
|
||||||
|
struct list_head head;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lxc_route6 {
|
struct lxc_route6 {
|
||||||
@ -173,7 +174,7 @@ struct lxc_netdev {
|
|||||||
char *mtu;
|
char *mtu;
|
||||||
union netdev_p priv;
|
union netdev_p priv;
|
||||||
struct list_head ipv4_list;
|
struct list_head ipv4_list;
|
||||||
struct lxc_list ipv6;
|
struct list_head ipv6_list;
|
||||||
bool ipv4_gateway_auto;
|
bool ipv4_gateway_auto;
|
||||||
bool ipv4_gateway_dev;
|
bool ipv4_gateway_dev;
|
||||||
struct in_addr *ipv4_gateway;
|
struct in_addr *ipv4_gateway;
|
||||||
|
Loading…
Reference in New Issue
Block a user