usb: quirks: add control message delay for 1b1c:1b20
[pandora-kernel.git] / include / net / ipv6.h
index a366a8a..25f0491 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/ipv6.h>
 #include <linux/hardirq.h>
+#include <linux/jhash.h>
 #include <net/if_inet6.h>
 #include <net/ndisc.h>
 #include <net/flow.h>
@@ -190,6 +191,7 @@ extern rwlock_t ip6_ra_lock;
  */
 
 struct ipv6_txoptions {
+       atomic_t                refcnt;
        /* Length of this structure */
        int                     tot_len;
 
@@ -202,7 +204,7 @@ struct ipv6_txoptions {
        struct ipv6_opt_hdr     *dst0opt;
        struct ipv6_rt_hdr      *srcrt; /* Routing Header */
        struct ipv6_opt_hdr     *dst1opt;
-
+       struct rcu_head         rcu;
        /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
 };
 
@@ -228,6 +230,24 @@ struct ipv6_fl_socklist {
        struct ip6_flowlabel    *fl;
 };
 
+static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
+{
+       struct ipv6_txoptions *opt;
+
+       rcu_read_lock();
+       opt = rcu_dereference(np->opt);
+       if (opt && !atomic_inc_not_zero(&opt->refcnt))
+               opt = NULL;
+       rcu_read_unlock();
+       return opt;
+}
+
+static inline void txopt_put(struct ipv6_txoptions *opt)
+{
+       if (opt && atomic_dec_and_test(&opt->refcnt))
+               kfree_rcu(opt, rcu);
+}
+
 extern struct ip6_flowlabel    *fl6_sock_lookup(struct sock *sk, __be32 label);
 extern struct ipv6_txoptions   *fl6_merge_options(struct ipv6_txoptions * opt_space,
                                                   struct ip6_flowlabel * fl,
@@ -381,11 +401,28 @@ struct ip6_create_arg {
        u32 user;
        const struct in6_addr *src;
        const struct in6_addr *dst;
+       int iif;
 };
 
 void ip6_frag_init(struct inet_frag_queue *q, void *a);
 int ip6_frag_match(struct inet_frag_queue *q, void *a);
 
+/* more secured version of ipv6_addr_hash() */
+static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
+{
+       u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];
+
+       return jhash_3words(v,
+                           (__force u32)a->s6_addr32[2],
+                           (__force u32)a->s6_addr32[3],
+                           initval);
+}
+
+static inline u32 ipv6_addr_jhash(const struct in6_addr *a)
+{
+       return __ipv6_addr_jhash(a, ipv6_hash_secret);
+}
+
 static inline int ipv6_addr_any(const struct in6_addr *a)
 {
        return (a->s6_addr32[0] | a->s6_addr32[1] |
@@ -464,6 +501,7 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
 }
 
 extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);
+void ipv6_proxy_select_ident(struct sk_buff *skb);
 
 /*
  *     Prototypes exported by ipv6
@@ -590,8 +628,10 @@ extern int                 compat_ipv6_getsockopt(struct sock *sk,
 extern int                     ip6_datagram_connect(struct sock *sk, 
                                                     struct sockaddr *addr, int addr_len);
 
-extern int                     ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
-extern int                     ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
+extern int                     ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+                                               int *addr_len);
+extern int                     ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
+                                                int *addr_len);
 extern void                    ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
                                                u32 info, u8 *payload);
 extern void                    ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);