예제 #1
0
int lxc_netdev_delete_by_index(int ifindex)
{
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL, *answer = NULL;
	struct link_req *link_req;
	int err;

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!answer)
		goto out;

	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:
	netlink_close(&nlh);
	nlmsg_free(answer);
	nlmsg_free(nlmsg);
	return err;
}
예제 #2
0
static int
ip_addr_add(int family, int ifindex,
		       void *addr, void *bcast, void *acast, int prefix) {
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL, *answer = NULL;
	struct ip_req *ip_req;
	int addrlen;
	int err;

	addrlen = family == AF_INET ? sizeof(struct in_addr) :
		sizeof(struct in6_addr);

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!answer)
		goto out;

	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;
        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))
		goto out;

	if (nla_put_buffer(nlmsg, IFA_ADDRESS, addr, addrlen))
		goto out;

	if (nla_put_buffer(nlmsg, IFA_BROADCAST, bcast, addrlen))
		goto out;

	/* TODO : multicast, anycast with ipv6 */
	err = -EPROTONOSUPPORT;
	if (family == AF_INET6 &&
	    (memcmp(bcast, &in6addr_any, sizeof(in6addr_any)) ||
	     memcmp(acast, &in6addr_any, sizeof(in6addr_any))))
		goto out;

	err = netlink_transaction(&nlh, nlmsg, answer);
out:
	netlink_close(&nlh);
	nlmsg_free(answer);
	nlmsg_free(nlmsg);
	return err;
}
예제 #3
0
파일: rtnl.c 프로젝트: d4s/lxc
extern int rtnetlink_transaction(struct rtnl_handler *handler,
				 struct rtnlmsg *request,
				 struct rtnlmsg *answer)
{
	return netlink_transaction(&handler->nlh,
				   (struct nlmsg *)&request->nlmsghdr,
				   (struct nlmsg *)&answer->nlmsghdr);
}
예제 #4
0
static int
ip_gateway_add(int family, int ifindex, void *gw) {
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL, *answer = NULL;
	struct rt_req *rt_req;
	int addrlen;
	int err;

	addrlen = family == AF_INET ? sizeof(struct in_addr) :
		sizeof(struct in6_addr);

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!answer)
		goto out;

	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;
	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_req->rt.rtm_dst_len = 0;

	err = -EINVAL;
	if (nla_put_buffer(nlmsg, RTA_GATEWAY, gw, addrlen))
		goto out;

	/* Adding the interface index enables the use of link-local
	 * addresses for the gateway */
	if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
		goto out;

	err = netlink_transaction(&nlh, nlmsg, answer);
out:
	netlink_close(&nlh);
	nlmsg_free(answer);
	nlmsg_free(nlmsg);
	return err;
}
예제 #5
0
int lxc_device_rename(const char *oldname, const char *newname)
{
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL, *answer = NULL;
	struct link_req *link_req;
	int index, len, err = -1;

	if (netlink_open(&nlh, NETLINK_ROUTE))
		return -1;

	len = strlen(oldname);
	if (len == 1 || len > IFNAMSIZ)
		goto out;

	len = strlen(newname);
	if (len == 1 || len > IFNAMSIZ)
		goto out;

	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!answer)
		goto out;

	index = if_nametoindex(oldname);
	if (!index)
		goto out;

	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_ACK|NLM_F_REQUEST;
	nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;

	if (nla_put_string(nlmsg, IFLA_IFNAME, newname))
		goto out;

	if (netlink_transaction(&nlh, nlmsg, answer))
		goto out;

	err = 0;
out:
	netlink_close(&nlh);
	nlmsg_free(answer);
	nlmsg_free(nlmsg);
	return err;
}
예제 #6
0
static int netdev_set_flag(const char *name, int flag)
{
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL, *answer = NULL;
	struct link_req *link_req;
	int index, len, err;

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -EINVAL;
	len = strlen(name);
	if (len == 1 || len >= IFNAMSIZ)
		goto out;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!answer)
		goto out;

	err = -EINVAL;
	index = if_nametoindex(name);
	if (!index)
		goto out;

	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:
	netlink_close(&nlh);
	nlmsg_free(nlmsg);
	nlmsg_free(answer);
	return err;
}
예제 #7
0
파일: network.c 프로젝트: LynxChaus/lxc
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;
	int err;

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	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));
	if (!ifi)
		goto out;
	ifi->ifi_family = AF_UNSPEC;
	ifi->ifi_index = ifindex;

	if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid))
		goto out;

	if (ifname != NULL) {
		if (nla_put_string(nlmsg, IFLA_IFNAME, ifname))
			goto out;
	}

	err = netlink_transaction(&nlh, nlmsg, nlmsg);
out:
	netlink_close(&nlh);
	nlmsg_free(nlmsg);
	return err;
}
예제 #8
0
int lxc_netdev_move(char *ifname, pid_t pid)
{
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL;
	struct link_req *link_req;
	int err, index;

	index = if_nametoindex(ifname);
	if (!ifname)
		return -EINVAL;

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	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_NET_NS_PID, pid))
		goto out;

	err = netlink_transaction(&nlh, nlmsg, nlmsg);
out:
	netlink_close(&nlh);
	nlmsg_free(nlmsg);
	return err;
}
예제 #9
0
static int genetlink_resolve_family(const char *family)
{
	struct nl_handler handler;
	struct nlattr *attr;
	struct genlmsg *request, *reply;
	struct genlmsghdr *genlmsghdr;

	int len, ret;

	request = genlmsg_alloc(GENLMSG_GOOD_SIZE);
	if (!request)
		return -ENOMEM;
		
	reply = genlmsg_alloc(GENLMSG_GOOD_SIZE);
	if (!reply) {
		genlmsg_free(request);
		return -ENOMEM;
	}

	request->nlmsghdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	request->nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
        request->nlmsghdr.nlmsg_type = GENL_ID_CTRL;

	genlmsghdr = NLMSG_DATA(&request->nlmsghdr);
        genlmsghdr->cmd = CTRL_CMD_GETFAMILY;

	ret = netlink_open(&handler, NETLINK_GENERIC);
	if (ret)
		goto out;

	ret = nla_put_string((struct nlmsg *)&request->nlmsghdr,
			     CTRL_ATTR_FAMILY_NAME, family);
	if (ret)
		goto out_close;

	ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr,
				  (struct nlmsg *)&reply->nlmsghdr);
	if (ret < 0)
		goto out_close;

	genlmsghdr = NLMSG_DATA(&reply->nlmsghdr);
	len = reply->nlmsghdr.nlmsg_len;

	ret = -ENOMSG;
	if (reply->nlmsghdr.nlmsg_type !=  GENL_ID_CTRL)
		goto out_close;

	if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY)
		goto out_close;

	ret = -EMSGSIZE;
	len -= NLMSG_LENGTH(GENL_HDRLEN);
	if (len < 0)
		goto out_close;
	
	attr = (struct nlattr *)GENLMSG_DATA(reply);
	attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len));
	
	ret = -ENOMSG;
	if (attr->nla_type != CTRL_ATTR_FAMILY_ID)
		goto out_close;

	ret =  *(__u16 *) NLA_DATA(attr);
out_close:
	netlink_close(&handler);
out:
	genlmsg_free(request);
	genlmsg_free(reply);
	return ret;
}
예제 #10
0
int lxc_veth_create(const char *name1, const char *name2)
{
	struct nl_handler nlh;
	struct nlmsg *nlmsg = NULL, *answer = NULL;
	struct link_req *link_req;
	struct rtattr *nest1, *nest2, *nest3;
	int len, err;

	err = netlink_open(&nlh, NETLINK_ROUTE);
	if (err)
		return err;

	err = -EINVAL;
	len = strlen(name1);
	if (len == 1 || len >= IFNAMSIZ)
		goto out;

	len = strlen(name2);
	if (len == 1 || len >= IFNAMSIZ)
		goto out;

	err = -ENOMEM;
	nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!nlmsg)
		goto out;

	answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
	if (!answer)
		goto out;

	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;

	err = -EINVAL;
	nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO);
	if (!nest1)
		goto out;

	if (nla_put_string(nlmsg, IFLA_INFO_KIND, "veth"))
		goto out;

	nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
	if (!nest2)
		goto out;

	nest3 = nla_begin_nested(nlmsg, VETH_INFO_PEER);
	if (!nest3)
		goto out;

	nlmsg->nlmsghdr.nlmsg_len += sizeof(struct ifinfomsg);

	if (nla_put_string(nlmsg, IFLA_IFNAME, name2))
		goto out;

	nla_end_nested(nlmsg, nest3);

	nla_end_nested(nlmsg, nest2);

	nla_end_nested(nlmsg, nest1);

	if (nla_put_string(nlmsg, IFLA_IFNAME, name1))
		goto out;

	err = netlink_transaction(&nlh, nlmsg, answer);
out:
	netlink_close(&nlh);
	nlmsg_free(answer);
	nlmsg_free(nlmsg);
	return err;
}