Commit a4318300 by Stéphane Graber

Revert "audit: added capacity and reserve() to nlmsg"

This reverts commit 55ae7edb. This change caused hangs in the testsuite, specifically with lxc-user-nic. Signed-off-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 26f1b390
...@@ -88,12 +88,26 @@ ...@@ -88,12 +88,26 @@
# define IFLA_MACVLAN_MODE 1 # define IFLA_MACVLAN_MODE 1
#endif #endif
struct link_req {
struct nlmsg nlmsg;
struct ifinfomsg ifinfomsg;
};
struct ip_req {
struct nlmsg nlmsg;
struct ifaddrmsg ifa;
};
struct rt_req {
struct nlmsg nlmsg;
struct rtmsg rt;
};
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)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL; struct nlmsg *nlmsg = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
int err; int err;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
...@@ -105,12 +119,12 @@ int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname) ...@@ -105,12 +119,12 @@ 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; link_req = (struct link_req *)nlmsg;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = ifindex;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
ifi->ifi_family = AF_UNSPEC; nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
ifi->ifi_index = ifindex; nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid)) if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
goto out; goto out;
...@@ -255,7 +269,7 @@ int lxc_netdev_delete_by_index(int ifindex) ...@@ -255,7 +269,7 @@ int lxc_netdev_delete_by_index(int ifindex)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
int err; int err;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
...@@ -271,12 +285,12 @@ int lxc_netdev_delete_by_index(int ifindex) ...@@ -271,12 +285,12 @@ 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; link_req = (struct link_req *)nlmsg;
nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK; link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = ifindex;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
ifi->ifi_family = AF_UNSPEC; nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
ifi->ifi_index = ifindex; nlmsg->nlmsghdr.nlmsg_type = RTM_DELLINK;
err = netlink_transaction(&nlh, nlmsg, answer); err = netlink_transaction(&nlh, nlmsg, answer);
out: out:
...@@ -301,7 +315,7 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname) ...@@ -301,7 +315,7 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
int len, err; int len, err;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
...@@ -321,12 +335,12 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname) ...@@ -321,12 +335,12 @@ 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; link_req = (struct link_req *)nlmsg;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = ifindex;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
ifi->ifi_family = AF_UNSPEC; nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
ifi->ifi_index = ifindex; nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_string(nlmsg, IFLA_IFNAME, newname)) if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
goto out; goto out;
...@@ -358,7 +372,7 @@ int netdev_set_flag(const char *name, int flag) ...@@ -358,7 +372,7 @@ int netdev_set_flag(const char *name, int flag)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
int index, len, err; int index, len, err;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
...@@ -384,14 +398,14 @@ int netdev_set_flag(const char *name, int flag) ...@@ -384,14 +398,14 @@ 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; link_req = (struct link_req *)nlmsg;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = index;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); link_req->ifinfomsg.ifi_change |= IFF_UP;
ifi->ifi_family = AF_UNSPEC; link_req->ifinfomsg.ifi_flags |= flag;
ifi->ifi_index = index; nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
ifi->ifi_change |= IFF_UP; nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
ifi->ifi_flags |= flag; nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
err = netlink_transaction(&nlh, nlmsg, answer); err = netlink_transaction(&nlh, nlmsg, answer);
out: out:
...@@ -405,8 +419,9 @@ int netdev_get_flag(const char* name, int *flag) ...@@ -405,8 +419,9 @@ int netdev_get_flag(const char* name, int *flag)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
int index, len, err; int index, len, err;
struct ifinfomsg *ifi;
if (!name) if (!name)
return -EINVAL; return -EINVAL;
...@@ -434,14 +449,12 @@ int netdev_get_flag(const char* name, int *flag) ...@@ -434,14 +449,12 @@ int netdev_get_flag(const char* name, int *flag)
if (!index) if (!index)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST; link_req = (struct link_req *)nlmsg;
nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK; link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = index;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
ifi->ifi_family = AF_UNSPEC; nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST;
ifi->ifi_index = index; nlmsg->nlmsghdr.nlmsg_type = RTM_GETLINK;
nlmsg_reserve(answer, sizeof(struct ifinfomsg));
err = netlink_transaction(&nlh, nlmsg, answer); err = netlink_transaction(&nlh, nlmsg, answer);
if (err) if (err)
...@@ -486,7 +499,7 @@ int netdev_get_mtu(int ifindex) ...@@ -486,7 +499,7 @@ int netdev_get_mtu(int ifindex)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct ip_req *ip_req;
struct nlmsghdr *msg; struct nlmsghdr *msg;
int err, res; int err, res;
int recv_len = 0, answer_len; int recv_len = 0, answer_len;
...@@ -508,14 +521,14 @@ int netdev_get_mtu(int ifindex) ...@@ -508,14 +521,14 @@ 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. */
nlmsg_reserve(answer, NLMSG_GOOD_SIZE); 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_type = RTM_GETLINK;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); ip_req = (struct ip_req *)nlmsg;
ifi->ifi_family = AF_UNSPEC; ip_req->nlmsg.nlmsghdr.nlmsg_len =
NLMSG_LENGTH(sizeof(struct ifaddrmsg));
ip_req->nlmsg.nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_GETLINK;
ip_req->ifa.ifa_family = AF_UNSPEC;
/* Send the request for addresses, which returns all addresses /* Send the request for addresses, which returns all addresses
* on all interfaces. */ * on all interfaces. */
...@@ -526,7 +539,7 @@ int netdev_get_mtu(int ifindex) ...@@ -526,7 +539,7 @@ 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 */
err = netlink_rcv(&nlh, answer); err = netlink_rcv(&nlh, answer);
...@@ -537,7 +550,7 @@ int netdev_get_mtu(int ifindex) ...@@ -537,7 +550,7 @@ int netdev_get_mtu(int ifindex)
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)) {
...@@ -554,7 +567,7 @@ int netdev_get_mtu(int ifindex) ...@@ -554,7 +567,7 @@ int netdev_get_mtu(int ifindex)
break; break;
} }
ifi = NLMSG_DATA(msg); struct ifinfomsg *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));
...@@ -596,7 +609,7 @@ int lxc_netdev_set_mtu(const char *name, int mtu) ...@@ -596,7 +609,7 @@ int lxc_netdev_set_mtu(const char *name, int mtu)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
int index, len, err; int index, len, err;
err = netlink_open(&nlh, NETLINK_ROUTE); err = netlink_open(&nlh, NETLINK_ROUTE);
...@@ -622,12 +635,12 @@ int lxc_netdev_set_mtu(const char *name, int mtu) ...@@ -622,12 +635,12 @@ 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; link_req = (struct link_req *)nlmsg;
nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK; link_req->ifinfomsg.ifi_family = AF_UNSPEC;
link_req->ifinfomsg.ifi_index = index;
ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg)); nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
ifi->ifi_family = AF_UNSPEC; nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
ifi->ifi_index = index; nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_u32(nlmsg, IFLA_MTU, mtu)) if (nla_put_u32(nlmsg, IFLA_MTU, mtu))
goto out; goto out;
...@@ -654,7 +667,7 @@ int lxc_veth_create(const char *name1, const char *name2) ...@@ -654,7 +667,7 @@ int lxc_veth_create(const char *name1, const char *name2)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
struct rtattr *nest1, *nest2, *nest3; struct rtattr *nest1, *nest2, *nest3;
int len, err; int len, err;
...@@ -680,12 +693,12 @@ int lxc_veth_create(const char *name1, const char *name2) ...@@ -680,12 +693,12 @@ int lxc_veth_create(const char *name1, const char *name2)
if (!answer) if (!answer)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
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->ifi_family = AF_UNSPEC;
err = -EINVAL; err = -EINVAL;
nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO); nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO);
...@@ -703,7 +716,7 @@ int lxc_veth_create(const char *name1, const char *name2) ...@@ -703,7 +716,7 @@ int lxc_veth_create(const char *name1, const char *name2)
if (!nest3) if (!nest3)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_len += sizeof(struct ifinfomsg); nlmsg->nlmsghdr.nlmsg_len += sizeof(struct ifinfomsg);
if (nla_put_string(nlmsg, IFLA_IFNAME, name2)) if (nla_put_string(nlmsg, IFLA_IFNAME, name2))
goto out; goto out;
...@@ -730,7 +743,7 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid) ...@@ -730,7 +743,7 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
struct rtattr *nest, *nest2; struct rtattr *nest, *nest2;
int lindex, len, err; int lindex, len, err;
...@@ -761,12 +774,12 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid) ...@@ -761,12 +774,12 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
if (!lindex) if (!lindex)
goto err1; goto err1;
nlmsg->nlmsghdr->nlmsg_flags = link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
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->ifi_family = AF_UNSPEC;
nest = nla_begin_nested(nlmsg, IFLA_LINKINFO); nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest) if (!nest)
...@@ -806,7 +819,7 @@ int lxc_macvlan_create(const char *master, const char *name, int mode) ...@@ -806,7 +819,7 @@ int lxc_macvlan_create(const char *master, const char *name, int mode)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifinfomsg *ifi; struct link_req *link_req;
struct rtattr *nest, *nest2; struct rtattr *nest, *nest2;
int index, len, err; int index, len, err;
...@@ -837,12 +850,12 @@ int lxc_macvlan_create(const char *master, const char *name, int mode) ...@@ -837,12 +850,12 @@ int lxc_macvlan_create(const char *master, const char *name, int mode)
if (!index) if (!index)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
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->ifi_family = AF_UNSPEC;
nest = nla_begin_nested(nlmsg, IFLA_LINKINFO); nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest) if (!nest)
...@@ -998,7 +1011,7 @@ static int ip_addr_add(int family, int ifindex, ...@@ -998,7 +1011,7 @@ static int ip_addr_add(int family, int ifindex,
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifaddrmsg *ifa; struct ip_req *ip_req;
int addrlen; int addrlen;
int err; int err;
...@@ -1018,15 +1031,16 @@ static int ip_addr_add(int family, int ifindex, ...@@ -1018,15 +1031,16 @@ static int ip_addr_add(int family, int ifindex,
if (!answer) if (!answer)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = ip_req = (struct ip_req *)nlmsg;
ip_req->nlmsg.nlmsghdr.nlmsg_len =
NLMSG_LENGTH(sizeof(struct ifaddrmsg));
ip_req->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; ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWADDR;
ip_req->ifa.ifa_prefixlen = prefix;
ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg)); ip_req->ifa.ifa_index = ifindex;
ifa->ifa_prefixlen = prefix; ip_req->ifa.ifa_family = family;
ifa->ifa_index = ifindex; ip_req->ifa.ifa_scope = 0;
ifa->ifa_family = family;
ifa->ifa_scope = 0;
err = -EINVAL; err = -EINVAL;
if (nla_put_buffer(nlmsg, IFA_LOCAL, addr, addrlen)) if (nla_put_buffer(nlmsg, IFA_LOCAL, addr, addrlen))
...@@ -1071,13 +1085,12 @@ int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr, ...@@ -1071,13 +1085,12 @@ int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr,
* address and stores that pointer in *res (so res should be an * address and stores 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 ip_req *ip_info, void** res) {
struct ifaddrmsg *ifa = NLMSG_DATA(msg); struct rtattr *rta = IFA_RTA(&ip_info->ifa);
struct rtattr *rta = IFA_RTA(ifa); int attr_len = IFA_PAYLOAD(&ip_info->nlmsg.nlmsghdr);
int attr_len = NLMSG_PAYLOAD(msg, sizeof(struct ifaddrmsg));
int addrlen; int addrlen;
if (ifa->ifa_family != family) if (ip_info->ifa.ifa_family != family)
return 0; return 0;
addrlen = family == AF_INET ? sizeof(struct in_addr) : addrlen = family == AF_INET ? sizeof(struct in_addr) :
...@@ -1116,7 +1129,7 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1116,7 +1129,7 @@ static int ip_addr_get(int family, int ifindex, void **res)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct ifaddrmsg *ifa; struct ip_req *ip_req, *ip_info;
struct nlmsghdr *msg; struct nlmsghdr *msg;
int err; int err;
int recv_len = 0, answer_len; int recv_len = 0, answer_len;
...@@ -1138,14 +1151,14 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1138,14 +1151,14 @@ static int ip_addr_get(int family, int ifindex, void **res)
/* 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. */
nlmsg_reserve(answer, NLMSG_GOOD_SIZE); 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_type = RTM_GETADDR;
ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg)); ip_req = (struct ip_req *)nlmsg;
ifa->ifa_family = family; ip_req->nlmsg.nlmsghdr.nlmsg_len =
NLMSG_LENGTH(sizeof(struct ifaddrmsg));
ip_req->nlmsg.nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ROOT;
ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_GETADDR;
ip_req->ifa.ifa_family = family;
/* Send the request for addresses, which returns all addresses /* Send the request for addresses, which returns all addresses
* on all interfaces. */ * on all interfaces. */
...@@ -1156,7 +1169,7 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1156,7 +1169,7 @@ static int ip_addr_get(int family, int ifindex, void **res)
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);
...@@ -1167,7 +1180,7 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1167,7 +1180,7 @@ static int ip_addr_get(int family, int ifindex, void **res)
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 */
...@@ -1188,9 +1201,9 @@ static int ip_addr_get(int family, int ifindex, void **res) ...@@ -1188,9 +1201,9 @@ static int ip_addr_get(int family, int ifindex, void **res)
goto out; goto out;
} }
ifa = (struct ifaddrmsg *)NLMSG_DATA(msg); ip_info = (struct ip_req *)msg;
if (ifa->ifa_index == ifindex) { if (ip_info->ifa.ifa_index == ifindex) {
if (ifa_get_local_ip(family, msg, res) < 0) { if (ifa_get_local_ip(family, ip_info, res) < 0) {
err = -1; err = -1;
goto out; goto out;
} }
...@@ -1234,7 +1247,7 @@ static int ip_gateway_add(int family, int ifindex, void *gw) ...@@ -1234,7 +1247,7 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct rtmsg *rt; struct rt_req *rt_req;
int addrlen; int addrlen;
int err; int err;
...@@ -1254,18 +1267,19 @@ static int ip_gateway_add(int family, int ifindex, void *gw) ...@@ -1254,18 +1267,19 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
if (!answer) if (!answer)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = rt_req = (struct rt_req *)nlmsg;
rt_req->nlmsg.nlmsghdr.nlmsg_len =
NLMSG_LENGTH(sizeof(struct rtmsg));
rt_req->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; rt_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWROUTE;
rt_req->rt.rtm_family = family;
rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg)); rt_req->rt.rtm_table = RT_TABLE_MAIN;
rt->rtm_family = family; rt_req->rt.rtm_scope = RT_SCOPE_UNIVERSE;
rt->rtm_table = RT_TABLE_MAIN; rt_req->rt.rtm_protocol = RTPROT_BOOT;
rt->rtm_scope = RT_SCOPE_UNIVERSE; rt_req->rt.rtm_type = RTN_UNICAST;
rt->rtm_protocol = RTPROT_BOOT;
rt->rtm_type = RTN_UNICAST;
/* "default" destination */ /* "default" destination */
rt->rtm_dst_len = 0; rt_req->rt.rtm_dst_len = 0;
err = -EINVAL; err = -EINVAL;
if (nla_put_buffer(nlmsg, RTA_GATEWAY, gw, addrlen)) if (nla_put_buffer(nlmsg, RTA_GATEWAY, gw, addrlen))
...@@ -1298,7 +1312,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest) ...@@ -1298,7 +1312,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
{ {
struct nl_handler nlh; struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL; struct nlmsg *nlmsg = NULL, *answer = NULL;
struct rtmsg *rt; struct rt_req *rt_req;
int addrlen; int addrlen;
int err; int err;
...@@ -1318,17 +1332,18 @@ static int ip_route_dest_add(int family, int ifindex, void *dest) ...@@ -1318,17 +1332,18 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
if (!answer) if (!answer)
goto out; goto out;
nlmsg->nlmsghdr->nlmsg_flags = rt_req = (struct rt_req *)nlmsg;
rt_req->nlmsg.nlmsghdr.nlmsg_len =
NLMSG_LENGTH(sizeof(struct rtmsg));
rt_req->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; rt_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWROUTE;
rt_req->rt.rtm_family = family;
rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg)); rt_req->rt.rtm_table = RT_TABLE_MAIN;
rt->rtm_family = family; rt_req->rt.rtm_scope = RT_SCOPE_LINK;
rt->rtm_table = RT_TABLE_MAIN; rt_req->rt.rtm_protocol = RTPROT_BOOT;
rt->rtm_scope = RT_SCOPE_LINK; rt_req->rt.rtm_type = RTN_UNICAST;
rt->rtm_protocol = RTPROT_BOOT; rt_req->rt.rtm_dst_len = addrlen*8;
rt->rtm_type = RTN_UNICAST;
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))
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
extern size_t nlmsg_len(const struct nlmsg *nlmsg) extern size_t nlmsg_len(const struct nlmsg *nlmsg)
{ {
return nlmsg->nlmsghdr->nlmsg_len - NLMSG_HDRLEN; return nlmsg->nlmsghdr.nlmsg_len - NLMSG_HDRLEN;
} }
extern void *nlmsg_data(struct nlmsg *nlmsg) extern void *nlmsg_data(struct nlmsg *nlmsg)
...@@ -53,16 +53,13 @@ static int nla_put(struct nlmsg *nlmsg, int attr, ...@@ -53,16 +53,13 @@ static int nla_put(struct nlmsg *nlmsg, int attr,
{ {
struct rtattr *rta; struct rtattr *rta;
size_t rtalen = RTA_LENGTH(len); size_t rtalen = RTA_LENGTH(len);
size_t tlen = NLMSG_ALIGN(nlmsg->nlmsghdr->nlmsg_len) + RTA_ALIGN(rtalen);
if (tlen > nlmsg->cap) rta = NLMSG_TAIL(&nlmsg->nlmsghdr);
return -ENOMEM; rta->rta_type = attr;
rta->rta_len = rtalen;
rta = NLMSG_TAIL(nlmsg->nlmsghdr); memcpy(RTA_DATA(rta), data, len);
rta->rta_type = attr; nlmsg->nlmsghdr.nlmsg_len =
rta->rta_len = rtalen; NLMSG_ALIGN(nlmsg->nlmsghdr.nlmsg_len) + RTA_ALIGN(rtalen);
memcpy(RTA_DATA(rta), data, len);
nlmsg->nlmsghdr->nlmsg_len = tlen;
return 0; return 0;
} }
...@@ -94,7 +91,7 @@ extern int nla_put_attr(struct nlmsg *nlmsg, int attr) ...@@ -94,7 +91,7 @@ extern int nla_put_attr(struct nlmsg *nlmsg, int attr)
struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr) struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr)
{ {
struct rtattr *rtattr = NLMSG_TAIL(nlmsg->nlmsghdr); struct rtattr *rtattr = NLMSG_TAIL(&nlmsg->nlmsghdr);
if (nla_put_attr(nlmsg, attr)) if (nla_put_attr(nlmsg, attr))
return NULL; return NULL;
...@@ -104,7 +101,7 @@ struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr) ...@@ -104,7 +101,7 @@ struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr)
void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr) void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr)
{ {
attr->rta_len = (void *)NLMSG_TAIL(nlmsg->nlmsghdr) - (void *)attr; attr->rta_len = (void *)NLMSG_TAIL(&nlmsg->nlmsghdr) - (void *)attr;
} }
extern struct nlmsg *nlmsg_alloc(size_t size) extern struct nlmsg *nlmsg_alloc(size_t size)
...@@ -112,48 +109,18 @@ extern struct nlmsg *nlmsg_alloc(size_t size) ...@@ -112,48 +109,18 @@ extern struct nlmsg *nlmsg_alloc(size_t size)
struct nlmsg *nlmsg; struct nlmsg *nlmsg;
size_t len = NLMSG_HDRLEN + NLMSG_ALIGN(size); size_t len = NLMSG_HDRLEN + NLMSG_ALIGN(size);
nlmsg = (struct nlmsg *)malloc(sizeof(struct nlmsg)); nlmsg = (struct nlmsg *)malloc(len);
if (!nlmsg) if (!nlmsg)
return NULL; return NULL;
nlmsg->nlmsghdr = (struct nlmsghdr *)malloc(len); memset(nlmsg, 0, len);
if (!nlmsg->nlmsghdr) nlmsg->nlmsghdr.nlmsg_len = NLMSG_HDRLEN;
goto errout;
memset(nlmsg->nlmsghdr, 0, len);
nlmsg->cap = len;
nlmsg->nlmsghdr->nlmsg_len = NLMSG_HDRLEN;
return nlmsg; return nlmsg;
errout:
free(nlmsg);
return NULL;
}
extern void *nlmsg_reserve(struct nlmsg *nlmsg, size_t len)
{
void *buf;
size_t nlmsg_len = nlmsg->nlmsghdr->nlmsg_len;
size_t tlen = NLMSG_ALIGN(len);
if (nlmsg_len + tlen > nlmsg->cap)
return NULL;
buf = nlmsg->nlmsghdr + nlmsg_len;
nlmsg->nlmsghdr->nlmsg_len += tlen;
if (tlen > len)
memset(buf + len, 0, tlen - len);
return buf;
} }
extern void nlmsg_free(struct nlmsg *nlmsg) extern void nlmsg_free(struct nlmsg *nlmsg)
{ {
if (!nlmsg)
return;
free(nlmsg->nlmsghdr);
free(nlmsg); free(nlmsg);
} }
...@@ -163,7 +130,7 @@ extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer) ...@@ -163,7 +130,7 @@ extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer)
struct sockaddr_nl nladdr; struct sockaddr_nl nladdr;
struct iovec iov = { struct iovec iov = {
.iov_base = answer, .iov_base = answer,
.iov_len = answer->nlmsghdr->nlmsg_len, .iov_len = answer->nlmsghdr.nlmsg_len,
}; };
struct msghdr msg = { struct msghdr msg = {
...@@ -190,7 +157,7 @@ again: ...@@ -190,7 +157,7 @@ again:
return 0; return 0;
if (msg.msg_flags & MSG_TRUNC && if (msg.msg_flags & MSG_TRUNC &&
ret == answer->nlmsghdr->nlmsg_len) ret == answer->nlmsghdr.nlmsg_len)
return -EMSGSIZE; return -EMSGSIZE;
return ret; return ret;
...@@ -201,7 +168,7 @@ extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg) ...@@ -201,7 +168,7 @@ extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg)
struct sockaddr_nl nladdr; struct sockaddr_nl nladdr;
struct iovec iov = { struct iovec iov = {
.iov_base = (void*)nlmsg, .iov_base = (void*)nlmsg,
.iov_len = nlmsg->nlmsghdr->nlmsg_len, .iov_len = nlmsg->nlmsghdr.nlmsg_len,
}; };
struct msghdr msg = { struct msghdr msg = {
.msg_name = &nladdr, .msg_name = &nladdr,
...@@ -239,7 +206,7 @@ extern int netlink_transaction(struct nl_handler *handler, ...@@ -239,7 +206,7 @@ extern int netlink_transaction(struct nl_handler *handler,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (answer->nlmsghdr->nlmsg_type == NLMSG_ERROR) { if (answer->nlmsghdr.nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer); struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer);
return err->error; return err->error;
} }
......
...@@ -53,16 +53,14 @@ struct nl_handler { ...@@ -53,16 +53,14 @@ struct nl_handler {
}; };
/* /*
* struct nlmsg : the netlink message structure. This message is to be used to * struct nlmsg : the netlink message structure, it consists just
* on a definition for a nlmsghdr. This message is to be used to
* be allocated with netlink_alloc. * be allocated with netlink_alloc.
* * @nlmsghdr : a pointer to a netlink message header, this field
* @nlmsghdr: a pointer to a netlink message header * _must_ be always the first field of this structure
* @cap: capacity of the netlink message, this is the initially allocated size
* and later operations (e.g. reserve and put) can not exceed this limit.
*/ */
struct nlmsg { struct nlmsg {
struct nlmsghdr *nlmsghdr; struct nlmsghdr nlmsghdr;
ssize_t cap;
}; };
/* /*
...@@ -222,16 +220,6 @@ void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr); ...@@ -222,16 +220,6 @@ void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr);
struct nlmsg *nlmsg_alloc(size_t size); struct nlmsg *nlmsg_alloc(size_t size);
/* /*
* Reserve room for additional data at the tail of a netlink message
*
* @nlmsg: the netlink message
* @len: length of additional data to reserve room for
*
* Returns a pointer to newly reserved room or NULL
*/
void *nlmsg_reserve(struct nlmsg *nlmsg, size_t len);
/*
* nlmsg_free : free a previously allocate message * nlmsg_free : free a previously allocate message
* *
* @nlmsg: the netlink message to be freed * @nlmsg: the netlink message to be freed
......
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