# define IFLA_MACVLAN_MODE 1
#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)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
int err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (!nlmsg)
goto out;
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
- ifi->ifi_index = ifindex;
+ link_req = (struct link_req *)nlmsg;
+ link_req->ifinfomsg.ifi_family = AF_UNSPEC;
+ link_req->ifinfomsg.ifi_index = ifindex;
+ nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
goto out;
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
int err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (!answer)
goto out;
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
- nlmsg->nlmsghdr->nlmsg_type = RTM_DELLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
- ifi->ifi_index = ifindex;
+ link_req = (struct link_req *)nlmsg;
+ link_req->ifinfomsg.ifi_family = AF_UNSPEC;
+ link_req->ifinfomsg.ifi_index = ifindex;
+ nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_DELLINK;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
int len, err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (!answer)
goto out;
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
- ifi->ifi_index = ifindex;
+ link_req = (struct link_req *)nlmsg;
+ link_req->ifinfomsg.ifi_family = AF_UNSPEC;
+ link_req->ifinfomsg.ifi_index = ifindex;
+ nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
goto out;
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
int index, len, err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (!index)
goto out;
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
- ifi->ifi_index = index;
- ifi->ifi_change |= IFF_UP;
- ifi->ifi_flags |= flag;
+ link_req = (struct link_req *)nlmsg;
+ link_req->ifinfomsg.ifi_family = AF_UNSPEC;
+ link_req->ifinfomsg.ifi_index = index;
+ link_req->ifinfomsg.ifi_change |= IFF_UP;
+ link_req->ifinfomsg.ifi_flags |= flag;
+ nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
err = netlink_transaction(&nlh, nlmsg, answer);
out:
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
int index, len, err;
+ struct ifinfomsg *ifi;
if (!name)
return -EINVAL;
if (!index)
goto out;
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST;
- nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
- ifi->ifi_index = index;
-
- nlmsg_reserve(answer, sizeof(struct ifinfomsg));
+ link_req = (struct link_req *)nlmsg;
+ link_req->ifinfomsg.ifi_family = AF_UNSPEC;
+ link_req->ifinfomsg.ifi_index = index;
+ nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_GETLINK;
err = netlink_transaction(&nlh, nlmsg, answer);
if (err)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct ip_req *ip_req;
struct nlmsghdr *msg;
int err, res;
int recv_len = 0, answer_len;
/* Save the answer buffer length, since it will be overwritten
* on the first receive (and we might need to receive more than
* once. */
- nlmsg_reserve(answer, NLMSG_GOOD_SIZE);
- answer_len = answer->nlmsghdr->nlmsg_len;
-
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
- nlmsg->nlmsghdr->nlmsg_type = RTM_GETLINK;
+ answer_len = answer->nlmsghdr.nlmsg_len;
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
+ 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_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
* on all interfaces. */
do {
/* Restore the answer buffer length, it might have been
* overwritten by a previous receive. */
- answer->nlmsghdr->nlmsg_len = answer_len;
+ answer->nlmsghdr.nlmsg_len = answer_len;
/* Get the (next) batch of reply messages */
err = netlink_rcv(&nlh, answer);
err = 0;
/* Satisfy the typing for the netlink macros */
- msg = answer->nlmsghdr;
+ msg = &answer->nlmsghdr;
while (NLMSG_OK(msg, recv_len)) {
break;
}
- ifi = NLMSG_DATA(msg);
+ struct ifinfomsg *ifi = NLMSG_DATA(msg);
if (ifi->ifi_index == ifindex) {
struct rtattr *rta = IFLA_RTA(ifi);
int attr_len = msg->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
int index, len, err;
err = netlink_open(&nlh, NETLINK_ROUTE);
if (!index)
goto out;
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
- ifi->ifi_index = index;
+ link_req = (struct link_req *)nlmsg;
+ link_req->ifinfomsg.ifi_family = AF_UNSPEC;
+ link_req->ifinfomsg.ifi_index = index;
+ nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
if (nla_put_u32(nlmsg, IFLA_MTU, mtu))
goto out;
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
struct rtattr *nest1, *nest2, *nest3;
int len, err;
if (!answer)
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;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
err = -EINVAL;
nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest3)
goto out;
- nlmsg->nlmsghdr->nlmsg_len += sizeof(struct ifinfomsg);
+ nlmsg->nlmsghdr.nlmsg_len += sizeof(struct ifinfomsg);
if (nla_put_string(nlmsg, IFLA_IFNAME, name2))
goto out;
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
struct rtattr *nest, *nest2;
int lindex, len, err;
if (!lindex)
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;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifinfomsg *ifi;
+ struct link_req *link_req;
struct rtattr *nest, *nest2;
int index, len, err;
if (!index)
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;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWLINK;
-
- ifi = nlmsg_reserve(nlmsg, sizeof(struct ifinfomsg));
- ifi->ifi_family = AF_UNSPEC;
+ nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifaddrmsg *ifa;
+ struct ip_req *ip_req;
int addrlen;
int err;
if (!answer)
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;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWADDR;
-
- ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
- ifa->ifa_prefixlen = prefix;
- ifa->ifa_index = ifindex;
- ifa->ifa_family = family;
- ifa->ifa_scope = 0;
+ ip_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWADDR;
+ ip_req->ifa.ifa_prefixlen = prefix;
+ ip_req->ifa.ifa_index = ifindex;
+ ip_req->ifa.ifa_family = family;
+ ip_req->ifa.ifa_scope = 0;
err = -EINVAL;
if (nla_put_buffer(nlmsg, IFA_LOCAL, addr, addrlen))
* address and stores that pointer in *res (so res should be an
* in_addr** or in6_addr**).
*/
-static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
- struct ifaddrmsg *ifa = NLMSG_DATA(msg);
- struct rtattr *rta = IFA_RTA(ifa);
- int attr_len = NLMSG_PAYLOAD(msg, sizeof(struct ifaddrmsg));
+static int ifa_get_local_ip(int family, struct ip_req *ip_info, void** res) {
+ struct rtattr *rta = IFA_RTA(&ip_info->ifa);
+ int attr_len = IFA_PAYLOAD(&ip_info->nlmsg.nlmsghdr);
int addrlen;
- if (ifa->ifa_family != family)
+ if (ip_info->ifa.ifa_family != family)
return 0;
addrlen = family == AF_INET ? sizeof(struct in_addr) :
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct ifaddrmsg *ifa;
+ struct ip_req *ip_req, *ip_info;
struct nlmsghdr *msg;
int err;
int recv_len = 0, answer_len;
/* Save the answer buffer length, since it will be overwritten
* on the first receive (and we might need to receive more than
* once. */
- nlmsg_reserve(answer, NLMSG_GOOD_SIZE);
- answer_len = answer->nlmsghdr->nlmsg_len;
-
- nlmsg->nlmsghdr->nlmsg_flags = NLM_F_REQUEST|NLM_F_ROOT;
- nlmsg->nlmsghdr->nlmsg_type = RTM_GETADDR;
+ answer_len = answer->nlmsghdr.nlmsg_len;
- ifa = nlmsg_reserve(nlmsg, sizeof(struct ifaddrmsg));
- ifa->ifa_family = family;
+ 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_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
* on all interfaces. */
do {
/* Restore the answer buffer length, it might have been
* overwritten by a previous receive. */
- answer->nlmsghdr->nlmsg_len = answer_len;
+ answer->nlmsghdr.nlmsg_len = answer_len;
/* Get the (next) batch of reply messages */
err = netlink_rcv(&nlh, answer);
err = 0;
/* Satisfy the typing for the netlink macros */
- msg = answer->nlmsghdr;
+ msg = &answer->nlmsghdr;
while (NLMSG_OK(msg, recv_len)) {
/* Stop reading if we see an error message */
goto out;
}
- ifa = (struct ifaddrmsg *)NLMSG_DATA(msg);
- if (ifa->ifa_index == ifindex) {
- if (ifa_get_local_ip(family, msg, res) < 0) {
+ ip_info = (struct ip_req *)msg;
+ if (ip_info->ifa.ifa_index == ifindex) {
+ if (ifa_get_local_ip(family, ip_info, res) < 0) {
err = -1;
goto out;
}
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct rtmsg *rt;
+ struct rt_req *rt_req;
int addrlen;
int err;
if (!answer)
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;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE;
-
- rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
- rt->rtm_family = family;
- rt->rtm_table = RT_TABLE_MAIN;
- rt->rtm_scope = RT_SCOPE_UNIVERSE;
- rt->rtm_protocol = RTPROT_BOOT;
- rt->rtm_type = RTN_UNICAST;
+ rt_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWROUTE;
+ rt_req->rt.rtm_family = family;
+ rt_req->rt.rtm_table = RT_TABLE_MAIN;
+ rt_req->rt.rtm_scope = RT_SCOPE_UNIVERSE;
+ rt_req->rt.rtm_protocol = RTPROT_BOOT;
+ rt_req->rt.rtm_type = RTN_UNICAST;
/* "default" destination */
- rt->rtm_dst_len = 0;
+ rt_req->rt.rtm_dst_len = 0;
err = -EINVAL;
if (nla_put_buffer(nlmsg, RTA_GATEWAY, gw, addrlen))
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
- struct rtmsg *rt;
+ struct rt_req *rt_req;
int addrlen;
int err;
if (!answer)
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;
- nlmsg->nlmsghdr->nlmsg_type = RTM_NEWROUTE;
-
- rt = nlmsg_reserve(nlmsg, sizeof(struct rtmsg));
- rt->rtm_family = family;
- rt->rtm_table = RT_TABLE_MAIN;
- rt->rtm_scope = RT_SCOPE_LINK;
- rt->rtm_protocol = RTPROT_BOOT;
- rt->rtm_type = RTN_UNICAST;
- rt->rtm_dst_len = addrlen*8;
+ rt_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWROUTE;
+ rt_req->rt.rtm_family = family;
+ rt_req->rt.rtm_table = RT_TABLE_MAIN;
+ rt_req->rt.rtm_scope = RT_SCOPE_LINK;
+ rt_req->rt.rtm_protocol = RTPROT_BOOT;
+ rt_req->rt.rtm_type = RTN_UNICAST;
+ rt_req->rt.rtm_dst_len = addrlen*8;
err = -EINVAL;
if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))