static int arp_req_set_public(struct net *net, struct arpreq *r,
                struct net_device *dev)
 {
-       __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
        __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
 
-       if (mask && mask != htonl(0xFFFFFFFF))
-               return -EINVAL;
        if (!dev && (r->arp_flags & ATF_COM)) {
                dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
                                      r->arp_ha.sa_data);
                        return -ENODEV;
        }
        if (mask) {
+               __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+
                if (!pneigh_lookup(&arp_tbl, net, &ip, dev, 1))
                        return -ENOBUFS;
                return 0;
 static int arp_req_delete_public(struct net *net, struct arpreq *r,
                struct net_device *dev)
 {
-       __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
        __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
 
-       if (mask == htonl(0xFFFFFFFF))
-               return pneigh_delete(&arp_tbl, net, &ip, dev);
+       if (mask) {
+               __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
 
-       if (mask)
-               return -EINVAL;
+               return pneigh_delete(&arp_tbl, net, &ip, dev);
+       }
 
        return arp_req_set_proxy(net, dev, 0);
 }
 
 int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 {
-       int err;
-       struct arpreq r;
        struct net_device *dev = NULL;
+       struct arpreq r;
+       __be32 *netmask;
+       int err;
 
        switch (cmd) {
        case SIOCDARP:
        if (!(r.arp_flags & ATF_PUBL) &&
            (r.arp_flags & (ATF_NETMASK | ATF_DONTPUB)))
                return -EINVAL;
+
+       netmask = &((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr;
        if (!(r.arp_flags & ATF_NETMASK))
-               ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
-                                                          htonl(0xFFFFFFFFUL);
+               *netmask = htonl(0xFFFFFFFFUL);
+       else if (*netmask && *netmask != htonl(0xFFFFFFFFUL))
+               return -EINVAL;
+
        rtnl_lock();
        if (r.arp_dev[0]) {
                err = -ENODEV;