* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/capability.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <net/checksum.h>
-/* Big ac list lock for all the sockets */
-static rwlock_t ipv6_sk_ac_lock = RW_LOCK_UNLOCKED;
-
-/* XXX ip6_addr_match() and ip6_onlink() really belong in net/core.c */
+static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
-static int
-ip6_addr_match(struct in6_addr *addr1, struct in6_addr *addr2, int prefix)
-{
- __u32 mask;
- int i;
-
- if (prefix > 128 || prefix < 0)
- return 0;
- if (prefix == 0)
- return 1;
- for (i=0; i<4; ++i) {
- if (prefix >= 32)
- mask = ~0;
- else
- mask = htonl(~0 << (32 - prefix));
- if ((addr1->s6_addr32[i] ^ addr2->s6_addr32[i]) & mask)
- return 0;
- prefix -= 32;
- if (prefix <= 0)
- break;
- }
- return 1;
-}
+/* Big ac list lock for all the sockets */
+static DEFINE_RWLOCK(ipv6_sk_ac_lock);
static int
ip6_onlink(struct in6_addr *addr, struct net_device *dev)
int onlink;
onlink = 0;
- read_lock(&addrconf_lock);
+ rcu_read_lock();
idev = __in6_dev_get(dev);
if (idev) {
read_lock_bh(&idev->lock);
for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
- onlink = ip6_addr_match(addr, &ifa->addr,
- ifa->prefix_len);
+ onlink = ipv6_prefix_equal(addr, &ifa->addr,
+ ifa->prefix_len);
if (onlink)
break;
}
read_unlock_bh(&idev->lock);
}
- read_unlock(&addrconf_lock);
+ rcu_read_unlock();
return onlink;
}
prev_pac = NULL;
for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) {
if ((ifindex == 0 || pac->acl_ifindex == ifindex) &&
- ipv6_addr_cmp(&pac->acl_addr, addr) == 0)
+ ipv6_addr_equal(&pac->acl_addr, addr))
break;
prev_pac = pac;
}
for (pac=np->ipv6_ac_list; pac; pac=pac->acl_next) {
if (ifindex && pac->acl_ifindex != ifindex)
continue;
- found = ipv6_addr_cmp(&pac->acl_addr, addr) == 0;
+ found = ipv6_addr_equal(&pac->acl_addr, addr);
if (found)
break;
}
}
for (aca = idev->ac_list; aca; aca = aca->aca_next) {
- if (ipv6_addr_cmp(&aca->aca_addr, addr) == 0) {
+ if (ipv6_addr_equal(&aca->aca_addr, addr)) {
aca->aca_users++;
err = 0;
goto out;
* not found: create a new one.
*/
- aca = kmalloc(sizeof(struct ifacaddr6), GFP_ATOMIC);
+ aca = kzalloc(sizeof(struct ifacaddr6), GFP_ATOMIC);
if (aca == NULL) {
err = -ENOMEM;
goto out;
}
- memset(aca, 0, sizeof(struct ifacaddr6));
-
ipv6_addr_copy(&aca->aca_addr, addr);
aca->aca_idev = idev;
aca->aca_rt = rt;
/* aca_tstamp should be updated upon changes */
aca->aca_cstamp = aca->aca_tstamp = jiffies;
atomic_set(&aca->aca_refcnt, 2);
- aca->aca_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&aca->aca_lock);
aca->aca_next = idev->ac_list;
idev->ac_list = aca;
write_unlock_bh(&idev->lock);
dst_hold(&rt->u.dst);
- if (ip6_ins_rt(rt, NULL, NULL))
+ if (ip6_ins_rt(rt))
dst_release(&rt->u.dst);
addrconf_join_solict(dev, &aca->aca_addr);
write_lock_bh(&idev->lock);
prev_aca = NULL;
for (aca = idev->ac_list; aca; aca = aca->aca_next) {
- if (ipv6_addr_cmp(&aca->aca_addr, addr) == 0)
+ if (ipv6_addr_equal(&aca->aca_addr, addr))
break;
prev_aca = aca;
}
addrconf_leave_solict(idev, &aca->aca_addr);
dst_hold(&aca->aca_rt->u.dst);
- if (ip6_del_rt(aca->aca_rt, NULL, NULL))
+ if (ip6_del_rt(aca->aca_rt))
dst_free(&aca->aca_rt->u.dst);
else
dst_release(&aca->aca_rt->u.dst);
return 0;
}
-int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
+static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
{
int ret;
struct inet6_dev *idev = in6_dev_get(dev);
if (idev) {
read_lock_bh(&idev->lock);
for (aca = idev->ac_list; aca; aca = aca->aca_next)
- if (ipv6_addr_cmp(&aca->aca_addr, addr) == 0)
+ if (ipv6_addr_equal(&aca->aca_addr, addr))
break;
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
break;
}
read_unlock_bh(&idev->lock);
+ in6_dev_put(idev);
}
return im;
}
struct ac6_iter_state *state = ac6_seq_private(seq);
seq_printf(seq,
- "%-4d %-15s "
- "%04x%04x%04x%04x%04x%04x%04x%04x "
- "%5d\n",
+ "%-4d %-15s " NIP6_SEQFMT " %5d\n",
state->dev->ifindex, state->dev->name,
NIP6(im->aca_addr),
im->aca_users);
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct ac6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct ac6_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree: