X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fanycast.c;h=fe0c895d03a5099804d202b3e78a309ded8efc32;hb=refs%2Fheads%2Fvserver;hp=a0de548c56cae218b1edd97fb3d2935dd7c6454a;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index a0de548c5..fe0c895d0 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -13,7 +13,7 @@ * 2 of the License, or (at your option) any later version. */ -#include +#include #include #include #include @@ -43,34 +43,10 @@ #include -/* 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) @@ -80,19 +56,19 @@ 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; } @@ -205,7 +181,7 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr) 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; } @@ -278,7 +254,7 @@ int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex) 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; } @@ -320,7 +296,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) } 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; @@ -331,7 +307,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) * 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; @@ -345,8 +321,6 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) goto out; } - memset(aca, 0, sizeof(struct ifacaddr6)); - ipv6_addr_copy(&aca->aca_addr, addr); aca->aca_idev = idev; aca->aca_rt = rt; @@ -354,14 +328,14 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) /* 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); @@ -384,7 +358,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *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; } @@ -404,7 +378,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr) 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); @@ -413,7 +387,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr) 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); @@ -436,7 +410,7 @@ static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr) 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); @@ -488,6 +462,7 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) break; } read_unlock_bh(&idev->lock); + in6_dev_put(idev); } return im; } @@ -555,9 +530,7 @@ static int ac6_seq_show(struct seq_file *seq, void *v) 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); @@ -575,7 +548,7 @@ static int ac6_seq_open(struct inode *inode, struct file *file) { 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; @@ -586,7 +559,6 @@ static int ac6_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; - memset(s, 0, sizeof(*s)); out: return rc; out_kfree: