Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 461d8837 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

[IPV6] address: Convert address addition to new netlink api



Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 94aec08e
Loading
Loading
Loading
Loading
+45 −27
Original line number Original line Diff line number Diff line
@@ -2868,6 +2868,29 @@ static void addrconf_verify(unsigned long foo)
	spin_unlock_bh(&addrconf_verify_lock);
	spin_unlock_bh(&addrconf_verify_lock);
}
}


static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
{
	struct in6_addr *pfx = NULL;

	if (addr)
		pfx = nla_data(addr);

	if (local) {
		if (pfx && nla_memcmp(local, pfx, sizeof(*pfx)))
			pfx = NULL;
		else
			pfx = nla_data(local);
	}

	return pfx;
}

static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = {
	[IFA_ADDRESS]		= { .len = sizeof(struct in6_addr) },
	[IFA_LOCAL]		= { .len = sizeof(struct in6_addr) },
	[IFA_CACHEINFO]		= { .len = sizeof(struct ifa_cacheinfo) },
};

static int
static int
inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
{
@@ -2945,46 +2968,41 @@ inet6_addr_modify(int ifindex, struct in6_addr *pfx,
static int
static int
inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
{
	struct rtattr  **rta = arg;
	struct ifaddrmsg *ifm;
	struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
	struct nlattr *tb[IFA_MAX+1];
	struct in6_addr *pfx;
	struct in6_addr *pfx;
	__u32 valid_lft = INFINITY_LIFE_TIME, prefered_lft = INFINITY_LIFE_TIME;
	u32 valid_lft, preferred_lft;
	int err;


	pfx = NULL;
	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
	if (rta[IFA_ADDRESS-1]) {
	if (err < 0)
		if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*pfx))
		return err;
			return -EINVAL;

		pfx = RTA_DATA(rta[IFA_ADDRESS-1]);
	ifm = nlmsg_data(nlh);
	}
	pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
	if (rta[IFA_LOCAL-1]) {
		if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) ||
		    (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))))
			return -EINVAL;
		pfx = RTA_DATA(rta[IFA_LOCAL-1]);
	}
	if (pfx == NULL)
	if (pfx == NULL)
		return -EINVAL;
		return -EINVAL;


	if (rta[IFA_CACHEINFO-1]) {
	if (tb[IFA_CACHEINFO]) {
		struct ifa_cacheinfo *ci;
		struct ifa_cacheinfo *ci;
		if (RTA_PAYLOAD(rta[IFA_CACHEINFO-1]) < sizeof(*ci))

			return -EINVAL;
		ci = nla_data(tb[IFA_CACHEINFO]);
		ci = RTA_DATA(rta[IFA_CACHEINFO-1]);
		valid_lft = ci->ifa_valid;
		valid_lft = ci->ifa_valid;
		prefered_lft = ci->ifa_prefered;
		preferred_lft = ci->ifa_prefered;
	} else {
		preferred_lft = INFINITY_LIFE_TIME;
		valid_lft = INFINITY_LIFE_TIME;
	}
	}


	if (nlh->nlmsg_flags & NLM_F_REPLACE) {
	if (nlh->nlmsg_flags & NLM_F_REPLACE) {
		int ret;
		err = inet6_addr_modify(ifm->ifa_index, pfx,
		ret = inet6_addr_modify(ifm->ifa_index, pfx,
					preferred_lft, valid_lft);
					prefered_lft, valid_lft);
		if (err == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE))
		if (ret == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE))
			return err;
			return ret;
	}
	}


	return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
	return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
			      prefered_lft, valid_lft);
			      preferred_lft, valid_lft);

}
}


/* Maximum length of ifa_cacheinfo attributes */
/* Maximum length of ifa_cacheinfo attributes */