Merge remote-tracking branches 'asoc/fix/tlv320aic3x' and 'asoc/fix/wm8962' into...
[linux-drm-fsl-dcu.git] / include / linux / skbuff.h
index 9b88536487e667b8727414e4131188db869711d4..4398411236f16c3f87691162909dc6197fb62b08 100644 (file)
@@ -37,6 +37,7 @@
 #include <net/flow_dissector.h>
 #include <linux/splice.h>
 #include <linux/in6.h>
+#include <net/flow.h>
 
 /* A. Checksumming of received packets by device.
  *
@@ -173,17 +174,24 @@ struct nf_bridge_info {
                BRNF_PROTO_8021Q,
                BRNF_PROTO_PPPOE
        } orig_proto:8;
-       bool                    pkt_otherhost;
+       u8                      pkt_otherhost:1;
+       u8                      in_prerouting:1;
+       u8                      bridged_dnat:1;
        __u16                   frag_max_size;
-       unsigned int            mask;
        struct net_device       *physindev;
+
+       /* always valid & non-NULL from FORWARD on, for physdev match */
+       struct net_device       *physoutdev;
        union {
-               struct net_device *physoutdev;
-               char neigh_header[8];
-       };
-       union {
+               /* prerouting: detect dnat in orig/reply direction */
                __be32          ipv4_daddr;
                struct in6_addr ipv6_daddr;
+
+               /* after prerouting + nat detected: store original source
+                * mac since neigh resolution overwrites it, only used while
+                * skb is out in neigh layer.
+                */
+               char neigh_header[8];
        };
 };
 #endif
@@ -506,6 +514,7 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1,
  *     @no_fcs:  Request NIC to treat last 4 bytes as Ethernet FCS
   *    @napi_id: id of the NAPI struct this skb came from
  *     @secmark: security marking
+ *     @offload_fwd_mark: fwding offload mark
  *     @mark: Generic packet mark
  *     @vlan_proto: vlan encapsulation protocol
  *     @vlan_tci: vlan tag control information
@@ -650,9 +659,15 @@ struct sk_buff {
                unsigned int    sender_cpu;
        };
 #endif
+       union {
 #ifdef CONFIG_NETWORK_SECMARK
-       __u32                   secmark;
+               __u32           secmark;
+#endif
+#ifdef CONFIG_NET_SWITCHDEV
+               __u32           offload_fwd_mark;
 #endif
+       };
+
        union {
                __u32           mark;
                __u32           reserved_tailroom;
@@ -922,14 +937,90 @@ enum pkt_hash_types {
        PKT_HASH_TYPE_L4,       /* Input: src_IP, dst_IP, src_port, dst_port */
 };
 
-static inline void
-skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type)
+static inline void skb_clear_hash(struct sk_buff *skb)
 {
-       skb->l4_hash = (type == PKT_HASH_TYPE_L4);
+       skb->hash = 0;
        skb->sw_hash = 0;
+       skb->l4_hash = 0;
+}
+
+static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb)
+{
+       if (!skb->l4_hash)
+               skb_clear_hash(skb);
+}
+
+static inline void
+__skb_set_hash(struct sk_buff *skb, __u32 hash, bool is_sw, bool is_l4)
+{
+       skb->l4_hash = is_l4;
+       skb->sw_hash = is_sw;
        skb->hash = hash;
 }
 
+static inline void
+skb_set_hash(struct sk_buff *skb, __u32 hash, enum pkt_hash_types type)
+{
+       /* Used by drivers to set hash from HW */
+       __skb_set_hash(skb, hash, false, type == PKT_HASH_TYPE_L4);
+}
+
+static inline void
+__skb_set_sw_hash(struct sk_buff *skb, __u32 hash, bool is_l4)
+{
+       __skb_set_hash(skb, hash, true, is_l4);
+}
+
+void __skb_get_hash(struct sk_buff *skb);
+u32 skb_get_poff(const struct sk_buff *skb);
+u32 __skb_get_poff(const struct sk_buff *skb, void *data,
+                  const struct flow_keys *keys, int hlen);
+__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
+                           void *data, int hlen_proto);
+
+static inline __be32 skb_flow_get_ports(const struct sk_buff *skb,
+                                       int thoff, u8 ip_proto)
+{
+       return __skb_flow_get_ports(skb, thoff, ip_proto, NULL, 0);
+}
+
+void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
+                            const struct flow_dissector_key *key,
+                            unsigned int key_count);
+
+bool __skb_flow_dissect(const struct sk_buff *skb,
+                       struct flow_dissector *flow_dissector,
+                       void *target_container,
+                       void *data, __be16 proto, int nhoff, int hlen,
+                       unsigned int flags);
+
+static inline bool skb_flow_dissect(const struct sk_buff *skb,
+                                   struct flow_dissector *flow_dissector,
+                                   void *target_container, unsigned int flags)
+{
+       return __skb_flow_dissect(skb, flow_dissector, target_container,
+                                 NULL, 0, 0, 0, flags);
+}
+
+static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb,
+                                             struct flow_keys *flow,
+                                             unsigned int flags)
+{
+       memset(flow, 0, sizeof(*flow));
+       return __skb_flow_dissect(skb, &flow_keys_dissector, flow,
+                                 NULL, 0, 0, 0, flags);
+}
+
+static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow,
+                                                 void *data, __be16 proto,
+                                                 int nhoff, int hlen,
+                                                 unsigned int flags)
+{
+       memset(flow, 0, sizeof(*flow));
+       return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow,
+                                 data, proto, nhoff, hlen, flags);
+}
+
 static inline __u32 skb_get_hash(struct sk_buff *skb)
 {
        if (!skb->l4_hash && !skb->sw_hash)
@@ -938,24 +1029,39 @@ static inline __u32 skb_get_hash(struct sk_buff *skb)
        return skb->hash;
 }
 
-__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb);
+__u32 __skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 *fl6);
 
-static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
+static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 *fl6)
 {
+       if (!skb->l4_hash && !skb->sw_hash) {
+               struct flow_keys keys;
+               __u32 hash = __get_hash_from_flowi6(fl6, &keys);
+
+               __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
+       }
+
        return skb->hash;
 }
 
-static inline void skb_clear_hash(struct sk_buff *skb)
+__u32 __skb_get_hash_flowi4(struct sk_buff *skb, const struct flowi4 *fl);
+
+static inline __u32 skb_get_hash_flowi4(struct sk_buff *skb, const struct flowi4 *fl4)
 {
-       skb->hash = 0;
-       skb->sw_hash = 0;
-       skb->l4_hash = 0;
+       if (!skb->l4_hash && !skb->sw_hash) {
+               struct flow_keys keys;
+               __u32 hash = __get_hash_from_flowi4(fl4, &keys);
+
+               __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
+       }
+
+       return skb->hash;
 }
 
-static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb)
+__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb);
+
+static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)
 {
-       if (!skb->l4_hash)
-               skb_clear_hash(skb);
+       return skb->hash;
 }
 
 static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from)
@@ -1943,7 +2049,7 @@ static inline void skb_probe_transport_header(struct sk_buff *skb,
 
        if (skb_transport_header_was_set(skb))
                return;
-       else if (skb_flow_dissect_flow_keys(skb, &keys))
+       else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
                skb_set_transport_header(skb, keys.control.thoff);
        else
                skb_set_transport_header(skb, offset_hint);
@@ -2601,6 +2707,9 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb,
 {
        if (skb->ip_summed == CHECKSUM_COMPLETE)
                skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0));
+       else if (skb->ip_summed == CHECKSUM_PARTIAL &&
+                skb_checksum_start_offset(skb) < 0)
+               skb->ip_summed = CHECKSUM_NONE;
 }
 
 unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
@@ -2667,12 +2776,6 @@ static inline void skb_frag_list_init(struct sk_buff *skb)
        skb_shinfo(skb)->frag_list = NULL;
 }
 
-static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)
-{
-       frag->next = skb_shinfo(skb)->frag_list;
-       skb_shinfo(skb)->frag_list = frag;
-}
-
 #define skb_walk_frags(skb, iter)      \
        for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
 
@@ -3464,5 +3567,6 @@ static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
                               skb_network_header(skb);
        return hdr_len + skb_gso_transport_seglen(skb);
 }
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SKBUFF_H */