| From 6a55410b0fac9eaa54f254784658f93468056654 Mon Sep 17 00:00:00 2001 |
| From: "fan.du" <fan.du@windriver.com> |
| Date: Sun, 1 Dec 2013 16:28:48 +0800 |
| Subject: {pktgen, xfrm} Update IPv4 header total len and checksum after tranformation |
| |
| From: "fan.du" <fan.du@windriver.com> |
| |
| [ Upstream commit 3868204d6b89ea373a273e760609cb08020beb1a ] |
| |
| commit a553e4a6317b2cfc7659542c10fe43184ffe53da ("[PKTGEN]: IPSEC support") |
| tried to support IPsec ESP transport transformation for pktgen, but acctually |
| this doesn't work at all for two reasons(The orignal transformed packet has |
| bad IPv4 checksum value, as well as wrong auth value, reported by wireshark) |
| |
| - After transpormation, IPv4 header total length needs update, |
| because encrypted payload's length is NOT same as that of plain text. |
| |
| - After transformation, IPv4 checksum needs re-caculate because of payload |
| has been changed. |
| |
| With this patch, armmed pktgen with below cofiguration, Wireshark is able to |
| decrypted ESP packet generated by pktgen without any IPv4 checksum error or |
| auth value error. |
| |
| pgset "flag IPSEC" |
| pgset "flows 1" |
| |
| Signed-off-by: Fan Du <fan.du@windriver.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/core/pktgen.c | 7 +++++++ |
| 1 file changed, 7 insertions(+) |
| |
| --- a/net/core/pktgen.c |
| +++ b/net/core/pktgen.c |
| @@ -2515,6 +2515,8 @@ static int process_ipsec(struct pktgen_d |
| if (x) { |
| int ret; |
| __u8 *eth; |
| + struct iphdr *iph; |
| + |
| nhead = x->props.header_len - skb_headroom(skb); |
| if (nhead > 0) { |
| ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); |
| @@ -2536,6 +2538,11 @@ static int process_ipsec(struct pktgen_d |
| eth = (__u8 *) skb_push(skb, ETH_HLEN); |
| memcpy(eth, pkt_dev->hh, 12); |
| *(u16 *) ð[12] = protocol; |
| + |
| + /* Update IPv4 header len as well as checksum value */ |
| + iph = ip_hdr(skb); |
| + iph->tot_len = htons(skb->len - ETH_HLEN); |
| + ip_send_check(iph); |
| } |
| } |
| return 1; |