|
@@ -617,7 +617,8 @@ struct sk_buff {
|
|
|
|
|
|
kmemcheck_bitfield_begin(flags3);
|
|
|
__u8 csum_level:2;
|
|
|
- /* 14 bit hole */
|
|
|
+ __u8 csum_bad:1;
|
|
|
+ /* 13 bit hole */
|
|
|
kmemcheck_bitfield_end(flags3);
|
|
|
|
|
|
__be16 inner_protocol;
|
|
@@ -2825,6 +2826,21 @@ static inline void __skb_incr_checksum_unnecessary(struct sk_buff *skb)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static inline void __skb_mark_checksum_bad(struct sk_buff *skb)
|
|
|
+{
|
|
|
+ /* Mark current checksum as bad (typically called from GRO
|
|
|
+ * path). In the case that ip_summed is CHECKSUM_NONE
|
|
|
+ * this must be the first checksum encountered in the packet.
|
|
|
+ * When ip_summed is CHECKSUM_UNNECESSARY, this is the first
|
|
|
+ * checksum after the last one validated. For UDP, a zero
|
|
|
+ * checksum can not be marked as bad.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (skb->ip_summed == CHECKSUM_NONE ||
|
|
|
+ skb->ip_summed == CHECKSUM_UNNECESSARY)
|
|
|
+ skb->csum_bad = 1;
|
|
|
+}
|
|
|
+
|
|
|
/* Check if we need to perform checksum complete validation.
|
|
|
*
|
|
|
* Returns true if checksum complete is needed, false otherwise
|
|
@@ -2866,6 +2882,9 @@ static inline __sum16 __skb_checksum_validate_complete(struct sk_buff *skb,
|
|
|
skb->csum_valid = 1;
|
|
|
return 0;
|
|
|
}
|
|
|
+ } else if (skb->csum_bad) {
|
|
|
+ /* ip_summed == CHECKSUM_NONE in this case */
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
skb->csum = psum;
|