[IPV6] address: Convert address lookup to new netlink api
[deliverable/linux.git] / net / ipv6 / addrconf.c
index 61627036eb2bf2fdca5eed28911451633db0ef1a..b2c38b3edb390ff2902a4db12fe405b376b32eaa 100644 (file)
@@ -3234,58 +3234,54 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
        return inet6_dump_addr(skb, cb, type);
 }
 
-static int inet6_rtm_getaddr(struct sk_buff *in_skb,
-               struct nlmsghdr* nlh, void *arg)
+static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
+                            void *arg)
 {
-       struct rtattr **rta = arg;
-       struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
+       struct ifaddrmsg *ifm;
+       struct nlattr *tb[IFA_MAX+1];
        struct in6_addr *addr = NULL;
        struct net_device *dev = NULL;
        struct inet6_ifaddr *ifa;
        struct sk_buff *skb;
-       int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE);
+       int payload = sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE;
        int err;
 
-       if (rta[IFA_ADDRESS-1]) {
-               if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*addr))
-                       return -EINVAL;
-               addr = RTA_DATA(rta[IFA_ADDRESS-1]);
-       }
-       if (rta[IFA_LOCAL-1]) {
-               if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*addr) ||
-                   (addr && memcmp(addr, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*addr))))
-                       return -EINVAL;
-               addr = RTA_DATA(rta[IFA_LOCAL-1]);
+       err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+       if (err < 0)
+               goto errout;
+
+       addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
+       if (addr == NULL) {
+               err = -EINVAL;
+               goto errout;
        }
-       if (addr == NULL)
-               return -EINVAL;
 
+       ifm = nlmsg_data(nlh);
        if (ifm->ifa_index)
                dev = __dev_get_by_index(ifm->ifa_index);
 
-       if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL)
-               return -EADDRNOTAVAIL;
+       if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
+               err = -EADDRNOTAVAIL;
+               goto errout;
+       }
 
-       if ((skb = alloc_skb(size, GFP_KERNEL)) == NULL) {
+       if ((skb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL)) == NULL) {
                err = -ENOBUFS;
-               goto out;
+               goto errout_ifa;
        }
 
-       NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
        err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
                                nlh->nlmsg_seq, RTM_NEWADDR, 0);
        if (err < 0) {
-               err = -EMSGSIZE;
-               goto out_free;
+               kfree_skb(skb);
+               goto errout_ifa;
        }
 
        err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
-out:
+errout_ifa:
        in6_ifa_put(ifa);
+errout:
        return err;
-out_free:
-       kfree_skb(skb);
-       goto out;
 }
 
 static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
This page took 0.029646 seconds and 5 git commands to generate.