diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2016-06-30 13:15:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-01 16:19:34 -0400 |
commit | 82a31b9231f02d9c1b7b290a46999d517b0d312a (patch) | |
tree | 1da59e437a0c406de78f8d60e2d9a6f880033c6f | |
parent | eb70db8756717b90c01ccc765fdefc4dd969fc74 (diff) |
net_sched: fix mirrored packets checksum
Similar to commit 9b368814b336 ("net: fix bridge multicast packet checksum validation")
we need to fixup the checksum for CHECKSUM_COMPLETE when
pushing skb on RX path. Otherwise we get similar splats.
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Tom Herbert <tom@herbertland.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/skbuff.h | 19 | ||||
-rw-r--r-- | net/core/skbuff.c | 18 | ||||
-rw-r--r-- | net/sched/act_mirred.c | 2 |
3 files changed, 20 insertions, 19 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 24859d40acde..f39b37180c41 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -2871,6 +2871,25 @@ static inline void skb_postpush_rcsum(struct sk_buff *skb, | |||
2871 | } | 2871 | } |
2872 | 2872 | ||
2873 | /** | 2873 | /** |
2874 | * skb_push_rcsum - push skb and update receive checksum | ||
2875 | * @skb: buffer to update | ||
2876 | * @len: length of data pulled | ||
2877 | * | ||
2878 | * This function performs an skb_push on the packet and updates | ||
2879 | * the CHECKSUM_COMPLETE checksum. It should be used on | ||
2880 | * receive path processing instead of skb_push unless you know | ||
2881 | * that the checksum difference is zero (e.g., a valid IP header) | ||
2882 | * or you are setting ip_summed to CHECKSUM_NONE. | ||
2883 | */ | ||
2884 | static inline unsigned char *skb_push_rcsum(struct sk_buff *skb, | ||
2885 | unsigned int len) | ||
2886 | { | ||
2887 | skb_push(skb, len); | ||
2888 | skb_postpush_rcsum(skb, skb->data, len); | ||
2889 | return skb->data; | ||
2890 | } | ||
2891 | |||
2892 | /** | ||
2874 | * pskb_trim_rcsum - trim received skb and update checksum | 2893 | * pskb_trim_rcsum - trim received skb and update checksum |
2875 | * @skb: buffer to trim | 2894 | * @skb: buffer to trim |
2876 | * @len: new length | 2895 | * @len: new length |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f2b77e549c03..eb12d2161fb2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3016,24 +3016,6 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page, | |||
3016 | EXPORT_SYMBOL_GPL(skb_append_pagefrags); | 3016 | EXPORT_SYMBOL_GPL(skb_append_pagefrags); |
3017 | 3017 | ||
3018 | /** | 3018 | /** |
3019 | * skb_push_rcsum - push skb and update receive checksum | ||
3020 | * @skb: buffer to update | ||
3021 | * @len: length of data pulled | ||
3022 | * | ||
3023 | * This function performs an skb_push on the packet and updates | ||
3024 | * the CHECKSUM_COMPLETE checksum. It should be used on | ||
3025 | * receive path processing instead of skb_push unless you know | ||
3026 | * that the checksum difference is zero (e.g., a valid IP header) | ||
3027 | * or you are setting ip_summed to CHECKSUM_NONE. | ||
3028 | */ | ||
3029 | static unsigned char *skb_push_rcsum(struct sk_buff *skb, unsigned len) | ||
3030 | { | ||
3031 | skb_push(skb, len); | ||
3032 | skb_postpush_rcsum(skb, skb->data, len); | ||
3033 | return skb->data; | ||
3034 | } | ||
3035 | |||
3036 | /** | ||
3037 | * skb_pull_rcsum - pull skb and update receive checksum | 3019 | * skb_pull_rcsum - pull skb and update receive checksum |
3038 | * @skb: buffer to update | 3020 | * @skb: buffer to update |
3039 | * @len: length of data pulled | 3021 | * @len: length of data pulled |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 128942bc9e42..1f5bd6ccbd2c 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -181,7 +181,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | |||
181 | 181 | ||
182 | if (!(at & AT_EGRESS)) { | 182 | if (!(at & AT_EGRESS)) { |
183 | if (m->tcfm_ok_push) | 183 | if (m->tcfm_ok_push) |
184 | skb_push(skb2, skb->mac_len); | 184 | skb_push_rcsum(skb2, skb->mac_len); |
185 | } | 185 | } |
186 | 186 | ||
187 | /* mirror is always swallowed */ | 187 | /* mirror is always swallowed */ |