Unverified Commit d42ec829 by Stéphane Graber Committed by GitHub

Merge pull request #3310 from brauner/2020-03-19/fixes

network: fix ovs removal
parents de95b436 d16bda44
......@@ -52,26 +52,26 @@ static const char loop_device[] = "lo";
static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *dest, unsigned int netmask)
{
int addrlen, err;
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int addrlen, err;
struct rtmsg *rt;
struct nlmsg *answer = NULL, *nlmsg = NULL;
addrlen = family == AF_INET ? sizeof(struct in_addr)
: sizeof(struct in6_addr);
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return -ENOMEM;
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
err = -ENOMEM;
nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
......@@ -79,7 +79,8 @@ static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *de
rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
if (!rt)
goto out;
err = -ENOMEM;
rt->rtm_family = family;
rt->rtm_table = RT_TABLE_MAIN;
rt->rtm_scope = RT_SCOPE_LINK;
......@@ -87,17 +88,13 @@ static int lxc_ip_route_dest(__u16 nlmsg_type, int family, int ifindex, void *de
rt->rtm_type = RTN_UNICAST;
rt->rtm_dst_len = netmask;
err = -EINVAL;
if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))
goto out;
return -EINVAL;
if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
goto out;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
return -EINVAL;
return netlink_transaction(nlh_ptr, nlmsg, answer);
}
static int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest, unsigned int netmask)
......@@ -129,11 +126,8 @@ static int lxc_setup_ipv4_routes(struct lxc_list *ip, int ifindex)
struct lxc_inetdev *inetdev = iterator->elem;
err = lxc_ipv4_dest_add(ifindex, &inetdev->addr, inetdev->prefix);
if (err) {
SYSERROR("Failed to setup ipv4 route for network device "
"with ifindex %d", ifindex);
return ret_set_errno(-1, -err);
}
if (err)
return log_error_errno(-1, -err, "Failed to setup ipv4 route for network device with ifindex %d", ifindex);
}
return 0;
......@@ -148,11 +142,8 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
struct lxc_inet6dev *inet6dev = iterator->elem;
err = lxc_ipv6_dest_add(ifindex, &inet6dev->addr, inet6dev->prefix);
if (err) {
SYSERROR("Failed to setup ipv6 route for network device "
"with ifindex %d", ifindex);
return ret_set_errno(-1, -err);
}
if (err)
return log_error_errno(-1, -err, "Failed to setup ipv6 route for network device with ifindex %d", ifindex);
}
return 0;
......@@ -169,9 +160,7 @@ static int setup_ipv4_addr_routes(struct lxc_list *ip, int ifindex)
err = lxc_ipv4_dest_add(ifindex, &inetdev->addr, 32);
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);
}
return 0;
......@@ -187,9 +176,7 @@ static int setup_ipv6_addr_routes(struct lxc_list *ip, int ifindex)
err = lxc_ipv6_dest_add(ifindex, &inet6dev->addr, 128);
if (err)
return log_error_errno(-1, err,
"Failed to setup ipv6 address route for network device with eifindex %d",
ifindex);
return log_error_errno(-1, err, "Failed to setup ipv6 address route for network device with eifindex %d", ifindex);
}
return 0;
......@@ -202,47 +189,42 @@ struct ip_proxy_args {
static int lxc_ip_neigh_proxy(__u16 nlmsg_type, int family, int ifindex, void *dest)
{
int addrlen, err;
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int addrlen, err;
struct ndmsg *rt;
struct nlmsg *answer = NULL, *nlmsg = NULL;
addrlen = family == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr);
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return -ENOMEM;
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
return -ENOMEM;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
nlmsg->nlmsghdr->nlmsg_type = nlmsg_type;
rt = nlmsg_reserve(nlmsg, sizeof(struct ndmsg));
if (!rt)
goto out;
return -ENOMEM;
rt->ndm_ifindex = ifindex;
rt->ndm_flags = NTF_PROXY;
rt->ndm_type = NDA_DST;
rt->ndm_family = family;
err = -EINVAL;
if (nla_put_buffer(nlmsg, NDA_DST, dest, addrlen))
goto out;
return -EINVAL;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
return netlink_transaction(nlh_ptr, nlmsg, answer);
}
static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
......@@ -254,10 +236,10 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
if (family != AF_INET && family != AF_INET6)
return ret_set_errno(-1, EINVAL);
ret = snprintf(path, PATH_MAX, "/proc/sys/net/%s/conf/%s/%s",
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
"forwarding");
if (ret < 0 || (size_t)ret >= PATH_MAX)
if (ret < 0 || (size_t)ret >= sizeof(path))
return ret_set_errno(-1, E2BIG);
return lxc_read_file_expect(path, buf, 1, "1");
......@@ -270,7 +252,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
char *veth1, *veth2;
char veth1buf[IFNAMSIZ], veth2buf[IFNAMSIZ];
if (netdev->priv.veth_attr.pair[0] != '\0') {
if (!is_empty_string(netdev->priv.veth_attr.pair)) {
veth1 = netdev->priv.veth_attr.pair;
if (handler->conf->reboot)
lxc_netdev_delete_by_name(veth1);
......@@ -299,7 +281,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
if (netdev->mtu) {
if (lxc_safe_uint(netdev->mtu, &mtu))
return log_error_errno(-1, errno, "Failed to parse mtu");
} else if (netdev->link[0] != '\0') {
} else if (!is_empty_string(netdev->link)) {
int ifindex_mtu;
ifindex_mtu = if_nametoindex(netdev->link);
......@@ -310,11 +292,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
err = lxc_veth_create(veth1, veth2, handler->pid, mtu);
if (err) {
errno = -err;
SYSERROR("Failed to create veth pair \"%s\" and \"%s\"", veth1, veth2);
return -1;
}
if (err)
return log_error_errno(-1, -err, "Failed to create veth pair \"%s\" and \"%s\"", veth1, veth2);
strlcpy(netdev->created_name, veth2, IFNAMSIZ);
......@@ -344,7 +323,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
}
if (netdev->link[0] != '\0' && netdev->priv.veth_attr.mode == VETH_MODE_BRIDGE) {
if (!is_empty_string(netdev->link) && netdev->priv.veth_attr.mode == VETH_MODE_BRIDGE) {
err = lxc_bridge_attach(netdev->link, veth1);
if (err) {
errno = -err;
......@@ -385,19 +364,19 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
if (netdev->ipv4_gateway) {
char bufinet4[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, netdev->ipv4_gateway, bufinet4, sizeof(bufinet4))) {
log_error_errno(-1, -errno, "Failed to convert gateway ipv4 address on \"%s\"", veth1);
SYSERROR("Failed to convert gateway ipv4 address on \"%s\"", veth1);
goto out_delete;
}
err = lxc_ip_forwarding_on(veth1, AF_INET);
if (err) {
log_error_errno(-1, err, "Failed to activate ipv4 forwarding on \"%s\"", veth1);
SYSERROR("Failed to activate ipv4 forwarding on \"%s\"", veth1);
goto out_delete;
}
err = lxc_ip_neigh_proxy(RTM_NEWNEIGH, AF_INET, netdev->priv.veth_attr.ifindex, netdev->ipv4_gateway);
if (err) {
log_error_errno(-1, err, "Failed to add gateway ipv4 proxy on \"%s\"", veth1);
SYSERROR("Failed to add gateway ipv4 proxy on \"%s\"", veth1);
goto out_delete;
}
}
......@@ -406,7 +385,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
char bufinet6[INET6_ADDRSTRLEN];
if (!inet_ntop(AF_INET6, netdev->ipv6_gateway, bufinet6, sizeof(bufinet6))) {
log_error_errno(-1, -errno, "Failed to convert gateway ipv6 address on \"%s\"", veth1);
SYSERROR("Failed to convert gateway ipv6 address on \"%s\"", veth1);
goto out_delete;
}
......@@ -415,25 +394,25 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
*/
err = lxc_is_ip_forwarding_enabled("all", AF_INET6);
if (err) {
log_error_errno(-1, err, "Requires sysctl net.ipv6.conf.all.forwarding=1");
SYSERROR("Requires sysctl net.ipv6.conf.all.forwarding=1");
goto out_delete;
}
err = lxc_ip_forwarding_on(veth1, AF_INET6);
if (err) {
log_error_errno(-1, err, "Failed to activate ipv6 forwarding on \"%s\"", veth1);
SYSERROR("Failed to activate ipv6 forwarding on \"%s\"", veth1);
goto out_delete;
}
err = lxc_neigh_proxy_on(veth1, AF_INET6);
if (err) {
log_error_errno(-1, err, "Failed to activate proxy ndp on \"%s\"", veth1);
SYSERROR("Failed to activate proxy ndp on \"%s\"", veth1);
goto out_delete;
}
err = lxc_ip_neigh_proxy(RTM_NEWNEIGH, AF_INET6, netdev->priv.veth_attr.ifindex, netdev->ipv6_gateway);
if (err) {
log_error_errno(-1, err, "Failed to add gateway ipv6 proxy on \"%s\"", veth1);
SYSERROR("Failed to add gateway ipv6 proxy on \"%s\"", veth1);
goto out_delete;
}
}
......@@ -441,14 +420,14 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
/* setup ipv4 address routes on the host interface */
err = setup_ipv4_addr_routes(&netdev->ipv4, netdev->priv.veth_attr.ifindex);
if (err) {
log_error_errno(-1, err, "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;
}
/* setup ipv6 address routes on the host interface */
err = setup_ipv6_addr_routes(&netdev->ipv6, netdev->priv.veth_attr.ifindex);
if (err) {
log_error_errno(-1, err, "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;
}
}
......@@ -482,7 +461,7 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
char peer[IFNAMSIZ];
int err;
if (netdev->link[0] == '\0') {
if (is_empty_string(netdev->link)) {
ERROR("No link for macvlan network device specified");
return -1;
}
......@@ -557,69 +536,66 @@ on_error:
static int lxc_ipvlan_create(const char *master, const char *name, int mode, int isolation)
{
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err, index, len;
struct ifinfomsg *ifi;
struct nl_handler nlh;
struct rtattr *nest, *nest2;
struct nlmsg *answer = NULL, *nlmsg = NULL;
len = strlen(master);
if (len == 1 || len >= IFNAMSIZ)
return ret_set_errno(-1, EINVAL);
return ret_errno(EINVAL);
len = strlen(name);
if (len == 1 || len >= IFNAMSIZ)
return ret_set_errno(-1, EINVAL);
return ret_errno(EINVAL);
index = if_nametoindex(master);
if (!index)
return ret_set_errno(-1, EINVAL);
return ret_errno(EINVAL);
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return ret_set_errno(-1, -err);
return ret_errno(-err);
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
return ret_errno(ENOMEM);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi) {
goto out;
}
if (!ifi)
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
err = -EPROTO;
nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest)
goto out;
return ret_errno(EPROTO);
if (nla_put_string(nlmsg, IFLA_INFO_KIND, "ipvlan"))
goto out;
return ret_errno(EPROTO);
if (mode) {
nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
if (!nest2)
goto out;
return ret_errno(EPROTO);
if (nla_put_u32(nlmsg, IFLA_IPVLAN_MODE, mode))
goto out;
return ret_errno(EPROTO);
/* if_link.h does not define the isolation flag value for bridge mode so we define it as 0
* and only send mode if mode >0 as default mode is bridge anyway according to ipvlan docs.
*/
if (isolation > 0) {
if (nla_put_u16(nlmsg, IFLA_IPVLAN_ISOLATION, isolation))
goto out;
}
if (isolation > 0 &&
nla_put_u16(nlmsg, IFLA_IPVLAN_ISOLATION, isolation))
return ret_errno(EPROTO);
nla_end_nested(nlmsg, nest2);
}
......@@ -627,19 +603,12 @@ static int lxc_ipvlan_create(const char *master, const char *name, int mode, int
nla_end_nested(nlmsg, nest);
if (nla_put_u32(nlmsg, IFLA_LINK, index))
goto out;
return ret_errno(EPROTO);
if (nla_put_string(nlmsg, IFLA_IFNAME, name))
goto out;
return ret_errno(EPROTO);
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
if (err < 0)
return ret_set_errno(-1, -err);
return 0;
return netlink_transaction(nlh_ptr, nlmsg, answer);
}
static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
......@@ -647,7 +616,7 @@ static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *ne
char peer[IFNAMSIZ];
int err;
if (netdev->link[0] == '\0') {
if (is_empty_string(netdev->link)) {
ERROR("No link for ipvlan network device specified");
return -1;
}
......@@ -724,7 +693,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
int err;
static uint16_t vlan_cntr = 0;
if (netdev->link[0] == '\0') {
if (is_empty_string(netdev->link)) {
ERROR("No link for vlan network device specified");
return -1;
}
......@@ -798,10 +767,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
{
int err, mtu_orig = 0;
if (netdev->link[0] == '\0') {
ERROR("No link for physical interface specified");
return -1;
}
if (is_empty_string(netdev->link))
return log_error_errno(-1, errno, "No link for physical interface specified");
/*
* Note that we're retrieving the container's ifindex in the host's
......@@ -812,10 +779,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
* device in the host's namespace.
*/
netdev->ifindex = if_nametoindex(netdev->link);
if (!netdev->ifindex) {
ERROR("Failed to retrieve ifindex for \"%s\"", netdev->link);
return -1;
}
if (!netdev->ifindex)
return log_error_errno(-1, errno, "Failed to retrieve ifindex for \"%s\"", netdev->link);
strlcpy(netdev->created_name, netdev->link, IFNAMSIZ);
if (is_empty_string(netdev->name))
......@@ -832,10 +797,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
* container shutdown.
*/
mtu_orig = netdev_get_mtu(netdev->ifindex);
if (mtu_orig < 0) {
SYSERROR("Failed to get original mtu for interface \"%s\"", netdev->link);
return ret_set_errno(-1, -mtu_orig);
}
if (mtu_orig < 0)
return log_error_errno(-1, -mtu_orig, "Failed to get original mtu for interface \"%s\"", netdev->link);
netdev->priv.phys_attr.mtu = mtu_orig;
......@@ -843,19 +806,12 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
unsigned int mtu;
err = lxc_safe_uint(netdev->mtu, &mtu);
if (err < 0) {
errno = -err;
SYSERROR("Failed to parse mtu \"%s\" for interface \"%s\"",
netdev->mtu, netdev->link);
return -1;
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to parse mtu \"%s\" for interface \"%s\"", netdev->mtu, netdev->link);
err = lxc_netdev_set_mtu(netdev->link, mtu);
if (err < 0) {
errno = -err;
SYSERROR("Failed to set mtu \"%s\" for interface \"%s\"", netdev->mtu, netdev->link);
return -1;
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to set mtu \"%s\" for interface \"%s\"", netdev->mtu, netdev->link);
}
if (netdev->upscript) {
......@@ -867,9 +823,8 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
err = run_script_argv(handler->name, handler->conf->hooks_version,
"net", netdev->upscript, "up", argv);
if (err < 0) {
if (err < 0)
return -1;
}
}
DEBUG("Instantiated phys \"%s\" with ifindex is \"%d\"", netdev->link,
......@@ -932,8 +887,7 @@ static int instantiate_ns_veth(struct lxc_netdev *netdev)
ret = lxc_netdev_rename_by_name(netdev->created_name, netdev->name);
if (ret)
return log_error_errno(-1,
-ret, "Failed to rename network device \"%s\" to \"%s\"",
return log_error_errno(-1, -ret, "Failed to rename network device \"%s\" to \"%s\"",
netdev->created_name,
netdev->name);
......@@ -945,9 +899,7 @@ static int instantiate_ns_veth(struct lxc_netdev *netdev)
* would be automatically allocated by the system
*/
if (!if_indextoname(netdev->ifindex, current_ifname))
return log_error_errno(-1,
errno, "Failed get name for network device with ifindex %d",
netdev->ifindex);
return log_error_errno(-1, errno, "Failed get name for network device with ifindex %d", netdev->ifindex);
/*
* Now update the recorded name of the network device to reflect the
......@@ -963,9 +915,7 @@ static int __instantiate_common(struct lxc_netdev *netdev)
{
netdev->ifindex = if_nametoindex(netdev->name);
if (!netdev->ifindex)
return log_error_errno(-1,
errno, "Failed to retrieve ifindex for network device with name %s",
netdev->name);
return log_error_errno(-1, errno, "Failed to retrieve ifindex for network device with name %s", netdev->name);
return 0;
}
......@@ -1023,7 +973,7 @@ static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
if (!netdev->downscript)
return 0;
if (netdev->priv.veth_attr.pair[0] != '\0')
if (!is_empty_string(netdev->priv.veth_attr.pair))
argv[2] = netdev->priv.veth_attr.pair;
else
argv[2] = netdev->priv.veth_attr.veth1;
......@@ -1153,78 +1103,72 @@ static instantiate_cb netdev_deconf[LXC_NET_MAXCONFTYPE + 1] = {
static int lxc_netdev_move_by_index_fd(int ifindex, int fd, const char *ifname)
{
int err;
call_cleaner(nlmsg_free) struct nlmsg *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err;
struct ifinfomsg *ifi;
struct nlmsg *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi)
goto out;
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
ifi->ifi_index = ifindex;
if (nla_put_u32(nlmsg, IFLA_NET_NS_FD, fd))
goto out;
return ret_errno(ENOMEM);
if (!is_empty_string(ifname) && nla_put_string(nlmsg, IFLA_IFNAME, ifname))
goto out;
return ret_errno(ENOMEM);
err = netlink_transaction(&nlh, nlmsg, nlmsg);
out:
netlink_close(&nlh);
nlmsg_free(nlmsg);
return err;
return netlink_transaction(nlh_ptr, nlmsg, nlmsg);
}
int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char *ifname)
{
int err;
call_cleaner(nlmsg_free) struct nlmsg *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err;
struct ifinfomsg *ifi;
struct nlmsg *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi)
goto out;
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
ifi->ifi_index = ifindex;
if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
goto out;
return ret_errno(ENOMEM);
if (!is_empty_string(ifname) && nla_put_string(nlmsg, IFLA_IFNAME, ifname))
goto out;
return ret_errno(ENOMEM);
err = netlink_transaction(&nlh, nlmsg, nlmsg);
out:
netlink_close(&nlh);
nlmsg_free(nlmsg);
return err;
return netlink_transaction(nlh_ptr, nlmsg, nlmsg);
}
/* If we are asked to move a wireless interface, then we must actually move its
......@@ -1306,9 +1250,8 @@ int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
* the 80211 module, so for now just call out to iw.
*/
cmd = on_path("iw", NULL);
if (!cmd) {
if (!cmd)
return -1;
}
fpid = fork();
if (fpid < 0)
......@@ -1317,8 +1260,7 @@ int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
if (fpid == 0) {
char pidstr[30];
sprintf(pidstr, "%d", pid);
execlp("iw", "iw", "phy", physname, "set", "netns", pidstr,
(char *)NULL);
execlp("iw", "iw", "phy", physname, "set", "netns", pidstr, (char *)NULL);
_exit(EXIT_FAILURE);
}
......@@ -1352,39 +1294,35 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
int lxc_netdev_delete_by_index(int ifindex)
{
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err;
struct ifinfomsg *ifi;
struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
return ret_errno(ENOMEM);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi)
goto out;
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
ifi->ifi_index = ifindex;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
return netlink_transaction(nlh_ptr, nlmsg, answer);
}
int lxc_netdev_delete_by_name(const char *name)
......@@ -1400,48 +1338,42 @@ int lxc_netdev_delete_by_name(const char *name)
int lxc_netdev_rename_by_index(int ifindex, const char *newname)
{
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err, len;
struct ifinfomsg *ifi;
struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
len = strlen(newname);
if (len == 1 || len >= IFNAMSIZ) {
err = -EINVAL;
goto out;
}
if (len == 1 || len >= IFNAMSIZ)
return ret_errno(EINVAL);
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
return ret_errno(ENOMEM);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi)
goto out;
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
ifi->ifi_index = ifindex;
if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
goto out;
return ret_errno(ENOMEM);
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(answer);
nlmsg_free(nlmsg);
return err;
return netlink_transaction(nlh_ptr, nlmsg, answer);
}
int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
......@@ -1461,110 +1393,95 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
int netdev_set_flag(const char *name, int flag)
{
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err, index, len;
struct ifinfomsg *ifi;
struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -EINVAL;
len = strlen(name);
if (len == 1 || len >= IFNAMSIZ)
goto out;
return ret_errno(EINVAL);
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
return ret_errno(ENOMEM);
err = -EINVAL;
index = if_nametoindex(name);
if (!index)
goto out;
return ret_errno(EINVAL);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi) {
err = -ENOMEM;
goto out;
}
if (!ifi)
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
ifi->ifi_index = index;
ifi->ifi_change |= IFF_UP;
ifi->ifi_flags |= flag;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
netlink_close(&nlh);
nlmsg_free(nlmsg);
nlmsg_free(answer);
return err;
return netlink_transaction(nlh_ptr, nlmsg, answer);
}
int netdev_get_flag(const char *name, int *flag)
{
call_cleaner(nlmsg_free) struct nlmsg *answer = NULL, *nlmsg = NULL;
struct nl_handler nlh;
call_cleaner(netlink_close) struct nl_handler *nlh_ptr = &nlh;
int err, index, len;
struct ifinfomsg *ifi;
struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
if (!name)
return -EINVAL;
return ret_errno(EINVAL);
err = netlink_open(&nlh, NETLINK_ROUTE);
err = netlink_open(nlh_ptr, NETLINK_ROUTE);
if (err)
return err;
err = -EINVAL;
len = strlen(name);
if (len == 1 || len >= IFNAMSIZ)
goto out;
return ret_errno(EINVAL);
err = -ENOMEM;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto out;
return ret_errno(ENOMEM);
answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
if (!answer)
goto out;
return ret_errno(ENOMEM);
err = -EINVAL;
index = if_nametoindex(name);
if (!index)
goto out;
return ret_errno(EINVAL);
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST;
nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
if (!ifi) {
err = -ENOMEM;
goto out;
}
if (!ifi)
return ret_errno(ENOMEM);
ifi->ifi_family = AF_UNSPEC;
ifi->ifi_index = index;
err = netlink_transaction(&nlh, nlmsg, answer);
err = netlink_transaction(nlh_ptr, nlmsg, answer);
if (err)
goto out;
return ret_set_errno(-1, errno);
ifi = NLMSG_DATA(answer->nlmsghdr);
*flag = ifi->ifi_flags;
out:
netlink_close(&nlh);
nlmsg_free(nlmsg);
nlmsg_free(answer);
return err;
}
......@@ -1654,7 +1571,6 @@ int netdev_get_mtu(int ifindex)
msg = answer->nlmsghdr;
while (NLMSG_OK(msg, recv_len)) {
/* Stop reading if we see an error message */
if (msg->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *errmsg =
......@@ -1676,7 +1592,8 @@ int netdev_get_mtu(int ifindex)
msg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
res = 0;
while (RTA_OK(rta, attr_len)) {
/* Found a local address for the
/*
Found a local address for the
* requested interface, return it.
*/
if (rta->rta_type == IFLA_MTU) {
......@@ -2039,9 +1956,9 @@ static int ip_forwarding_set(const char *ifname, int family, int flag)
if (family != AF_INET && family != AF_INET6)
return -EINVAL;
ret = snprintf(path, PATH_MAX, "/proc/sys/net/%s/conf/%s/%s",
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname, "forwarding");
if (ret < 0 || (size_t)ret >= PATH_MAX)
if (ret < 0 || (size_t)ret >= sizeof(path))
return -E2BIG;
return proc_sys_net_write(path, flag ? "1" : "0");
......@@ -2065,10 +1982,10 @@ static int neigh_proxy_set(const char *ifname, int family, int flag)
if (family != AF_INET && family != AF_INET6)
return -EINVAL;
ret = snprintf(path, PATH_MAX, "/proc/sys/net/%s/conf/%s/%s",
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || (size_t)ret >= PATH_MAX)
if (ret < 0 || (size_t)ret >= sizeof(path))
return -E2BIG;
return proc_sys_net_write(path, flag ? "1" : "0");
......@@ -2083,10 +2000,10 @@ static int lxc_is_ip_neigh_proxy_enabled(const char *ifname, int family)
if (family != AF_INET && family != AF_INET6)
return ret_set_errno(-1, EINVAL);
ret = snprintf(path, PATH_MAX, "/proc/sys/net/%s/conf/%s/%s",
ret = snprintf(path, sizeof(path), "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || (size_t)ret >= PATH_MAX)
if (ret < 0 || (size_t)ret >= sizeof(path))
return ret_set_errno(-1, E2BIG);
return lxc_read_file_expect(path, buf, 1, "1");
......@@ -2502,8 +2419,7 @@ static int lxc_ovs_delete_port_exec(void *data)
{
struct ovs_veth_args *args = data;
execlp("ovs-vsctl", "ovs-vsctl", "del-port", args->bridge, args->nic,
(char *)NULL);
execlp("ovs-vsctl", "ovs-vsctl", "del-port", args->bridge, args->nic, (char *)NULL);
return -1;
}
......@@ -2517,11 +2433,8 @@ int lxc_ovs_delete_port(const char *bridge, const char *nic)
args.nic = nic;
ret = run_command(cmd_output, sizeof(cmd_output),
lxc_ovs_delete_port_exec, (void *)&args);
if (ret < 0) {
ERROR("Failed to delete \"%s\" from openvswitch bridge \"%s\": "
"%s", nic, bridge, cmd_output);
return -1;
}
if (ret < 0)
return log_error(-1, "Failed to delete \"%s\" from openvswitch bridge \"%s\": %s", nic, bridge, cmd_output);
return 0;
}
......@@ -2530,8 +2443,7 @@ static int lxc_ovs_attach_bridge_exec(void *data)
{
struct ovs_veth_args *args = data;
execlp("ovs-vsctl", "ovs-vsctl", "add-port", args->bridge, args->nic,
(char *)NULL);
execlp("ovs-vsctl", "ovs-vsctl", "add-port", args->bridge, args->nic, (char *)NULL);
return -1;
}
......@@ -2545,11 +2457,8 @@ static int lxc_ovs_attach_bridge(const char *bridge, const char *nic)
args.nic = nic;
ret = run_command(cmd_output, sizeof(cmd_output),
lxc_ovs_attach_bridge_exec, (void *)&args);
if (ret < 0) {
ERROR("Failed to attach \"%s\" to openvswitch bridge \"%s\": %s",
nic, bridge, cmd_output);
return -1;
}
if (ret < 0)
return log_error(-1, "Failed to attach \"%s\" to openvswitch bridge \"%s\": %s", nic, bridge, cmd_output);
return 0;
}
......@@ -2631,10 +2540,8 @@ char *lxc_mkifname(char *template)
/* Get all the network interfaces. */
ret = netns_getifaddrs(&ifaddr, -1, &(bool){false});
if (ret < 0) {
SYSERROR("Failed to get network interfaces");
return NULL;
}
if (ret < 0)
return log_error_errno(NULL, errno, "Failed to get network interfaces");
/* Generate random names until we find one that doesn't exist. */
for (;;) {
......@@ -2713,14 +2620,11 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
if (!netdev->ipv4_gateway_auto && !netdev->ipv6_gateway_auto)
continue;
if (netdev->type != LXC_NET_VETH && netdev->type != LXC_NET_MACVLAN) {
ERROR("Automatic gateway detection is only supported for veth and macvlan");
return -1;
}
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 (netdev->link[0] == '\0') {
ERROR("Automatic gateway detection needs a link interface");
return -1;
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);
......@@ -2728,19 +2632,13 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
return -EINVAL;
if (netdev->ipv4_gateway_auto) {
if (lxc_ipv4_addr_get(link_index, &netdev->ipv4_gateway)) {
ERROR("Failed to automatically find ipv4 gateway address from link interface \"%s\"",
netdev->link);
return -1;
}
if (lxc_ipv4_addr_get(link_index, &netdev->ipv4_gateway))
return log_error_errno(-1, errno, "Failed to automatically find ipv4 gateway address from link interface \"%s\"", netdev->link);
}
if (netdev->ipv6_gateway_auto) {
if (lxc_ipv6_addr_get(link_index, &netdev->ipv6_gateway)) {
ERROR("Failed to automatically find ipv6 gateway address from link interface \"%s\"",
netdev->link);
return -1;
}
if (lxc_ipv6_addr_get(link_index, &netdev->ipv6_gateway))
return log_error_errno(-1, errno, "Failed to automatically find ipv6 gateway address from link interface \"%s\"", netdev->link);
}
}
......@@ -2759,23 +2657,18 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
char buffer[PATH_MAX] = {0};
size_t retlen;
if (netdev->type != LXC_NET_VETH) {
ERROR("Network type %d not support for unprivileged use", netdev->type);
return -1;
}
if (netdev->type != LXC_NET_VETH)
return log_error_errno(-1, errno, "Network type %d not support for unprivileged use", netdev->type);
ret = pipe(pipefd);
if (ret < 0) {
SYSERROR("Failed to create pipe");
return -1;
}
if (ret < 0)
return log_error_errno(-1, errno, "Failed to create pipe");
child = fork();
if (child < 0) {
SYSERROR("Failed to create new process");
close(pipefd[0]);
close(pipefd[1]);
return -1;
return log_error_errno(-1, errno, "Failed to create new process");
}
if (child == 0) {
......@@ -2792,7 +2685,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
_exit(EXIT_FAILURE);
}
if (netdev->link[0] != '\0')
if (!is_empty_string(netdev->link))
retlen = strlcpy(netdev_link, netdev->link, IFNAMSIZ);
else
retlen = strlcpy(netdev_link, "none", IFNAMSIZ);
......@@ -2824,7 +2717,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
/* close the write-end of the pipe */
close(pipefd[1]);
bytes = lxc_read_nointr(pipefd[0], &buffer, PATH_MAX);
bytes = lxc_read_nointr(pipefd[0], &buffer, sizeof(buffer));
if (bytes < 0) {
SYSERROR("Failed to read from pipe file descriptor");
close(pipefd[0]);
......@@ -2834,19 +2727,14 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
ret = wait_for_pid(child);
close(pipefd[0]);
if (ret != 0 || bytes < 0) {
ERROR("lxc-user-nic failed to configure requested network: %s",
buffer[0] != '\0' ? buffer : "(null)");
return -1;
}
if (ret != 0 || bytes < 0)
return log_error(-1, "lxc-user-nic failed to configure requested network: %s", buffer[0] != '\0' ? buffer : "(null)");
TRACE("Received output \"%s\" from lxc-user-nic", buffer);
/* netdev->name */
token = strtok_r(buffer, ":", &saveptr);
if (!token) {
ERROR("Failed to parse lxc-user-nic output");
return -1;
}
if (!token)
return log_error(-1, "Failed to parse lxc-user-nic output");
/*
* lxc-user-nic will take care of proper network device naming. So
......@@ -2856,52 +2744,35 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
retlen = strlcpy(netdev->name, token, IFNAMSIZ);
if (retlen < IFNAMSIZ)
retlen = strlcpy(netdev->created_name, token, IFNAMSIZ);
if (retlen >= IFNAMSIZ) {
ERROR("Container side veth device name returned by lxc-user-nic is too long");
return -E2BIG;
}
if (retlen >= IFNAMSIZ)
return log_error_errno(-1, E2BIG, "Container side veth device name returned by lxc-user-nic is too long");
/* netdev->ifindex */
token = strtok_r(NULL, ":", &saveptr);
if (!token) {
ERROR("Failed to parse lxc-user-nic output");
return -1;
}
if (!token)
return log_error(-1, "Failed to parse lxc-user-nic output");
ret = lxc_safe_int(token, &netdev->ifindex);
if (ret < 0) {
errno = -ret;
SYSERROR("Failed to convert string \"%s\" to integer", token);
return -1;
}
if (ret < 0)
return log_error_errno(-1, -ret, "Failed to convert string \"%s\" to integer", token);
/* netdev->priv.veth_attr.veth1 */
token = strtok_r(NULL, ":", &saveptr);
if (!token) {
ERROR("Failed to parse lxc-user-nic output");
return -1;
}
if (!token)
return log_error(-1, "Failed to parse lxc-user-nic output");
retlen = strlcpy(netdev->priv.veth_attr.veth1, token, IFNAMSIZ);
if (retlen >= IFNAMSIZ) {
ERROR("Host side veth device name returned by lxc-user-nic is "
"too long");
return -E2BIG;
}
if (retlen >= IFNAMSIZ)
return log_error_errno(-1, E2BIG, "Host side veth device name returned by lxc-user-nic is too long");
/* netdev->priv.veth_attr.ifindex */
token = strtok_r(NULL, ":", &saveptr);
if (!token) {
ERROR("Failed to parse lxc-user-nic output");
return -1;
}
if (!token)
return log_error(-1, "Failed to parse lxc-user-nic output");
ret = lxc_safe_int(token, &netdev->priv.veth_attr.ifindex);
if (ret < 0) {
errno = -ret;
SYSERROR("Failed to convert string \"%s\" to integer", token);
return -1;
}
if (ret < 0)
return log_error_errno(-1, -ret, "Failed to convert string \"%s\" to integer", token);
if (netdev->upscript) {
char *argv[] = {
......@@ -2929,23 +2800,18 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
int pipefd[2];
char buffer[PATH_MAX] = {0};
if (netdev->type != LXC_NET_VETH) {
ERROR("Network type %d not support for unprivileged use", netdev->type);
return -1;
}
if (netdev->type != LXC_NET_VETH)
return log_error_errno(-1, EINVAL, "Network type %d not support for unprivileged use", netdev->type);
ret = pipe(pipefd);
if (ret < 0) {
SYSERROR("Failed to create pipe");
return -1;
}
if (ret < 0)
return log_error_errno(-1, errno, "Failed to create pipe");
child = fork();
if (child < 0) {
SYSERROR("Failed to create new process");
close(pipefd[0]);
close(pipefd[1]);
return -1;
return log_error_errno(-1, errno, "Failed to create new process");
}
if (child == 0) {
......@@ -2962,18 +2828,17 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
_exit(EXIT_FAILURE);
}
if (netdev->priv.veth_attr.pair[0] != '\0')
if (!is_empty_string(netdev->priv.veth_attr.pair))
hostveth = netdev->priv.veth_attr.pair;
else
hostveth = netdev->priv.veth_attr.veth1;
if (hostveth[0] == '\0') {
if (is_empty_string(hostveth)) {
SYSERROR("Host side veth device name is missing");
_exit(EXIT_FAILURE);
}
if (netdev->link[0] == '\0') {
SYSERROR("Network link for network device \"%s\" is "
"missing", netdev->priv.veth_attr.veth1);
if (is_empty_string(netdev->link)) {
SYSERROR("Network link for network device \"%s\" is missing", netdev->priv.veth_attr.veth1);
_exit(EXIT_FAILURE);
}
......@@ -2988,7 +2853,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
close(pipefd[1]);
bytes = lxc_read_nointr(pipefd[0], &buffer, PATH_MAX);
bytes = lxc_read_nointr(pipefd[0], &buffer, sizeof(buffer));
if (bytes < 0) {
SYSERROR("Failed to read from pipe file descriptor.");
close(pipefd[0]);
......@@ -2997,12 +2862,10 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
}
ret = wait_for_pid(child);
close(pipefd[0]);
if (ret != 0 || bytes < 0) {
ERROR("lxc-user-nic failed to delete requested network: %s",
buffer[0] != '\0' ? buffer : "(null)");
return -1;
}
close_prot_errno_disarm(pipefd[0]);
if (ret != 0 || bytes < 0)
return log_error_errno(-1, errno, "lxc-user-nic failed to delete requested network: %s",
!is_empty_string(buffer) ? buffer : "(null)");
return 0;
}
......@@ -3026,11 +2889,8 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
*netns_path = '\0';
if (handler->nsfd[LXC_NS_NET] < 0) {
DEBUG("Cannot not guarantee safe deletion of network devices. "
"Manual cleanup maybe needed");
return false;
}
if (handler->nsfd[LXC_NS_NET] < 0)
return log_debug(false, "Cannot not guarantee safe deletion of network devices. Manual cleanup maybe needed");
ret = snprintf(netns_path, sizeof(netns_path), "/proc/%d/fd/%d",
lxc_raw_getpid(), handler->nsfd[LXC_NS_NET]);
......@@ -3051,12 +2911,10 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
ret = lxc_netdev_rename_by_index(netdev->ifindex,
netdev->link);
if (ret < 0)
WARN("Failed to rename interface with index %d "
"to its initial name \"%s\"",
WARN("Failed to rename interface with index %d to its initial name \"%s\"",
netdev->ifindex, netdev->link);
else
TRACE("Renamed interface with index %d to its "
"initial name \"%s\"",
TRACE("Renamed interface with index %d to its initial name \"%s\"",
netdev->ifindex, netdev->link);
ret = netdev_deconf[netdev->type](handler, netdev);
......@@ -3070,26 +2928,24 @@ bool lxc_delete_network_unpriv(struct lxc_handler *handler)
if (netdev->type != LXC_NET_VETH)
goto clear_ifindices;
if (netdev->link[0] == '\0' || !is_ovs_bridge(netdev->link))
if (is_empty_string(netdev->link) || !is_ovs_bridge(netdev->link))
goto clear_ifindices;
if (netdev->priv.veth_attr.pair[0] != '\0')
if (!is_empty_string(netdev->priv.veth_attr.pair))
hostveth = netdev->priv.veth_attr.pair;
else
hostveth = netdev->priv.veth_attr.veth1;
if (hostveth[0] == '\0')
if (is_empty_string(hostveth))
goto clear_ifindices;
ret = lxc_delete_network_unpriv_exec(handler->lxcpath,
handler->name, netdev,
netns_path);
if (ret < 0) {
WARN("Failed to remove port \"%s\" from openvswitch "
"bridge \"%s\"", hostveth, netdev->link);
WARN("Failed to remove port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
goto clear_ifindices;
}
INFO("Removed interface \"%s\" from \"%s\"", hostveth,
netdev->link);
INFO("Removed interface \"%s\" from \"%s\"", hostveth, netdev->link);
clear_ifindices:
/*
......@@ -3118,50 +2974,38 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
unsigned int lo_ifindex = 0, link_ifindex = 0;
link_ifindex = if_nametoindex(netdev->link);
if (link_ifindex == 0) {
ERROR("Failed to retrieve ifindex for \"%s\" l2proxy setup", netdev->link);
return ret_set_errno(-1, EINVAL);
}
if (link_ifindex == 0)
return log_error_errno(-1, errno, "Failed to retrieve ifindex for \"%s\" l2proxy setup", netdev->link);
/* If IPv4 addresses are specified, then check that sysctl is configured correctly. */
if (!lxc_list_empty(&netdev->ipv4)) {
/* Check for net.ipv4.conf.[link].forwarding=1 */
if (lxc_is_ip_forwarding_enabled(netdev->link, AF_INET) < 0) {
ERROR("Requires sysctl net.ipv4.conf.%s.forwarding=1", netdev->link);
return ret_set_errno(-1, EINVAL);
}
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);
}
/* If IPv6 addresses are specified, then check that sysctl is configured correctly. */
if (!lxc_list_empty(&netdev->ipv6)) {
/* Check for net.ipv6.conf.[link].proxy_ndp=1 */
if (lxc_is_ip_neigh_proxy_enabled(netdev->link, AF_INET6) < 0) {
ERROR("Requires sysctl net.ipv6.conf.%s.proxy_ndp=1", netdev->link);
return ret_set_errno(-1, EINVAL);
}
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);
/* Check for net.ipv6.conf.[link].forwarding=1 */
if (lxc_is_ip_forwarding_enabled(netdev->link, AF_INET6) < 0) {
ERROR("Requires sysctl net.ipv6.conf.%s.forwarding=1", netdev->link);
return ret_set_errno(-1, EINVAL);
}
if (lxc_is_ip_forwarding_enabled(netdev->link, AF_INET6) < 0)
return log_error_errno(-1, EINVAL, "Requires sysctl net.ipv6.conf.%s.forwarding=1", netdev->link);
}
/* Perform IPVLAN specific checks. */
if (netdev->type == LXC_NET_IPVLAN) {
/* Check mode is l3s as other modes do not work with l2proxy. */
if (netdev->priv.ipvlan_attr.mode != IPVLAN_MODE_L3S) {
ERROR("Requires ipvlan mode on dev \"%s\" be l3s when used with l2proxy", netdev->link);
return ret_set_errno(-1, EINVAL);
}
if (netdev->priv.ipvlan_attr.mode != IPVLAN_MODE_L3S)
return log_error_errno(-1, EINVAL, "Requires ipvlan mode on dev \"%s\" be l3s when used with l2proxy", netdev->link);
/* Retrieve local-loopback interface index for use with IPVLAN static routes. */
lo_ifindex = if_nametoindex(loop_device);
if (lo_ifindex == 0) {
ERROR("Failed to retrieve ifindex for \"%s\" routing cleanup", loop_device);
return ret_set_errno(-1, EINVAL);
}
if (lo_ifindex == 0)
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) {
......@@ -3175,10 +3019,8 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
if (netdev->type == LXC_NET_IPVLAN) {
err = lxc_ipv4_dest_add(lo_ifindex, &inet4dev->addr, 32);
if (err < 0) {
ERROR("Failed to add ipv4 dest \"%s\" for network device \"%s\"", bufinet4, loop_device);
return ret_set_errno(-1, -err);
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to add ipv4 dest \"%s\" for network device \"%s\"", bufinet4, loop_device);
}
}
......@@ -3193,70 +3035,66 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
if (netdev->type == LXC_NET_IPVLAN) {
err = lxc_ipv6_dest_add(lo_ifindex, &inet6dev->addr, 128);
if (err < 0) {
ERROR("Failed to add ipv6 dest \"%s\" for network device \"%s\"", bufinet6, loop_device);
return ret_set_errno(-1, -err);
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to add ipv6 dest \"%s\" for network device \"%s\"", bufinet6, loop_device);
}
}
return 0;
}
static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, char *link, unsigned int lo_ifindex) {
static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, char *link, unsigned int lo_ifindex)
{
char bufinet4[INET_ADDRSTRLEN];
unsigned int errCount = 0, link_ifindex = 0;
bool had_error = false;
unsigned int link_ifindex = 0;
if (!inet_ntop(AF_INET, ip, bufinet4, sizeof(bufinet4))) {
SYSERROR("Failed to convert IP for l2proxy ipv4 removal on dev \"%s\"", link);
return ret_set_errno(-1, EINVAL);
}
if (!inet_ntop(AF_INET, ip, bufinet4, sizeof(bufinet4)))
return log_error_errno(-1, EINVAL, "Failed to convert IP for l2proxy ipv4 removal on dev \"%s\"", link);
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
if (lo_ifindex > 0) {
if (lxc_ipv4_dest_del(lo_ifindex, ip, 32) < 0) {
errCount++;
had_error = true;
ERROR("Failed to delete ipv4 dest \"%s\" for network ifindex \"%u\"", bufinet4, lo_ifindex);
}
}
/* If link is supplied remove the IP neigh proxy entry for this IP on the device. */
if (link[0] != '\0') {
if (!is_empty_string(link)) {
link_ifindex = if_nametoindex(link);
if (link_ifindex == 0) {
ERROR("Failed to retrieve ifindex for \"%s\" l2proxy cleanup", link);
return ret_set_errno(-1, EINVAL);
}
if (link_ifindex == 0)
return log_error_errno(-1, EINVAL, "Failed to retrieve ifindex for \"%s\" l2proxy cleanup", link);
if (lxc_ip_neigh_proxy(RTM_DELNEIGH, AF_INET, link_ifindex, ip) < 0)
errCount++;
had_error = true;
}
if (errCount > 0)
if (had_error)
return ret_set_errno(-1, EINVAL);
return 0;
}
static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int lo_ifindex) {
static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int lo_ifindex)
{
char bufinet6[INET6_ADDRSTRLEN];
unsigned int errCount = 0, link_ifindex = 0;
bool had_error = false;
unsigned int link_ifindex = 0;
if (!inet_ntop(AF_INET6, ip, bufinet6, sizeof(bufinet6))) {
SYSERROR("Failed to convert IP for l2proxy ipv6 removal on dev \"%s\"", link);
return ret_set_errno(-1, EINVAL);
}
if (!inet_ntop(AF_INET6, ip, bufinet6, sizeof(bufinet6)))
return log_error_errno(-1, EINVAL, "Failed to convert IP for l2proxy ipv6 removal on dev \"%s\"", link);
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
if (lo_ifindex > 0) {
if (lxc_ipv6_dest_del(lo_ifindex, ip, 128) < 0) {
errCount++;
had_error = true;
ERROR("Failed to delete ipv6 dest \"%s\" for network ifindex \"%u\"", bufinet6, lo_ifindex);
}
}
/* If link is supplied remove the IP neigh proxy entry for this IP on the device. */
if (link[0] != '\0') {
if (!is_empty_string(link)) {
link_ifindex = if_nametoindex(link);
if (link_ifindex == 0) {
ERROR("Failed to retrieve ifindex for \"%s\" l2proxy cleanup", link);
......@@ -3264,10 +3102,10 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int
}
if (lxc_ip_neigh_proxy(RTM_DELNEIGH, AF_INET6, link_ifindex, ip) < 0)
errCount++;
had_error = true;
}
if (errCount > 0)
if (had_error)
return ret_set_errno(-1, EINVAL);
return 0;
......@@ -3316,23 +3154,17 @@ static int lxc_create_network_priv(struct lxc_handler *handler)
lxc_list_for_each(iterator, network) {
struct lxc_netdev *netdev = iterator->elem;
if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE) {
ERROR("Invalid network configuration type %d", netdev->type);
return -1;
}
if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE)
return log_error_errno(-1, EINVAL, "Invalid network configuration type %d", netdev->type);
/* Setup l2proxy entries if enabled and used with a link property */
if (netdev->l2proxy && netdev->link[0] != '\0') {
if (lxc_setup_l2proxy(netdev)) {
ERROR("Failed to setup l2proxy");
return -1;
}
if (netdev->l2proxy && !is_empty_string(netdev->link)) {
if (lxc_setup_l2proxy(netdev))
return log_error_errno(-1, errno, "Failed to setup l2proxy");
}
if (netdev_conf[netdev->type](handler, netdev)) {
ERROR("Failed to create network device");
return -1;
}
if (netdev_conf[netdev->type](handler, netdev))
return log_error_errno(-1, errno, "Failed to create network device");
}
return 0;
......@@ -3362,12 +3194,10 @@ int lxc_network_move_created_netdev_priv(struct lxc_handler *handler)
ret = lxc_netdev_move_wlan(physname, netdev->link, pid, netdev->name);
else
ret = lxc_netdev_move_by_index(netdev->ifindex, pid, netdev->name);
if (ret) {
errno = -ret;
SYSERROR("Failed to move network device \"%s\" with ifindex %d to network namespace %d",
netdev->created_name, netdev->ifindex, pid);
return -1;
}
if (ret)
return log_error_errno(-1, -ret, "Failed to move network device \"%s\" with ifindex %d to network namespace %d",
netdev->created_name,
netdev->ifindex, pid);
DEBUG("Moved network device \"%s\" with ifindex %d to network namespace of %d",
netdev->created_name, netdev->ifindex, pid);
......@@ -3402,11 +3232,9 @@ static int lxc_create_network_unpriv(struct lxc_handler *handler)
if (!network_requires_advanced_setup(netdev->type))
continue;
if (netdev->type != LXC_NET_VETH) {
ERROR("Networks of type %s are not supported by unprivileged containers",
lxc_net_type_to_str(netdev->type));
return -1;
}
if (netdev->type != LXC_NET_VETH)
return log_error_errno(-1, EINVAL, "Networks of type %s are not supported by unprivileged containers",
lxc_net_type_to_str(netdev->type));
if (netdev->mtu)
INFO("mtu ignored due to insufficient privilege");
......@@ -3442,7 +3270,7 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
netdev->ifindex = if_nametoindex(netdev->name);
/* Delete l2proxy entries if enabled and used with a link property */
if (netdev->l2proxy && netdev->link[0] != '\0') {
if (netdev->l2proxy && !is_empty_string(netdev->link)) {
if (lxc_delete_l2proxy(netdev))
WARN("Failed to delete all l2proxy config");
/* Don't return, let the network be cleaned up as normal. */
......@@ -3485,36 +3313,26 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
/* Explicitly delete host veth device to prevent lingering
* devices. We had issues in LXD around this.
*/
if (netdev->priv.veth_attr.pair[0] != '\0')
if (!is_empty_string(netdev->priv.veth_attr.pair))
hostveth = netdev->priv.veth_attr.pair;
else
hostveth = netdev->priv.veth_attr.veth1;
if (hostveth[0] == '\0')
if (is_empty_string(hostveth))
goto clear_ifindices;
ret = lxc_netdev_delete_by_name(hostveth);
if (ret < 0) {
WARN("Failed to remove interface \"%s\" from \"%s\"",
hostveth, netdev->link);
goto clear_ifindices;
}
INFO("Removed interface \"%s\" from \"%s\"", hostveth, netdev->link);
if (is_empty_string(netdev->link) || !is_ovs_bridge(netdev->link)) {
ret = lxc_netdev_delete_by_name(hostveth);
if (ret < 0)
WARN("Failed to remove interface \"%s\" from \"%s\"", hostveth, netdev->link);
if (netdev->link[0] == '\0' || !is_ovs_bridge(netdev->link)) {
netdev->priv.veth_attr.veth1[0] = '\0';
netdev->ifindex = 0;
netdev->priv.veth_attr.ifindex = 0;
goto clear_ifindices;
}
INFO("Removed interface \"%s\" from \"%s\"", hostveth, netdev->link);
} else if (!is_empty_string(netdev->link)) {
ret = lxc_ovs_delete_port(netdev->link, hostveth);
if (ret < 0)
WARN("Failed to remove port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
/* Delete the openvswitch port. */
ret = lxc_ovs_delete_port(netdev->link, hostveth);
if (ret < 0)
WARN("Failed to remove port \"%s\" from openvswitch "
"bridge \"%s\"", hostveth, netdev->link);
else
INFO("Removed port \"%s\" from openvswitch bridge \"%s\"",
hostveth, netdev->link);
INFO("Removed port \"%s\" from openvswitch bridge \"%s\"", hostveth, netdev->link);
}
clear_ifindices:
/* We need to clear any ifindices we recorded so liblxc won't
......@@ -3542,7 +3360,7 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
if (lxc_list_empty(network))
return 0;
lxc_list_for_each(iterator, network) {
lxc_list_for_each (iterator, network) {
struct lxc_netdev *netdev = iterator->elem;
if (netdev->type == LXC_NET_NONE)
......@@ -3550,20 +3368,22 @@ int lxc_requests_empty_network(struct lxc_handler *handler)
else
found_nic = true;
}
if (found_none && !found_nic)
return 1;
return 0;
}
/* try to move physical nics to the init netns */
int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
{
__do_close int oldfd = -EBADF;
int netnsfd = handler->nsfd[LXC_NS_NET];
struct lxc_conf *conf = handler->conf;
int ret;
int oldfd;
char ifname[IFNAMSIZ];
struct lxc_list *iterator;
int netnsfd = handler->nsfd[LXC_NS_NET];
struct lxc_conf *conf = handler->conf;
/* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
* the parent network namespace. We won't have this capability if we are
......@@ -3575,17 +3395,12 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
TRACE("Moving physical network devices back to parent network namespace");
oldfd = lxc_preserve_ns(handler->monitor_pid, "net");
if (oldfd < 0) {
SYSERROR("Failed to preserve network namespace");
return -1;
}
if (oldfd < 0)
return log_error_errno(-1, errno, "Failed to preserve network namespace");
ret = setns(netnsfd, CLONE_NEWNET);
if (ret < 0) {
SYSERROR("Failed to enter network namespace");
close(oldfd);
return -1;
}
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;
......@@ -3597,42 +3412,34 @@ int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
* namespace.
*/
if (!if_indextoname(netdev->ifindex, ifname)) {
WARN("No interface corresponding to ifindex %d",
netdev->ifindex);
WARN("No interface corresponding to ifindex %d", netdev->ifindex);
continue;
}
ret = lxc_netdev_move_by_index_fd(netdev->ifindex, oldfd, netdev->link);
if (ret < 0)
WARN("Error moving network device \"%s\" back to "
"network namespace", ifname);
WARN("Error moving network device \"%s\" back to network namespace", ifname);
else
TRACE("Moved network device \"%s\" back to network "
"namespace", ifname);
TRACE("Moved network device \"%s\" back to network namespace", ifname);
}
ret = setns(oldfd, CLONE_NEWNET);
close(oldfd);
if (ret < 0) {
SYSERROR("Failed to enter network namespace");
return -1;
}
if (ret < 0)
return log_error_errno(-1, errno, "Failed to enter network namespace");
return 0;
}
static int setup_hw_addr(char *hwaddr, const char *ifname)
{
__do_close int fd = -EBADF;
struct sockaddr sockaddr;
struct ifreq ifr;
int ret, fd;
int ret;
ret = lxc_convert_mac(hwaddr, &sockaddr);
if (ret) {
errno = -ret;
SYSERROR("Mac address \"%s\" conversion failed", hwaddr);
return -1;
}
if (ret)
return log_error_errno(-1, -ret, "Mac address \"%s\" conversion failed", hwaddr);
memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
......@@ -3646,10 +3453,7 @@ static int setup_hw_addr(char *hwaddr, const char *ifname)
if (ret)
SYSERROR("Failed to perform ioctl");
close(fd);
DEBUG("Mac address \"%s\" on \"%s\" has been setup", hwaddr,
ifr.ifr_name);
DEBUG("Mac address \"%s\" on \"%s\" has been setup", hwaddr, ifr.ifr_name);
return ret;
}
......@@ -3664,12 +3468,8 @@ static int setup_ipv4_addr(struct lxc_list *ip, int ifindex)
err = lxc_ipv4_addr_add(ifindex, &inetdev->addr,
&inetdev->bcast, inetdev->prefix);
if (err) {
errno = -err;
SYSERROR("Failed to setup ipv4 address for network device "
"with ifindex %d", ifindex);
return -1;
}
if (err)
return log_error_errno(-1, -err, "Failed to setup ipv4 address for network device with ifindex %d", ifindex);
}
return 0;
......@@ -3686,12 +3486,8 @@ static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
err = lxc_ipv6_addr_add(ifindex, &inet6dev->addr,
&inet6dev->mcast, &inet6dev->acast,
inet6dev->prefix);
if (err) {
errno = -err;
SYSERROR("Failed to setup ipv6 address for network device "
"with ifindex %d", ifindex);
return -1;
}
if (err)
return log_error_errno(-1, -err, "Failed to setup ipv6 address for network device with ifindex %d", ifindex);
}
return 0;
......@@ -3705,77 +3501,47 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
/* empty network namespace */
if (!netdev->ifindex && netdev->flags & IFF_UP) {
err = lxc_netdev_up("lo");
if (err) {
errno = -err;
SYSERROR( "Failed to set the loopback network device up");
return -1;
}
if (err)
return log_error_errno(-1, -err, "Failed to set the loopback network device up");
}
/* set a mac address */
if (netdev->hwaddr) {
if (setup_hw_addr(netdev->hwaddr, netdev->name)) {
ERROR("Failed to setup hw address for network device \"%s\"",
netdev->name);
return -1;
}
}
if (netdev->hwaddr && setup_hw_addr(netdev->hwaddr, 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 */
if (setup_ipv4_addr(&netdev->ipv4, netdev->ifindex)) {
ERROR("Failed to setup ip addresses for network device \"%s\"",
netdev->name);
return -1;
}
if (setup_ipv4_addr(&netdev->ipv4, netdev->ifindex))
return log_error_errno(-1, errno, "Failed to setup ip addresses for network device \"%s\"", netdev->name);
/* setup ipv6 addresses on the interface */
if (setup_ipv6_addr(&netdev->ipv6, netdev->ifindex)) {
ERROR("Failed to setup ipv6 addresses for network device \"%s\"",
netdev->name);
return -1;
}
if (setup_ipv6_addr(&netdev->ipv6, netdev->ifindex))
return log_error_errno(-1, errno, "Failed to setup ipv6 addresses for network device \"%s\"", netdev->name);
/* set the network device up */
if (netdev->flags & IFF_UP) {
err = lxc_netdev_up(netdev->name);
if (err) {
errno = -err;
SYSERROR("Failed to set network device \"%s\" up",
netdev->name);
return -1;
}
if (err)
return log_error_errno(-1, -err, "Failed to set network device \"%s\" up", netdev->name);
/* the network is up, make the loopback up too */
err = lxc_netdev_up("lo");
if (err) {
errno = -err;
SYSERROR("Failed to set the loopback network device up");
return -1;
}
if (err)
return log_error_errno(-1, -err, "Failed to set the loopback network device up");
}
/* setup ipv4 gateway on the interface */
if (netdev->ipv4_gateway || netdev->ipv4_gateway_dev) {
if (!(netdev->flags & IFF_UP)) {
ERROR("Cannot add ipv4 gateway for network device "
"\"%s\" when not bringing up the interface", netdev->name);
return -1;
}
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);
if (lxc_list_empty(&netdev->ipv4)) {
ERROR("Cannot add ipv4 gateway for network device "
"\"%s\" when not assigning an address", netdev->name);
return -1;
}
if (lxc_list_empty(&netdev->ipv4))
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 */
if (netdev->ipv4_gateway_dev) {
err = lxc_ipv4_gateway_add(netdev->ifindex, NULL);
if (err < 0) {
SYSERROR("Failed to setup ipv4 gateway to network device \"%s\"",
netdev->name);
return ret_set_errno(-1, -err);
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to setup ipv4 gateway to network device \"%s\"", netdev->name);
} else {
/* Check the gateway address is valid */
if (!inet_ntop(AF_INET, netdev->ipv4_gateway, bufinet4, sizeof(bufinet4)))
......@@ -3790,46 +3556,29 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
* gateway address first, and then try again.
*/
err = lxc_ipv4_dest_add(netdev->ifindex, netdev->ipv4_gateway, 32);
if (err < 0) {
errno = -err;
SYSERROR("Failed to add ipv4 dest \"%s\" for network device \"%s\"",
bufinet4, netdev->name);
return -1;
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to add ipv4 dest \"%s\" for network device \"%s\"", bufinet4, netdev->name);
err = lxc_ipv4_gateway_add(netdev->ifindex, netdev->ipv4_gateway);
if (err < 0) {
errno = -err;
SYSERROR("Failed to setup ipv4 gateway \"%s\" for network device \"%s\"",
bufinet4, netdev->name);
return -1;
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to setup ipv4 gateway \"%s\" for network device \"%s\"", bufinet4, netdev->name);
}
}
}
/* setup ipv6 gateway on the interface */
if (netdev->ipv6_gateway || netdev->ipv6_gateway_dev) {
if (!(netdev->flags & IFF_UP)) {
ERROR("Cannot add ipv6 gateway for network device \"%s\" when not bringing up the interface",
netdev->name);
return -1;
}
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);
if (lxc_list_empty(&netdev->ipv6) && !IN6_IS_ADDR_LINKLOCAL(netdev->ipv6_gateway)) {
ERROR("Cannot add ipv6 gateway for network device \"%s\" when not assigning an address",
netdev->name);
return -1;
}
if (lxc_list_empty(&netdev->ipv6) && !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);
/* Setup device route if ipv6_gateway_dev is enabled */
if (netdev->ipv6_gateway_dev) {
err = lxc_ipv6_gateway_add(netdev->ifindex, NULL);
if (err < 0) {
SYSERROR("Failed to setup ipv6 gateway to network device \"%s\"",
netdev->name);
return ret_set_errno(-1, -err);
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to setup ipv6 gateway to network device \"%s\"", netdev->name);
} else {
/* Check the gateway address is valid */
if (!inet_ntop(AF_INET6, netdev->ipv6_gateway, bufinet6, sizeof(bufinet6)))
......@@ -3844,20 +3593,12 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde
* gateway address first, and then try again.
*/
err = lxc_ipv6_dest_add(netdev->ifindex, netdev->ipv6_gateway, 128);
if (err < 0) {
errno = -err;
SYSERROR("Failed to add ipv6 dest \"%s\" for network device \"%s\"",
bufinet6, netdev->name);
return -1;
}
if (err < 0)
return log_error_errno(-1, errno, "Failed to add ipv6 dest \"%s\" for network device \"%s\"", bufinet6, netdev->name);
err = lxc_ipv6_gateway_add(netdev->ifindex, netdev->ipv6_gateway);
if (err < 0) {
errno = -err;
SYSERROR("Failed to setup ipv6 gateway \"%s\" for network device \"%s\"",
bufinet6, netdev->name);
return -1;
}
if (err < 0)
return log_error_errno(-1, -err, "Failed to setup ipv6 gateway \"%s\" for network device \"%s\"", bufinet6, netdev->name);
}
}
}
......@@ -3879,10 +3620,8 @@ int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
ret = netdev_ns_conf[netdev->type](netdev);
if (!ret)
ret = lxc_network_setup_in_child_namespaces_common(netdev);
if (ret) {
ERROR("Failed to setup netdev");
return -1;
}
if (ret)
return log_error_errno(-1, errno, "Failed to setup netdev");
}
if (!lxc_list_empty(network))
......
......@@ -319,11 +319,9 @@ errclose:
return err;
}
extern int netlink_close(struct nl_handler *handler)
extern void netlink_close(struct nl_handler *handler)
{
close(handler->fd);
handler->fd = -1;
return 0;
close_prot_errno_disarm(handler->fd);
}
int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data,
......
......@@ -5,6 +5,8 @@
#include <stdio.h>
#include "memory_utils.h"
/*
* Use this as a good size to allocate generic netlink messages
*/
......@@ -64,10 +66,9 @@ int netlink_open(struct nl_handler *handler, int protocol);
* the handler is no longer valid
*
* @handler: a handler to the netlink socket
*
* Returns 0 on success, < 0 otherwise
*/
int netlink_close(struct nl_handler *handler);
void netlink_close(struct nl_handler *handler);
define_cleanup_function(struct nl_handler *, netlink_close);
/*
* netlink_rcv : receive a netlink message from the kernel.
......@@ -231,6 +232,7 @@ void *nlmsg_reserve(struct nlmsg *nlmsg, size_t len);
* @nlmsg: the netlink message to be freed
*/
void nlmsg_free(struct nlmsg *nlmsg);
define_cleanup_function(struct nlmsg *, nlmsg_free);
/*
* nlmsg_data : returns a pointer to the data contained in the netlink message
......
......@@ -21,9 +21,9 @@ extern int rtnetlink_open(struct rtnl_handler *handler)
return netlink_open(&handler->nlh, NETLINK_ROUTE);
}
extern int rtnetlink_close(struct rtnl_handler *handler)
extern void rtnetlink_close(struct rtnl_handler *handler)
{
return netlink_close(&handler->nlh);
netlink_close(&handler->nlh);
}
#pragma GCC diagnostic push
......
......@@ -44,10 +44,8 @@ extern int rtnetlink_open(struct rtnl_handler *handler);
* genetlink_close : close a route netlink socket
*
* @handler: the handler of the socket to be closed
*
* Returns 0 on success, < 0 otherwise
*/
extern int rtnetlink_close(struct rtnl_handler *handler);
extern void rtnetlink_close(struct rtnl_handler *handler);
/*
* rtnetlink_rcv : receive a route netlink socket, it is up
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment