addrconf.c (56fc709b7a9fe191173dc772a881e180458db517) addrconf.c (752a92927e97e88096394dac3f10d12a58555254)
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 942 unchanged lines hidden (view full) ---

951}
952
953static u32 inet6_addr_hash(const struct in6_addr *addr)
954{
955 return hash_32(ipv6_addr_hash(addr), IN6_ADDR_HSIZE_SHIFT);
956}
957
958static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 942 unchanged lines hidden (view full) ---

951}
952
953static u32 inet6_addr_hash(const struct in6_addr *addr)
954{
955 return hash_32(ipv6_addr_hash(addr), IN6_ADDR_HSIZE_SHIFT);
956}
957
958static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
959 struct net_device *dev)
959 struct net_device *dev, unsigned int hash)
960{
960{
961 unsigned int hash = inet6_addr_hash(addr);
962 struct inet6_ifaddr *ifp;
963
964 hlist_for_each_entry(ifp, &inet6_addr_lst[hash], addr_lst) {
965 if (!net_eq(dev_net(ifp->idev->dev), net))
966 continue;
967 if (ipv6_addr_equal(&ifp->addr, addr)) {
968 if (!dev || ifp->idev->dev == dev)
969 return true;
970 }
971 }
972 return false;
973}
974
975static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
976{
961 struct inet6_ifaddr *ifp;
962
963 hlist_for_each_entry(ifp, &inet6_addr_lst[hash], addr_lst) {
964 if (!net_eq(dev_net(ifp->idev->dev), net))
965 continue;
966 if (ipv6_addr_equal(&ifp->addr, addr)) {
967 if (!dev || ifp->idev->dev == dev)
968 return true;
969 }
970 }
971 return false;
972}
973
974static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
975{
977 unsigned int hash;
976 unsigned int hash = inet6_addr_hash(&ifa->addr);
978 int err = 0;
979
980 spin_lock(&addrconf_hash_lock);
981
982 /* Ignore adding duplicate addresses on an interface */
977 int err = 0;
978
979 spin_lock(&addrconf_hash_lock);
980
981 /* Ignore adding duplicate addresses on an interface */
983 if (ipv6_chk_same_addr(dev_net(dev), &ifa->addr, dev)) {
982 if (ipv6_chk_same_addr(dev_net(dev), &ifa->addr, dev, hash)) {
984 ADBG("ipv6_add_addr: already assigned\n");
985 err = -EEXIST;
983 ADBG("ipv6_add_addr: already assigned\n");
984 err = -EEXIST;
986 goto out;
985 } else {
986 hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
987 }
988
987 }
988
989 /* Add to big hash table */
990 hash = inet6_addr_hash(&ifa->addr);
991 hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
992
993out:
994 spin_unlock(&addrconf_hash_lock);
995
996 return err;
997}
998
999/* On success it returns ifp with increased reference count */
1000
1001static struct inet6_ifaddr *

--- 5650 unchanged lines hidden ---
989 spin_unlock(&addrconf_hash_lock);
990
991 return err;
992}
993
994/* On success it returns ifp with increased reference count */
995
996static struct inet6_ifaddr *

--- 5650 unchanged lines hidden ---