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

[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
...@@ -2868,6 +2868,29 @@ static void addrconf_verify(unsigned long foo) ...@@ -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, ...@@ -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 */
......
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