summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorLi RongQing <roy.qing.li@gmail.com>2013-01-08 15:41:12 +0800
committerSteffen Klassert <steffen.klassert@secunet.com>2013-01-08 12:41:30 +0100
commita9403f8aeb3e7dba6988d6cbe436e6521894e427 (patch)
tree5dda4e7fde169a8ffba69b24bd4487b249529062 /net
parent7143dfac692cd25d48a24dbe8323bc17af95b4ec (diff)
downloadlinux-3.10-a9403f8aeb3e7dba6988d6cbe436e6521894e427.tar.gz
linux-3.10-a9403f8aeb3e7dba6988d6cbe436e6521894e427.tar.bz2
linux-3.10-a9403f8aeb3e7dba6988d6cbe436e6521894e427.zip
ah6/esp6: set transport header correctly for IPsec tunnel mode.
IPsec tunnel does not set ECN field to CE in inner header when the ECN field in the outer header is CE, and the ECN field in the inner header is ECT(0) or ECT(1). The cause is ipip6_hdr() does not return the correct address of inner header since skb->transport-header is not the inner header after esp6_input_done2(), or ah6_input(). Signed-off-by: Li RongQing <roy.qing.li@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/ah6.c11
-rw-r--r--net/ipv6/esp6.c5
2 files changed, 13 insertions, 3 deletions
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index ecc35b93314..384233188ac 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -472,7 +472,10 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
skb->network_header += ah_hlen;
memcpy(skb_network_header(skb), work_iph, hdr_len);
__skb_pull(skb, ah_hlen + hdr_len);
- skb_set_transport_header(skb, -hdr_len);
+ if (x->props.mode == XFRM_MODE_TUNNEL)
+ skb_reset_transport_header(skb);
+ else
+ skb_set_transport_header(skb, -hdr_len);
out:
kfree(AH_SKB_CB(skb)->tmp);
xfrm_input_resume(skb, err);
@@ -593,9 +596,13 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
skb->network_header += ah_hlen;
memcpy(skb_network_header(skb), work_iph, hdr_len);
- skb->transport_header = skb->network_header;
__skb_pull(skb, ah_hlen + hdr_len);
+ if (x->props.mode == XFRM_MODE_TUNNEL)
+ skb_reset_transport_header(skb);
+ else
+ skb_set_transport_header(skb, -hdr_len);
+
err = nexthdr;
out_free:
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 282f3723ee1..40ffd72243a 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -300,7 +300,10 @@ static int esp_input_done2(struct sk_buff *skb, int err)
pskb_trim(skb, skb->len - alen - padlen - 2);
__skb_pull(skb, hlen);
- skb_set_transport_header(skb, -hdr_len);
+ if (x->props.mode == XFRM_MODE_TUNNEL)
+ skb_reset_transport_header(skb);
+ else
+ skb_set_transport_header(skb, -hdr_len);
err = nexthdr[1];