ipv6: Fix conflict resolutions during ipv6 binding
[safe/jmp/linux-2.6] / include / net / addrconf.h
index edcb4bb..7b55ab2 100644 (file)
@@ -71,54 +71,85 @@ extern int                  ipv6_chk_addr(struct net *net,
 extern int                     ipv6_chk_home_addr(struct net *net,
                                                   struct in6_addr *addr);
 #endif
+
+extern int                     ipv6_chk_prefix(struct in6_addr *addr,
+                                               struct net_device *dev);
+
 extern struct inet6_ifaddr      *ipv6_get_ifaddr(struct net *net,
-                                                struct in6_addr *addr,
+                                                const struct in6_addr *addr,
                                                 struct net_device *dev,
                                                 int strict);
 
-extern int                     ipv6_dev_get_saddr(struct net_device *dev, 
-                                              struct in6_addr *daddr,
+extern int                     ipv6_dev_get_saddr(struct net *net,
+                                              struct net_device *dev,
+                                              const struct in6_addr *daddr,
+                                              unsigned int srcprefs,
                                               struct in6_addr *saddr);
 extern int                     ipv6_get_lladdr(struct net_device *dev,
                                                struct in6_addr *addr,
                                                unsigned char banned_flags);
-extern int                     ipv6_rcv_saddr_equal(const struct sock *sk, 
-                                                     const struct sock *sk2);
+extern int                     ipv6_rcv_saddr_equal(const struct sock *sk,
+                                                   const struct sock *sk2);
 extern void                    addrconf_join_solict(struct net_device *dev,
                                        struct in6_addr *addr);
 extern void                    addrconf_leave_solict(struct inet6_dev *idev,
                                        struct in6_addr *addr);
 
+static inline unsigned long addrconf_timeout_fixup(u32 timeout,
+                                                   unsigned unit)
+{
+       if (timeout == 0xffffffff)
+               return ~0UL;
+
+       /*
+        * Avoid arithmetic overflow.
+        * Assuming unit is constant and non-zero, this "if" statement
+        * will go away on 64bit archs.
+        */
+       if (0xfffffffe > LONG_MAX / unit && timeout > LONG_MAX / unit)
+               return LONG_MAX / unit;
+
+       return timeout;
+}
+
+static inline int addrconf_finite_timeout(unsigned long timeout)
+{
+       return ~timeout;
+}
+
 /*
  *     IPv6 Address Label subsystem (addrlabel.c)
  */
 extern int                     ipv6_addr_label_init(void);
 extern void                    ipv6_addr_label_rtnl_register(void);
-extern u32                     ipv6_addr_label(const struct in6_addr *addr,
+extern u32                     ipv6_addr_label(struct net *net,
+                                               const struct in6_addr *addr,
                                                int type, int ifindex);
 
 /*
  *     multicast prototypes (mcast.c)
  */
-extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, 
-                 struct in6_addr *addr);
-extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, 
-                 struct in6_addr *addr);
+extern int ipv6_sock_mc_join(struct sock *sk, int ifindex,
+                            const struct in6_addr *addr);
+extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+                            const struct in6_addr *addr);
 extern void ipv6_sock_mc_close(struct sock *sk);
-extern int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr,
-               struct in6_addr *src_addr);
+extern int inet6_mc_check(struct sock *sk,
+                         const struct in6_addr *mc_addr,
+                         const struct in6_addr *src_addr);
 
-extern int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr);
-extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr);
-extern int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr);
+extern int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
+extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
+extern int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
 extern void ipv6_mc_up(struct inet6_dev *idev);
 extern void ipv6_mc_down(struct inet6_dev *idev);
 extern void ipv6_mc_init_dev(struct inet6_dev *idev);
 extern void ipv6_mc_destroy_dev(struct inet6_dev *idev);
 extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
 
-extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
-               struct in6_addr *src_addr);
+extern int ipv6_chk_mcast_addr(struct net_device *dev,
+                              const struct in6_addr *group,
+                              const struct in6_addr *src_addr);
 extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr);
 
 extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len);
@@ -133,7 +164,8 @@ extern int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex);
 
 extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr);
 extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr);
-extern int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr);
+extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
+                              struct in6_addr *addr);
 
 
 /* Device notifier */
@@ -183,26 +215,6 @@ static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
 #define in6_ifa_hold(ifp)      atomic_inc(&(ifp)->refcnt)
 
 
-extern void                    addrconf_forwarding_on(void);
-/*
- *     Hash function taken from net_alias.c
- */
-
-static __inline__ u8 ipv6_addr_hash(const struct in6_addr *addr)
-{      
-       __u32 word;
-
-       /* 
-        * We perform the hash function over the last 64 bits of the address
-        * This will include the IEEE address token on links that support it.
-        */
-
-       word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]);
-       word ^= (word >> 16);
-       word ^= (word >> 8);
-
-       return ((word ^ (word >> 4)) & 0x0f);
-}
 
 /*
  *     compute link-local solicited-node multicast address
@@ -217,17 +229,6 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
                      htonl(0xFF000000) | addr->s6_addr32[3]);
 }
 
-
-static inline void ipv6_addr_all_nodes(struct in6_addr *addr)
-{
-       ipv6_addr_set(addr, htonl(0xFF020000), 0, 0, htonl(0x1));
-}
-
-static inline void ipv6_addr_all_routers(struct in6_addr *addr)
-{
-       ipv6_addr_set(addr, htonl(0xFF020000), 0, 0, htonl(0x2));
-}
-
 static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
 {
        return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
@@ -235,34 +236,19 @@ static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
 
 static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
 {
-       return (addr->s6_addr32[0] == htonl(0xff020000) &&
-               addr->s6_addr32[1] == 0 &&
-               addr->s6_addr32[2] == 0 &&
-               addr->s6_addr32[3] == htonl(0x00000001));
+       return (((addr->s6_addr32[0] ^ htonl(0xff020000)) |
+               addr->s6_addr32[1] | addr->s6_addr32[2] |
+               (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0);
 }
 
 static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
 {
-       return (addr->s6_addr32[0] == htonl(0xff020000) &&
-               addr->s6_addr32[1] == 0 &&
-               addr->s6_addr32[2] == 0 &&
-               addr->s6_addr32[3] == htonl(0x00000002));
+       return (((addr->s6_addr32[0] ^ htonl(0xff020000)) |
+               addr->s6_addr32[1] | addr->s6_addr32[2] |
+               (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0);
 }
 
-static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
-{
-       eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
-                 ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
-                 ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
-                 ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) ||
-                 ipv4_is_test_198(addr) || ipv4_is_multicast(addr) ||
-                 ipv4_is_lbcast(addr)) ? 0x00 : 0x02;
-       eui[1] = 0;
-       eui[2] = 0x5E;
-       eui[3] = 0xFE;
-       memcpy (eui+4, &addr, 4);
-       return 0;
-}
+extern int __ipv6_isatap_ifid(u8 *eui, __be32 addr);
 
 static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
 {