Merge branch 'overlayfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszere...
[firefly-linux-kernel-4.4.55.git] / include / linux / skbuff.h
index b349c96dc80a2921398fd4c8252f8afde8b25b65..30007afe70b3541cdb4300919c2a5cfbbc0063f2 100644 (file)
  *
  * CHECKSUM_PARTIAL:
  *
- *   This is identical to the case for output below. This may occur on a packet
+ *   A checksum is set up to be offloaded to a device as described in the
+ *   output description for CHECKSUM_PARTIAL. This may occur on a packet
  *   received directly from another Linux OS, e.g., a virtualized Linux kernel
- *   on the same host. The packet can be treated in the same way as
- *   CHECKSUM_UNNECESSARY, except that on output (i.e., forwarding) the
- *   checksum must be filled in by the OS or the hardware.
+ *   on the same host, or it may be set in the input path in GRO or remote
+ *   checksum offload. For the purposes of checksum verification, the checksum
+ *   referred to by skb->csum_start + skb->csum_offset and any preceding
+ *   checksums in the packet are considered verified. Any checksums in the
+ *   packet that are after the checksum being offloaded are not considered to
+ *   be verified.
  *
  * B. Checksumming on output.
  *
@@ -626,8 +630,11 @@ struct sk_buff {
        __u32                   hash;
        __be16                  vlan_proto;
        __u16                   vlan_tci;
-#ifdef CONFIG_NET_RX_BUSY_POLL
-       unsigned int    napi_id;
+#if defined(CONFIG_NET_RX_BUSY_POLL) || defined(CONFIG_XPS)
+       union {
+               unsigned int    napi_id;
+               unsigned int    sender_cpu;
+       };
 #endif
 #ifdef CONFIG_NETWORK_SECMARK
        __u32                   secmark;
@@ -2912,7 +2919,10 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
 static inline int skb_csum_unnecessary(const struct sk_buff *skb)
 {
-       return ((skb->ip_summed & CHECKSUM_UNNECESSARY) || skb->csum_valid);
+       return ((skb->ip_summed == CHECKSUM_UNNECESSARY) ||
+               skb->csum_valid ||
+               (skb->ip_summed == CHECKSUM_PARTIAL &&
+                skb_checksum_start_offset(skb) >= 0));
 }
 
 /**
@@ -3069,7 +3079,7 @@ static inline __wsum null_compute_pseudo(struct sk_buff *skb, int proto)
 
 #define skb_checksum_validate_zero_check(skb, proto, check,            \
                                         compute_pseudo)                \
-       __skb_checksum_validate_(skb, proto, true, true, check, compute_pseudo)
+       __skb_checksum_validate(skb, proto, true, true, check, compute_pseudo)
 
 #define skb_checksum_simple_validate(skb)                              \
        __skb_checksum_validate(skb, 0, true, false, 0, null_compute_pseudo)
@@ -3094,6 +3104,40 @@ do {                                                                     \
                                       compute_pseudo(skb, proto));     \
 } while (0)
 
+static inline void skb_remcsum_adjust_partial(struct sk_buff *skb, void *ptr,
+                                             u16 start, u16 offset)
+{
+       skb->ip_summed = CHECKSUM_PARTIAL;
+       skb->csum_start = ((unsigned char *)ptr + start) - skb->head;
+       skb->csum_offset = offset - start;
+}
+
+/* Update skbuf and packet to reflect the remote checksum offload operation.
+ * When called, ptr indicates the starting point for skb->csum when
+ * ip_summed is CHECKSUM_COMPLETE. If we need create checksum complete
+ * here, skb_postpull_rcsum is done so skb->csum start is ptr.
+ */
+static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
+                                      int start, int offset, bool nopartial)
+{
+       __wsum delta;
+
+       if (!nopartial) {
+               skb_remcsum_adjust_partial(skb, ptr, start, offset);
+               return;
+       }
+
+        if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
+               __skb_checksum_complete(skb);
+               skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
+       }
+
+       delta = remcsum_adjust(ptr, skb->csum, start, offset);
+
+       /* Adjust skb->csum since we changed the packet */
+       skb->csum = csum_add(skb->csum, delta);
+}
+
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 void nf_conntrack_destroy(struct nf_conntrack *nfct);
 static inline void nf_conntrack_put(struct nf_conntrack *nfct)