network: non-functional changes

parent cb0dc11b
...@@ -92,12 +92,12 @@ ...@@ -92,12 +92,12 @@
lxc_log_define(lxc_network, lxc); lxc_log_define(lxc_network, lxc);
int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname) int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char *ifname)
{ {
int err;
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
int err; struct nlmsg *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -108,7 +108,7 @@ int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname) ...@@ -108,7 +108,7 @@ int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname)
if (!nlmsg) if (!nlmsg)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -132,42 +132,47 @@ out: ...@@ -132,42 +132,47 @@ out:
return err; return err;
} }
/* /* If we are asked to move a wireless interface, then we must actually move its
* If we are asked to move a wireless interface, then * phyN device. Detect that condition and return the physname here. The physname
* we must actually move its phyN device. Detect * will be passed to lxc_netdev_move_wlan() which will free it when done.
* that condition and return the physname here. The
* physname will be passed to lxc_netdev_move_wlan()
* which will free it when done
*/ */
#define PHYSNAME "/sys/class/net/%s/phy80211/name" #define PHYSNAME "/sys/class/net/%s/phy80211/name"
static char * is_wlan(const char *ifname) static char *is_wlan(const char *ifname)
{ {
char *path, *physname = NULL; int i, ret;
size_t len = strlen(ifname) + strlen(PHYSNAME) - 1;
struct stat sb;
long physlen; long physlen;
size_t len;
char *path;
FILE *f; FILE *f;
int ret, i; struct stat sb;
char *physname = NULL;
path = alloca(len+1); len = strlen(ifname) + strlen(PHYSNAME) - 1;
path = alloca(len + 1);
ret = snprintf(path, len, PHYSNAME, ifname); ret = snprintf(path, len, PHYSNAME, ifname);
if (ret < 0 || ret >= len) if (ret < 0 || (size_t)ret >= len)
goto bad; goto bad;
ret = stat(path, &sb); ret = stat(path, &sb);
if (ret) if (ret)
goto bad; goto bad;
if (!(f = fopen(path, "r")))
f = fopen(path, "r");
if (!f)
goto bad; goto bad;
/* Feh - sb.st_size is always 4096. */ /* Feh - sb.st_size is always 4096. */
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
physlen = ftell(f); physlen = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
physname = malloc(physlen+1);
physname = malloc(physlen + 1);
if (!physname) { if (!physname) {
fclose(f); fclose(f);
goto bad; goto bad;
} }
memset(physname, 0, physlen+1);
memset(physname, 0, physlen + 1);
ret = fread(physname, 1, physlen, f); ret = fread(physname, 1, physlen, f);
fclose(f); fclose(f);
if (ret < 0) if (ret < 0)
...@@ -176,6 +181,7 @@ static char * is_wlan(const char *ifname) ...@@ -176,6 +181,7 @@ static char * is_wlan(const char *ifname)
for (i = 0; i < physlen; i++) { for (i = 0; i < physlen; i++) {
if (physname[i] == '\n') if (physname[i] == '\n')
physname[i] = '\0'; physname[i] = '\0';
if (physname[i] == '\0') if (physname[i] == '\0')
break; break;
} }
...@@ -187,30 +193,34 @@ bad: ...@@ -187,30 +193,34 @@ bad:
return NULL; return NULL;
} }
static int static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old,
lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old, const char *new) const char *new)
{ {
pid_t fpid = fork(); pid_t fpid;
fpid = fork();
if (fpid < 0) if (fpid < 0)
return -1; return -1;
if (fpid != 0) if (fpid != 0)
return wait_for_pid(fpid); return wait_for_pid(fpid);
if (!switch_to_ns(pid, "net")) if (!switch_to_ns(pid, "net"))
return -1; return -1;
exit(lxc_netdev_rename_by_name(old, new)); exit(lxc_netdev_rename_by_name(old, new));
} }
static int static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char* newname) const char *newname)
{ {
int err = -1;
pid_t fpid;
char *cmd; char *cmd;
pid_t fpid;
int err = -1;
/* Move phyN into the container. TODO - do this using netlink. /* Move phyN into the container. TODO - do this using netlink.
* However, IIUC this involves a bit more complicated work to * However, IIUC this involves a bit more complicated work to talk to
* talk to the 80211 module, so for now just call out to iw * the 80211 module, so for now just call out to iw.
*/ */
cmd = on_path("iw", NULL); cmd = on_path("iw", NULL);
if (!cmd) if (!cmd)
...@@ -220,13 +230,15 @@ lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char* ...@@ -220,13 +230,15 @@ lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char*
fpid = fork(); fpid = fork();
if (fpid < 0) if (fpid < 0)
goto out1; goto out1;
if (fpid == 0) { if (fpid == 0) {
char pidstr[30]; char pidstr[30];
sprintf(pidstr, "%d", pid); sprintf(pidstr, "%d", pid);
if (execlp("iw", "iw", "phy", physname, "set", "netns", pidstr, (char *)NULL)) execlp("iw", "iw", "phy", physname, "set", "netns", pidstr,
exit(1); (char *)NULL);
exit(0); /* notreached */ exit(EXIT_FAILURE);
} }
if (wait_for_pid(fpid)) if (wait_for_pid(fpid))
goto out1; goto out1;
...@@ -251,7 +263,8 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname) ...@@ -251,7 +263,8 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
if (!index) if (!index)
return -EINVAL; return -EINVAL;
if ((physname = is_wlan(ifname))) physname = is_wlan(ifname);
if (physname)
return lxc_netdev_move_wlan(physname, ifname, pid, newname); return lxc_netdev_move_wlan(physname, ifname, pid, newname);
return lxc_netdev_move_by_index(index, pid, newname); return lxc_netdev_move_by_index(index, pid, newname);
...@@ -259,10 +272,10 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname) ...@@ -259,10 +272,10 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
int lxc_netdev_delete_by_index(int ifindex) int lxc_netdev_delete_by_index(int ifindex)
{ {
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi;
int err; 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, NETLINK_ROUTE);
if (err) if (err)
...@@ -277,7 +290,7 @@ int lxc_netdev_delete_by_index(int ifindex) ...@@ -277,7 +290,7 @@ int lxc_netdev_delete_by_index(int ifindex)
if (!answer) if (!answer)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -307,10 +320,10 @@ int lxc_netdev_delete_by_name(const char *name) ...@@ -307,10 +320,10 @@ int lxc_netdev_delete_by_name(const char *name)
int lxc_netdev_rename_by_index(int ifindex, const char *newname) int lxc_netdev_rename_by_index(int ifindex, const char *newname)
{ {
struct nl_handler nlh; int err, len;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
int len, err; struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -329,7 +342,7 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname) ...@@ -329,7 +342,7 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname)
if (!answer) if (!answer)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -366,10 +379,10 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname) ...@@ -366,10 +379,10 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
int netdev_set_flag(const char *name, int flag) int netdev_set_flag(const char *name, int flag)
{ {
struct nl_handler nlh; int err, index, len;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
int index, len, err; struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -394,7 +407,7 @@ int netdev_set_flag(const char *name, int flag) ...@@ -394,7 +407,7 @@ int netdev_set_flag(const char *name, int flag)
if (!index) if (!index)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -415,12 +428,12 @@ out: ...@@ -415,12 +428,12 @@ out:
return err; return err;
} }
int netdev_get_flag(const char* name, int *flag) int netdev_get_flag(const char *name, int *flag)
{ {
struct nl_handler nlh; int err, index, len;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
int index, len, err; struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
if (!name) if (!name)
return -EINVAL; return -EINVAL;
...@@ -483,30 +496,28 @@ out: ...@@ -483,30 +496,28 @@ out:
* 1 means interface is up. * 1 means interface is up.
* Others means error happened, and ret-value is the error number. * Others means error happened, and ret-value is the error number.
*/ */
int lxc_netdev_isup(const char* name) int lxc_netdev_isup(const char *name)
{ {
int flag; int err, flag;
int err;
err = netdev_get_flag(name, &flag); err = netdev_get_flag(name, &flag);
if (err) if (err)
goto out; return err;
if (flag & IFF_UP) if (flag & IFF_UP)
return 1; return 1;
return 0; return 0;
out:
return err;
} }
int netdev_get_mtu(int ifindex) int netdev_get_mtu(int ifindex)
{ {
int answer_len, err, res;
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
struct nlmsghdr *msg; struct nlmsghdr *msg;
int err, res; int readmore = 0, recv_len = 0;
int recv_len = 0, answer_len; struct nlmsg *answer = NULL, *nlmsg = NULL;
int readmore = 0;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -523,10 +534,11 @@ int netdev_get_mtu(int ifindex) ...@@ -523,10 +534,11 @@ int netdev_get_mtu(int ifindex)
/* Save the answer buffer length, since it will be overwritten /* Save the answer buffer length, since it will be overwritten
* on the first receive (and we might need to receive more than * on the first receive (and we might need to receive more than
* once. */ * once.
*/
answer_len = answer->nlmsghdr->nlmsg_len; answer_len = answer->nlmsghdr->nlmsg_len;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -542,7 +554,8 @@ int netdev_get_mtu(int ifindex) ...@@ -542,7 +554,8 @@ int netdev_get_mtu(int ifindex)
do { do {
/* Restore the answer buffer length, it might have been /* Restore the answer buffer length, it might have been
* overwritten by a previous receive. */ * overwritten by a previous receive.
*/
answer->nlmsghdr->nlmsg_len = answer_len; answer->nlmsghdr->nlmsg_len = answer_len;
/* Get the (next) batch of reply messages */ /* Get the (next) batch of reply messages */
...@@ -560,7 +573,8 @@ int netdev_get_mtu(int ifindex) ...@@ -560,7 +573,8 @@ int netdev_get_mtu(int ifindex)
/* Stop reading if we see an error message */ /* Stop reading if we see an error message */
if (msg->nlmsg_type == NLMSG_ERROR) { if (msg->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *errmsg = (struct nlmsgerr*)NLMSG_DATA(msg); struct nlmsgerr *errmsg =
(struct nlmsgerr *)NLMSG_DATA(msg);
err = errmsg->error; err = errmsg->error;
goto out; goto out;
} }
...@@ -574,32 +588,34 @@ int netdev_get_mtu(int ifindex) ...@@ -574,32 +588,34 @@ int netdev_get_mtu(int ifindex)
ifi = NLMSG_DATA(msg); ifi = NLMSG_DATA(msg);
if (ifi->ifi_index == ifindex) { if (ifi->ifi_index == ifindex) {
struct rtattr *rta = IFLA_RTA(ifi); struct rtattr *rta = IFLA_RTA(ifi);
int attr_len = msg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); int attr_len =
msg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
res = 0; res = 0;
while(RTA_OK(rta, attr_len)) { while (RTA_OK(rta, attr_len)) {
/* Found a local address for the requested interface, /* Found a local address for the
* return it. */ * requested interface, return it.
*/
if (rta->rta_type == IFLA_MTU) { if (rta->rta_type == IFLA_MTU) {
memcpy(&res, RTA_DATA(rta), sizeof(int)); memcpy(&res, RTA_DATA(rta),
sizeof(int));
err = res; err = res;
goto out; goto out;
} }
rta = RTA_NEXT(rta, attr_len); rta = RTA_NEXT(rta, attr_len);
} }
} }
/* Keep reading more data from the socket if the /* Keep reading more data from the socket if the last
* last message had the NLF_F_MULTI flag set */ * message had the NLF_F_MULTI flag set.
*/
readmore = (msg->nlmsg_flags & NLM_F_MULTI); readmore = (msg->nlmsg_flags & NLM_F_MULTI);
/* Look at the next message received in this buffer */ /* Look at the next message received in this buffer. */
msg = NLMSG_NEXT(msg, recv_len); msg = NLMSG_NEXT(msg, recv_len);
} }
} while (readmore); } while (readmore);
/* If we end up here, we didn't find any result, so signal an /* If we end up here, we didn't find any result, so signal an error. */
* error */
err = -1; err = -1;
out: out:
...@@ -611,10 +627,10 @@ out: ...@@ -611,10 +627,10 @@ out:
int lxc_netdev_set_mtu(const char *name, int mtu) int lxc_netdev_set_mtu(const char *name, int mtu)
{ {
struct nl_handler nlh; int err, index, len;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
int index, len, err; struct nl_handler nlh;
struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -639,7 +655,7 @@ int lxc_netdev_set_mtu(const char *name, int mtu) ...@@ -639,7 +655,7 @@ int lxc_netdev_set_mtu(const char *name, int mtu)
if (!index) if (!index)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -673,11 +689,11 @@ int lxc_netdev_down(const char *name) ...@@ -673,11 +689,11 @@ int lxc_netdev_down(const char *name)
int lxc_veth_create(const char *name1, const char *name2) int lxc_veth_create(const char *name1, const char *name2)
{ {
struct nl_handler nlh; int err, len;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
struct nl_handler nlh;
struct rtattr *nest1, *nest2, *nest3; struct rtattr *nest1, *nest2, *nest3;
int len, err; struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -702,7 +718,7 @@ int lxc_veth_create(const char *name1, const char *name2) ...@@ -702,7 +718,7 @@ int lxc_veth_create(const char *name1, const char *name2)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -736,9 +752,7 @@ int lxc_veth_create(const char *name1, const char *name2) ...@@ -736,9 +752,7 @@ int lxc_veth_create(const char *name1, const char *name2)
goto out; goto out;
nla_end_nested(nlmsg, nest3); nla_end_nested(nlmsg, nest3);
nla_end_nested(nlmsg, nest2); nla_end_nested(nlmsg, nest2);
nla_end_nested(nlmsg, nest1); nla_end_nested(nlmsg, nest1);
if (nla_put_string(nlmsg, IFLA_IFNAME, name1)) if (nla_put_string(nlmsg, IFLA_IFNAME, name1))
...@@ -752,14 +766,14 @@ out: ...@@ -752,14 +766,14 @@ out:
return err; return err;
} }
/* XXX: merge with lxc_macvlan_create */ /* TODO: merge with lxc_macvlan_create */
int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid) int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
{ {
struct nl_handler nlh; int err, len, lindex;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
struct nl_handler nlh;
struct rtattr *nest, *nest2; struct rtattr *nest, *nest2;
int lindex, len, err; struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -789,7 +803,7 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid) ...@@ -789,7 +803,7 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
goto err1; goto err1;
nlmsg->nlmsghdr->nlmsg_flags = nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -814,7 +828,6 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid) ...@@ -814,7 +828,6 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
goto err1; goto err1;
nla_end_nested(nlmsg, nest2); nla_end_nested(nlmsg, nest2);
nla_end_nested(nlmsg, nest); nla_end_nested(nlmsg, nest);
if (nla_put_u32(nlmsg, IFLA_LINK, lindex)) if (nla_put_u32(nlmsg, IFLA_LINK, lindex))
...@@ -835,11 +848,11 @@ err3: ...@@ -835,11 +848,11 @@ err3:
int lxc_macvlan_create(const char *master, const char *name, int mode) int lxc_macvlan_create(const char *master, const char *name, int mode)
{ {
struct nl_handler nlh; int err, index, len;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ifinfomsg *ifi;
struct nl_handler nlh;
struct rtattr *nest, *nest2; struct rtattr *nest, *nest2;
int index, len, err; struct nlmsg *answer = NULL, *nlmsg = NULL;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -869,7 +882,7 @@ int lxc_macvlan_create(const char *master, const char *name, int mode) ...@@ -869,7 +882,7 @@ int lxc_macvlan_create(const char *master, const char *name, int mode)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
...@@ -915,7 +928,8 @@ out: ...@@ -915,7 +928,8 @@ out:
static int proc_sys_net_write(const char *path, const char *value) static int proc_sys_net_write(const char *path, const char *value)
{ {
int fd, err = 0; int fd;
int err = 0;
fd = open(path, O_WRONLY); fd = open(path, O_WRONLY);
if (fd < 0) if (fd < 0)
...@@ -930,18 +944,18 @@ static int proc_sys_net_write(const char *path, const char *value) ...@@ -930,18 +944,18 @@ static int proc_sys_net_write(const char *path, const char *value)
static int ip_forward_set(const char *ifname, int family, int flag) static int ip_forward_set(const char *ifname, int family, int flag)
{ {
char path[MAXPATHLEN];
int rc; int rc;
char path[MAXPATHLEN];
if (family != AF_INET && family != AF_INET6) if (family != AF_INET && family != AF_INET6)
return -EINVAL; return -EINVAL;
rc = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding", rc = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding",
family == AF_INET?"ipv4":"ipv6" , ifname); family == AF_INET ? "ipv4" : "ipv6", ifname);
if (rc >= MAXPATHLEN) if (rc < 0 || (size_t)rc >= MAXPATHLEN)
return -E2BIG; return -E2BIG;
return proc_sys_net_write(path, flag?"1":"0"); return proc_sys_net_write(path, flag ? "1" : "0");
} }
int lxc_ip_forward_on(const char *ifname, int family) int lxc_ip_forward_on(const char *ifname, int family)
...@@ -956,19 +970,19 @@ int lxc_ip_forward_off(const char *ifname, int family) ...@@ -956,19 +970,19 @@ int lxc_ip_forward_off(const char *ifname, int family)
static int neigh_proxy_set(const char *ifname, int family, int flag) static int neigh_proxy_set(const char *ifname, int family, int flag)
{ {
char path[MAXPATHLEN];
int ret; int ret;
char path[MAXPATHLEN];
if (family != AF_INET && family != AF_INET6) if (family != AF_INET && family != AF_INET6)
return -EINVAL; return -EINVAL;
ret = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/%s", ret = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/%s",
family == AF_INET?"ipv4":"ipv6" , ifname, family == AF_INET ? "ipv4" : "ipv6", ifname,
family == AF_INET?"proxy_arp":"proxy_ndp"); family == AF_INET ? "proxy_arp" : "proxy_ndp");
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || (size_t)ret >= MAXPATHLEN)
return -E2BIG; return -E2BIG;
return proc_sys_net_write(path, flag?"1":"0"); return proc_sys_net_write(path, flag ? "1" : "0");
} }
int lxc_neigh_proxy_on(const char *name, int family) int lxc_neigh_proxy_on(const char *name, int family)
...@@ -983,10 +997,10 @@ int lxc_neigh_proxy_off(const char *name, int family) ...@@ -983,10 +997,10 @@ int lxc_neigh_proxy_off(const char *name, int family)
int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr) int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
{ {
unsigned char *data;
char c;
int i = 0; int i = 0;
unsigned val; unsigned val;
char c;
unsigned char *data;
sockaddr->sa_family = ARPHRD_ETHER; sockaddr->sa_family = ARPHRD_ETHER;
data = (unsigned char *)sockaddr->sa_data; data = (unsigned char *)sockaddr->sa_data;
...@@ -1000,9 +1014,9 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr) ...@@ -1000,9 +1014,9 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
val = c - 'a' + 10; val = c - 'a' + 10;
else if (c >= 'A' && c <= 'F') else if (c >= 'A' && c <= 'F')
val = c - 'A' + 10; val = c - 'A' + 10;
else { else
return -EINVAL; return -EINVAL;
}
val <<= 4; val <<= 4;
c = *macaddr; c = *macaddr;
if (isdigit(c)) if (isdigit(c))
...@@ -1013,12 +1027,11 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr) ...@@ -1013,12 +1027,11 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
val |= c - 'A' + 10; val |= c - 'A' + 10;
else if (c == ':' || c == 0) else if (c == ':' || c == 0)
val >>= 4; val >>= 4;
else { else
return -EINVAL; return -EINVAL;
}
if (c != 0) if (c != 0)
macaddr++; macaddr++;
*data++ = (unsigned char) (val & 0377); *data++ = (unsigned char)(val & 0377);
i++; i++;
if (*macaddr == ':') if (*macaddr == ':')
...@@ -1028,17 +1041,16 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr) ...@@ -1028,17 +1041,16 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
return 0; return 0;
} }
static int ip_addr_add(int family, int ifindex, static int ip_addr_add(int family, int ifindex, void *addr, void *bcast,
void *addr, void *bcast, void *acast, int prefix) void *acast, int prefix)
{ {
struct nl_handler nlh; int addrlen, err;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifaddrmsg *ifa; struct ifaddrmsg *ifa;
int addrlen; struct nl_handler nlh;
int err; struct nlmsg *answer = NULL, *nlmsg = NULL;
addrlen = family == AF_INET ? sizeof(struct in_addr) : addrlen = family == AF_INET ? sizeof(struct in_addr)
sizeof(struct in6_addr); : sizeof(struct in6_addr);
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -1054,7 +1066,7 @@ static int ip_addr_add(int family, int ifindex, ...@@ -1054,7 +1066,7 @@ static int ip_addr_add(int family, int ifindex,
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWADDR; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWADDR;
ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg)); ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
...@@ -1075,7 +1087,7 @@ static int ip_addr_add(int family, int ifindex, ...@@ -1075,7 +1087,7 @@ static int ip_addr_add(int family, int ifindex,
if (nla_put_buffer(nlmsg, IFA_BROADCAST, bcast, addrlen)) if (nla_put_buffer(nlmsg, IFA_BROADCAST, bcast, addrlen))
goto out; goto out;
/* TODO : multicast, anycast with ipv6 */ /* TODO: multicast, anycast with ipv6 */
err = -EPROTONOSUPPORT; err = -EPROTONOSUPPORT;
if (family == AF_INET6 && if (family == AF_INET6 &&
(memcmp(bcast, &in6addr_any, sizeof(in6addr_any)) || (memcmp(bcast, &in6addr_any, sizeof(in6addr_any)) ||
...@@ -1091,48 +1103,52 @@ out: ...@@ -1091,48 +1103,52 @@ out:
} }
int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr, int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
struct in6_addr *mcast, struct in6_addr *mcast, struct in6_addr *acast,
struct in6_addr *acast, int prefix) int prefix)
{ {
return ip_addr_add(AF_INET6, ifindex, addr, mcast, acast, prefix); return ip_addr_add(AF_INET6, ifindex, addr, mcast, acast, prefix);
} }
int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr, int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr, struct in_addr *bcast,
struct in_addr *bcast, int prefix) int prefix)
{ {
return ip_addr_add(AF_INET, ifindex, addr, bcast, NULL, prefix); return ip_addr_add(AF_INET, ifindex, addr, bcast, NULL, prefix);
} }
/* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present) /* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present) address from
* address from the given RTM_NEWADDR message. Allocates memory for the * the given RTM_NEWADDR message. Allocates memory for the address and stores
* address and stores that pointer in *res (so res should be an * that pointer in *res (so res should be an in_addr** or in6_addr**).
* in_addr** or in6_addr**).
*/ */
static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) { static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void **res)
{
int addrlen;
struct ifaddrmsg *ifa = NLMSG_DATA(msg); struct ifaddrmsg *ifa = NLMSG_DATA(msg);
struct rtattr *rta = IFA_RTA(ifa); struct rtattr *rta = IFA_RTA(ifa);
int attr_len = NLMSG_PAYLOAD(msg, sizeof(struct ifaddrmsg)); int attr_len = NLMSG_PAYLOAD(msg, sizeof(struct ifaddrmsg));
int addrlen;
if (ifa->ifa_family != family) if (ifa->ifa_family != family)
return 0; return 0;
addrlen = family == AF_INET ? sizeof(struct in_addr) : addrlen = family == AF_INET ? sizeof(struct in_addr)
sizeof(struct in6_addr); : sizeof(struct in6_addr);
/* Loop over the rtattr's in this message */ /* Loop over the rtattr's in this message */
while(RTA_OK(rta, attr_len)) { while (RTA_OK(rta, attr_len)) {
/* Found a local address for the requested interface, /* Found a local address for the requested interface,
* return it. */ * return it.
if (rta->rta_type == IFA_LOCAL || rta->rta_type == IFA_ADDRESS) { */
/* Sanity check. The family check above should if (rta->rta_type == IFA_LOCAL ||
* make sure the address length is correct, but rta->rta_type == IFA_ADDRESS) {
* check here just in case */ /* Sanity check. The family check above should make sure
* the address length is correct, but check here just in
* case.
*/
if (RTA_PAYLOAD(rta) != addrlen) if (RTA_PAYLOAD(rta) != addrlen)
return -1; return -1;
/* We might have found an IFA_ADDRESS before, /* We might have found an IFA_ADDRESS before, which we
* which we now overwrite with an IFA_LOCAL. */ * now overwrite with an IFA_LOCAL.
*/
if (!*res) { if (!*res) {
*res = malloc(addrlen); *res = malloc(addrlen);
if (!*res) if (!*res)
...@@ -1140,7 +1156,6 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) { ...@@ -1140,7 +1156,6 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
} }
memcpy(*res, RTA_DATA(rta), addrlen); memcpy(*res, RTA_DATA(rta), addrlen);
if (rta->rta_type == IFA_LOCAL) if (rta->rta_type == IFA_LOCAL)
break; break;
} }
...@@ -1151,13 +1166,12 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) { ...@@ -1151,13 +1166,12 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
static int ip_addr_get(int family, int ifindex, void **res) static int ip_addr_get(int family, int ifindex, void **res)
{ {
struct nl_handler nlh; int answer_len, err;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifaddrmsg *ifa; struct ifaddrmsg *ifa;
struct nl_handler nlh;
struct nlmsghdr *msg; struct nlmsghdr *msg;
int err; int readmore = 0, recv_len = 0;
int recv_len = 0, answer_len; struct nlmsg *answer = NULL, *nlmsg = NULL;
int readmore = 0;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -1172,12 +1186,12 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1172,12 +1186,12 @@ static int ip_addr_get(int family, int ifindex, void **res)
if (!answer) if (!answer)
goto out; goto out;
/* Save the answer buffer length, since it will be overwritten /* Save the answer buffer length, since it will be overwritten on the
* on the first receive (and we might need to receive more than * first receive (and we might need to receive more than once).
* once. */ */
answer_len = answer->nlmsghdr->nlmsg_len; answer_len = answer->nlmsghdr->nlmsg_len;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ROOT; nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
nlmsg->nlmsghdr->nlmsg_type = RTM_GETADDR; nlmsg->nlmsghdr->nlmsg_type = RTM_GETADDR;
ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg)); ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
...@@ -1185,18 +1199,20 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1185,18 +1199,20 @@ static int ip_addr_get(int family, int ifindex, void **res)
goto out; goto out;
ifa->ifa_family = family; ifa->ifa_family = family;
/* Send the request for addresses, which returns all addresses /* Send the request for addresses, which returns all addresses on all
* on all interfaces. */ * interfaces.
*/
err = netlink_send(&nlh, nlmsg); err = netlink_send(&nlh, nlmsg);
if (err < 0) if (err < 0)
goto out; goto out;
do { do {
/* Restore the answer buffer length, it might have been /* Restore the answer buffer length, it might have been
* overwritten by a previous receive. */ * overwritten by a previous receive.
*/
answer->nlmsghdr->nlmsg_len = answer_len; answer->nlmsghdr->nlmsg_len = answer_len;
/* Get the (next) batch of reply messages */ /* Get the (next) batch of reply messages. */
err = netlink_rcv(&nlh, answer); err = netlink_rcv(&nlh, answer);
if (err < 0) if (err < 0)
goto out; goto out;
...@@ -1204,18 +1220,19 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1204,18 +1220,19 @@ static int ip_addr_get(int family, int ifindex, void **res)
recv_len = err; recv_len = err;
err = 0; err = 0;
/* Satisfy the typing for the netlink macros */ /* Satisfy the typing for the netlink macros. */
msg = answer->nlmsghdr; msg = answer->nlmsghdr;
while (NLMSG_OK(msg, recv_len)) { while (NLMSG_OK(msg, recv_len)) {
/* Stop reading if we see an error message */ /* Stop reading if we see an error message. */
if (msg->nlmsg_type == NLMSG_ERROR) { if (msg->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *errmsg = (struct nlmsgerr*)NLMSG_DATA(msg); struct nlmsgerr *errmsg =
(struct nlmsgerr *)NLMSG_DATA(msg);
err = errmsg->error; err = errmsg->error;
goto out; goto out;
} }
/* Stop reading if we see a NLMSG_DONE message */ /* Stop reading if we see a NLMSG_DONE message. */
if (msg->nlmsg_type == NLMSG_DONE) { if (msg->nlmsg_type == NLMSG_DONE) {
readmore = 0; readmore = 0;
break; break;
...@@ -1233,22 +1250,24 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1233,22 +1250,24 @@ static int ip_addr_get(int family, int ifindex, void **res)
goto out; goto out;
} }
/* Found a result, stop searching */ /* Found a result, stop searching. */
if (*res) if (*res)
goto out; goto out;
} }
/* Keep reading more data from the socket if the /* Keep reading more data from the socket if the last
* last message had the NLF_F_MULTI flag set */ * message had the NLF_F_MULTI flag set.
*/
readmore = (msg->nlmsg_flags & NLM_F_MULTI); readmore = (msg->nlmsg_flags & NLM_F_MULTI);
/* Look at the next message received in this buffer */ /* Look at the next message received in this buffer. */
msg = NLMSG_NEXT(msg, recv_len); msg = NLMSG_NEXT(msg, recv_len);
} }
} while (readmore); } while (readmore);
/* If we end up here, we didn't find any result, so signal an /* If we end up here, we didn't find any result, so signal an
* error */ * error.
*/
err = -1; err = -1;
out: out:
...@@ -1260,24 +1279,23 @@ out: ...@@ -1260,24 +1279,23 @@ out:
int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res) int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res)
{ {
return ip_addr_get(AF_INET6, ifindex, (void**)res); return ip_addr_get(AF_INET6, ifindex, (void **)res);
} }
int lxc_ipv4_addr_get(int ifindex, struct in_addr** res) int lxc_ipv4_addr_get(int ifindex, struct in_addr **res)
{ {
return ip_addr_get(AF_INET, ifindex, (void**)res); return ip_addr_get(AF_INET, ifindex, (void **)res);
} }
static int ip_gateway_add(int family, int ifindex, void *gw) static int ip_gateway_add(int family, int ifindex, void *gw)
{ {
int addrlen, err;
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct rtmsg *rt; struct rtmsg *rt;
int addrlen; struct nlmsg *answer = NULL, *nlmsg = NULL;
int err;
addrlen = family == AF_INET ? sizeof(struct in_addr) : addrlen = family == AF_INET ? sizeof(struct in_addr)
sizeof(struct in6_addr); : sizeof(struct in6_addr);
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -1293,7 +1311,7 @@ static int ip_gateway_add(int family, int ifindex, void *gw) ...@@ -1293,7 +1311,7 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE;
rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg)); rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
...@@ -1312,7 +1330,8 @@ static int ip_gateway_add(int family, int ifindex, void *gw) ...@@ -1312,7 +1330,8 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
goto out; goto out;
/* Adding the interface index enables the use of link-local /* Adding the interface index enables the use of link-local
* addresses for the gateway */ * addresses for the gateway.
*/
if (nla_put_u32(nlmsg, RTA_OIF, ifindex)) if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
goto out; goto out;
...@@ -1336,14 +1355,13 @@ int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw) ...@@ -1336,14 +1355,13 @@ int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
static int ip_route_dest_add(int family, int ifindex, void *dest) static int ip_route_dest_add(int family, int ifindex, void *dest)
{ {
int addrlen, err;
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct rtmsg *rt; struct rtmsg *rt;
int addrlen; struct nlmsg *answer = NULL, *nlmsg = NULL;
int err;
addrlen = family == AF_INET ? sizeof(struct in_addr) : addrlen = family == AF_INET ? sizeof(struct in_addr)
sizeof(struct in6_addr); : sizeof(struct in6_addr);
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
if (err) if (err)
...@@ -1359,7 +1377,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest) ...@@ -1359,7 +1377,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = nlmsg->nlmsghdr->nlmsg_flags =
NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE; nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE;
rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg)); rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
...@@ -1370,7 +1388,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest) ...@@ -1370,7 +1388,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
rt->rtm_scope = RT_SCOPE_LINK; rt->rtm_scope = RT_SCOPE_LINK;
rt->rtm_protocol = RTPROT_BOOT; rt->rtm_protocol = RTPROT_BOOT;
rt->rtm_type = RTN_UNICAST; rt->rtm_type = RTN_UNICAST;
rt->rtm_dst_len = addrlen*8; rt->rtm_dst_len = addrlen * 8;
err = -EINVAL; err = -EINVAL;
if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen)) if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))
...@@ -1397,12 +1415,19 @@ int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest) ...@@ -1397,12 +1415,19 @@ int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
static bool is_ovs_bridge(const char *bridge) static bool is_ovs_bridge(const char *bridge)
{ {
char brdirname[22 + IFNAMSIZ + 1] = {0}; int ret;
struct stat sb; struct stat sb;
char brdirname[22 + IFNAMSIZ + 1] = {0};
ret = snprintf(brdirname, 22 + IFNAMSIZ + 1, "/sys/class/net/%s/bridge",
bridge);
if (ret < 0 || (size_t)ret >= 22 + IFNAMSIZ + 1)
return false;
snprintf(brdirname, 22 +IFNAMSIZ + 1, "/sys/class/net/%s/bridge", bridge); ret = stat(brdirname, &sb);
if (stat(brdirname, &sb) == -1 && errno == ENOENT) if (ret < 0 && errno == ENOENT)
return true; return true;
return false; return false;
} }
...@@ -1432,7 +1457,8 @@ static void ovs_cleanup_nic(const char *lxcpath, const char *name, ...@@ -1432,7 +1457,8 @@ static void ovs_cleanup_nic(const char *lxcpath, const char *name,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static int attach_to_ovs_bridge(const char *lxcpath, const char *name, const char *bridge, const char *nic) static int attach_to_ovs_bridge(const char *lxcpath, const char *name,
const char *bridge, const char *nic)
{ {
pid_t pid; pid_t pid;
char *cmd; char *cmd;
...@@ -1446,31 +1472,34 @@ static int attach_to_ovs_bridge(const char *lxcpath, const char *name, const cha ...@@ -1446,31 +1472,34 @@ static int attach_to_ovs_bridge(const char *lxcpath, const char *name, const cha
pid = fork(); pid = fork();
if (pid < 0) if (pid < 0)
return -1; return -1;
if (pid > 0) { if (pid > 0) {
ret = wait_for_pid(pid); ret = wait_for_pid(pid);
if (ret < 0) if (ret < 0)
return ret; return ret;
pid = fork(); pid = fork();
if (pid < 0) if (pid < 0)
return -1; /* how to properly recover? */ return -1;
if (pid > 0) if (pid > 0)
return 0; return 0;
ovs_cleanup_nic(lxcpath, name, bridge, nic); ovs_cleanup_nic(lxcpath, name, bridge, nic);
exit(0); exit(EXIT_SUCCESS);
} }
if (execlp("ovs-vsctl", "ovs-vsctl", "add-port", bridge, nic, (char *)NULL)) execlp("ovs-vsctl", "ovs-vsctl", "add-port", bridge, nic, (char *)NULL);
exit(1); exit(EXIT_FAILURE);
/* not reached */
exit(1);
} }
/* There is a lxc_bridge_attach, but no need of a bridge detach as automatically /* There is a lxc_bridge_attach, but no need of a bridge detach as automatically
* done by kernel when a netdev is deleted. * done by kernel when a netdev is deleted.
*/ */
int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge, const char *ifname) int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
const char *ifname)
{ {
int fd, index, err; int err, fd, index;
struct ifreq ifr; struct ifreq ifr;
if (strlen(ifname) >= IFNAMSIZ) if (strlen(ifname) >= IFNAMSIZ)
...@@ -1487,8 +1516,8 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge, ...@@ -1487,8 +1516,8 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
if (fd < 0) if (fd < 0)
return -errno; return -errno;
strncpy(ifr.ifr_name, bridge, IFNAMSIZ-1); strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
ifr.ifr_name[IFNAMSIZ-1] = '\0'; ifr.ifr_name[IFNAMSIZ - 1] = '\0';
ifr.ifr_ifindex = index; ifr.ifr_ifindex = index;
err = ioctl(fd, SIOCBRADDIF, &ifr); err = ioctl(fd, SIOCBRADDIF, &ifr);
close(fd); close(fd);
...@@ -1498,7 +1527,7 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge, ...@@ -1498,7 +1527,7 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
return err; return err;
} }
static const char* const lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = { static const char *const lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = {
[LXC_NET_EMPTY] = "empty", [LXC_NET_EMPTY] = "empty",
[LXC_NET_VETH] = "veth", [LXC_NET_VETH] = "veth",
[LXC_NET_MACVLAN] = "macvlan", [LXC_NET_MACVLAN] = "macvlan",
...@@ -1511,40 +1540,40 @@ const char *lxc_net_type_to_str(int type) ...@@ -1511,40 +1540,40 @@ const char *lxc_net_type_to_str(int type)
{ {
if (type < 0 || type > LXC_NET_MAXCONFTYPE) if (type < 0 || type > LXC_NET_MAXCONFTYPE)
return NULL; return NULL;
return lxc_network_types[type]; return lxc_network_types[type];
} }
static const char padchar[] = static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *lxc_mkifname(char *template) char *lxc_mkifname(char *template)
{ {
char *name = NULL; int ifexists = 0;
size_t i = 0; size_t i = 0;
FILE *urandom; char *name = NULL;
unsigned int seed; unsigned int seed;
struct ifaddrs *ifaddr, *ifa; FILE *urandom;
int ifexists = 0; struct ifaddrs *ifa, *ifaddr;
/* Get all the network interfaces */ /* Get all the network interfaces. */
getifaddrs(&ifaddr); getifaddrs(&ifaddr);
/* Initialize the random number generator */ /* Initialize the random number generator. */
urandom = fopen ("/dev/urandom", "r"); urandom = fopen("/dev/urandom", "r");
if (urandom != NULL) { if (urandom != NULL) {
if (fread (&seed, sizeof(seed), 1, urandom) <= 0) if (fread(&seed, sizeof(seed), 1, urandom) <= 0)
seed = time(0); seed = time(0);
fclose(urandom); fclose(urandom);
} } else {
else
seed = time(0); seed = time(0);
}
#ifndef HAVE_RAND_R #ifndef HAVE_RAND_R
srand(seed); srand(seed);
#endif #endif
/* Generate random names until we find one that doesn't exist */ /* Generate random names until we find one that doesn't exist. */
while(1) { while (true) {
ifexists = 0; ifexists = 0;
name = strdup(template); name = strdup(template);
...@@ -1554,7 +1583,8 @@ char *lxc_mkifname(char *template) ...@@ -1554,7 +1583,8 @@ char *lxc_mkifname(char *template)
for (i = 0; i < strlen(name); i++) { for (i = 0; i < strlen(name); i++) {
if (name[i] == 'X') { if (name[i] == 'X') {
#ifdef HAVE_RAND_R #ifdef HAVE_RAND_R
name[i] = padchar[rand_r(&seed) % (strlen(padchar) - 1)]; name[i] = padchar[rand_r(&seed) %
(strlen(padchar) - 1)];
#else #else
name[i] = padchar[rand() % (strlen(padchar) - 1)]; name[i] = padchar[rand() % (strlen(padchar) - 1)];
#endif #endif
...@@ -1580,15 +1610,17 @@ char *lxc_mkifname(char *template) ...@@ -1580,15 +1610,17 @@ char *lxc_mkifname(char *template)
int setup_private_host_hw_addr(char *veth1) int setup_private_host_hw_addr(char *veth1)
{ {
int err, sockfd;
struct ifreq ifr; struct ifreq ifr;
int err;
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) if (sockfd < 0)
return -errno; return -errno;
snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1); err = snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1);
if (err < 0 || (size_t)err >= IFNAMSIZ)
return -E2BIG;
err = ioctl(sockfd, SIOCGIFHWADDR, &ifr); err = ioctl(sockfd, SIOCGIFHWADDR, &ifr);
if (err < 0) { if (err < 0) {
close(sockfd); close(sockfd);
......
...@@ -23,64 +23,50 @@ ...@@ -23,64 +23,50 @@
#ifndef __LXC_NETWORK_H #ifndef __LXC_NETWORK_H
#define __LXC_NETWORK_H #define __LXC_NETWORK_H
/* #include <stdio.h>
* Convert a string mac address to a socket structure #include <unistd.h>
*/ #include <arpa/inet.h>
#include <sys/socket.h>
/* Convert a string mac address to a socket structure. */
extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr); extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr);
/* /* Move a device between namespaces. */
* Move a device between namespaces
*/
extern int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname); extern int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname);
extern int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname); extern int lxc_netdev_move_by_name(const char *ifname, pid_t pid,
const char *newname);
/* /* Delete a network device. */
* Delete a network device
*/
extern int lxc_netdev_delete_by_name(const char *name); extern int lxc_netdev_delete_by_name(const char *name);
extern int lxc_netdev_delete_by_index(int ifindex); extern int lxc_netdev_delete_by_index(int ifindex);
/* /* Change the device name. */
* Change the device name
*/
extern int lxc_netdev_rename_by_name(const char *oldname, const char *newname); extern int lxc_netdev_rename_by_name(const char *oldname, const char *newname);
extern int lxc_netdev_rename_by_index(int ifindex, const char *newname); extern int lxc_netdev_rename_by_index(int ifindex, const char *newname);
extern int netdev_set_flag(const char *name, int flag); extern int netdev_set_flag(const char *name, int flag);
/* /* Set the device network up or down. */
* Set the device network up or down
*/
extern int lxc_netdev_isup(const char *name); extern int lxc_netdev_isup(const char *name);
extern int lxc_netdev_up(const char *name); extern int lxc_netdev_up(const char *name);
extern int lxc_netdev_down(const char *name); extern int lxc_netdev_down(const char *name);
/* /* Change the mtu size for the specified device. */
* Change the mtu size for the specified device
*/
extern int lxc_netdev_set_mtu(const char *name, int mtu); extern int lxc_netdev_set_mtu(const char *name, int mtu);
/* /* Create a virtual network devices. */
* Create a virtual network devices
*/
extern int lxc_veth_create(const char *name1, const char *name2); extern int lxc_veth_create(const char *name1, const char *name2);
extern int lxc_macvlan_create(const char *master, const char *name, int mode); extern int lxc_macvlan_create(const char *master, const char *name, int mode);
extern int lxc_vlan_create(const char *master, const char *name, unsigned short vid); extern int lxc_vlan_create(const char *master, const char *name,
unsigned short vid);
/* /* Activate forwarding.*/
* Activate forwarding
*/
extern int lxc_ip_forward_on(const char *name, int family); extern int lxc_ip_forward_on(const char *name, int family);
/* /* Disable forwarding. */
* Disable forwarding
*/
extern int lxc_ip_forward_off(const char *name, int family); extern int lxc_ip_forward_off(const char *name, int family);
/* /* Set ip address. */
* Set ip address
*/
extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr, extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
struct in6_addr *mcast, struct in6_addr *mcast,
struct in6_addr *acast, int prefix); struct in6_addr *acast, int prefix);
...@@ -88,57 +74,41 @@ extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr, ...@@ -88,57 +74,41 @@ extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
extern int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr, extern int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr,
struct in_addr *bcast, int prefix); struct in_addr *bcast, int prefix);
/* /* Get ip address. */
* Get ip address
*/
extern int lxc_ipv4_addr_get(int ifindex, struct in_addr **res); extern int lxc_ipv4_addr_get(int ifindex, struct in_addr **res);
extern int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res); extern int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res);
/* /* Set a destination route to an interface. */
* Set a destination route to an interface
*/
extern int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest); extern int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest);
extern int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest); extern int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest);
/* /* Set default route. */
* Set default route.
*/
extern int lxc_ipv4_gateway_add(int ifindex, struct in_addr *gw); extern int lxc_ipv4_gateway_add(int ifindex, struct in_addr *gw);
extern int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw); extern int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw);
/* /* Attach an interface to the bridge. */
* Attach an interface to the bridge extern int lxc_bridge_attach(const char *lxcpath, const char *name,
*/ const char *bridge, const char *ifname);
extern int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge, const char *ifname);
/* /* Create default gateway. */
* Create default gateway
*/
extern int lxc_route_create_default(const char *addr, const char *ifname, extern int lxc_route_create_default(const char *addr, const char *ifname,
int gateway); int gateway);
/* /* Delete default gateway. */
* Delete default gateway
*/
extern int lxc_route_delete_default(const char *addr, const char *ifname, extern int lxc_route_delete_default(const char *addr, const char *ifname,
int gateway); int gateway);
/* /* Activate neighbor proxying. */
* Activate neighbor proxying
*/
extern int lxc_neigh_proxy_on(const char *name, int family); extern int lxc_neigh_proxy_on(const char *name, int family);
/* /* Disable neighbor proxying. */
* Disable neighbor proxying
*/
extern int lxc_neigh_proxy_off(const char *name, int family); extern int lxc_neigh_proxy_off(const char *name, int family);
/* /* Generate a new unique network interface name. */
* Generate a new unique network interface name
*/
extern char *lxc_mkifname(char *template); extern char *lxc_mkifname(char *template);
extern const char *lxc_net_type_to_str(int type); extern const char *lxc_net_type_to_str(int type);
extern int setup_private_host_hw_addr(char *veth1); extern int setup_private_host_hw_addr(char *veth1);
extern int netdev_get_mtu(int ifindex); extern int netdev_get_mtu(int ifindex);
#endif
#endif /* __LXC_NETWORK_H */
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