Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[firefly-linux-kernel-4.4.55.git] / include / net / ipv6.h
index 574337fe72ddbd3038c061dab5aef142ea0f068b..a2db816e8461cff706f23c725cf69372ab8bfcaa 100644 (file)
@@ -19,6 +19,7 @@
 #include <net/if_inet6.h>
 #include <net/ndisc.h>
 #include <net/flow.h>
+#include <net/flow_keys.h>
 #include <net/snmp.h>
 
 #define SIN6_LEN_RFC2133       24
@@ -298,11 +299,6 @@ static inline bool ipv6_accept_ra(struct inet6_dev *idev)
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
-static inline int ip6_frag_nqueues(struct net *net)
-{
-       return net->ipv6.frags.nqueues;
-}
-
 static inline int ip6_frag_mem(struct net *net)
 {
        return sum_frag_mem_limit(&net->ipv6.frags);
@@ -495,8 +491,8 @@ struct ip6_create_arg {
        u8 ecn;
 };
 
-void ip6_frag_init(struct inet_frag_queue *q, void *a);
-bool ip6_frag_match(struct inet_frag_queue *q, void *a);
+void ip6_frag_init(struct inet_frag_queue *q, const void *a);
+bool ip6_frag_match(const struct inet_frag_queue *q, const void *a);
 
 /*
  *     Equivalent of ipv4 struct ip
@@ -557,24 +553,29 @@ static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
 static inline bool ipv6_addr_loopback(const struct in6_addr *a)
 {
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
-       const unsigned long *ul = (const unsigned long *)a;
+       const __be64 *be = (const __be64 *)a;
 
-       return (ul[0] | (ul[1] ^ cpu_to_be64(1))) == 0UL;
+       return (be[0] | (be[1] ^ cpu_to_be64(1))) == 0UL;
 #else
        return (a->s6_addr32[0] | a->s6_addr32[1] |
-               a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0;
+               a->s6_addr32[2] | (a->s6_addr32[3] ^ cpu_to_be32(1))) == 0;
 #endif
 }
 
+/*
+ * Note that we must __force cast these to unsigned long to make sparse happy,
+ * since all of the endian-annotated types are fixed size regardless of arch.
+ */
 static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
 {
        return (
 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
-               *(__be64 *)a |
+               *(unsigned long *)a |
 #else
-               (a->s6_addr32[0] | a->s6_addr32[1]) |
+               (__force unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
 #endif
-               (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
+               (__force unsigned long)(a->s6_addr32[2] ^
+                                       cpu_to_be32(0x0000ffff))) == 0UL;
 }
 
 /*
@@ -684,6 +685,50 @@ static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
        return hlimit;
 }
 
+#if IS_ENABLED(CONFIG_IPV6)
+static inline void ip6_set_txhash(struct sock *sk)
+{
+       struct inet_sock *inet = inet_sk(sk);
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct flow_keys keys;
+
+       keys.src = (__force __be32)ipv6_addr_hash(&np->saddr);
+       keys.dst = (__force __be32)ipv6_addr_hash(&sk->sk_v6_daddr);
+       keys.port16[0] = inet->inet_sport;
+       keys.port16[1] = inet->inet_dport;
+
+       sk->sk_txhash = flow_hash_from_keys(&keys);
+}
+
+static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
+                                       __be32 flowlabel, bool autolabel)
+{
+       if (!flowlabel && (autolabel || net->ipv6.sysctl.auto_flowlabels)) {
+               __be32 hash;
+
+               hash = skb_get_hash(skb);
+
+               /* Since this is being sent on the wire obfuscate hash a bit
+                * to minimize possbility that any useful information to an
+                * attacker is leaked. Only lower 20 bits are relevant.
+                */
+               hash ^= hash >> 12;
+
+               flowlabel = hash & IPV6_FLOWLABEL_MASK;
+       }
+
+       return flowlabel;
+}
+#else
+static inline void ip6_set_txhash(struct sock *sk) { }
+static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
+                                       __be32 flowlabel, bool autolabel)
+{
+       return flowlabel;
+}
+#endif
+
+
 /*
  *     Header manipulation
  */