diff options
-rw-r--r-- | include/net/xfrm.h | 6 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_beet.c | 11 | ||||
-rw-r--r-- | net/ipv4/xfrm4_state.c | 2 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_beet.c | 1 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 2 |
5 files changed, 16 insertions, 6 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 4e6f9568cbe7..0d255ae008b6 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -552,6 +552,9 @@ struct xfrm_mode_skb_cb { | |||
552 | __be16 id; | 552 | __be16 id; |
553 | __be16 frag_off; | 553 | __be16 frag_off; |
554 | 554 | ||
555 | /* IP header length (excluding options or extension headers). */ | ||
556 | u8 ihl; | ||
557 | |||
555 | /* TOS for IPv4, class for IPv6. */ | 558 | /* TOS for IPv4, class for IPv6. */ |
556 | u8 tos; | 559 | u8 tos; |
557 | 560 | ||
@@ -561,6 +564,9 @@ struct xfrm_mode_skb_cb { | |||
561 | /* Protocol for IPv4, NH for IPv6. */ | 564 | /* Protocol for IPv4, NH for IPv6. */ |
562 | u8 protocol; | 565 | u8 protocol; |
563 | 566 | ||
567 | /* Option length for IPv4, zero for IPv6. */ | ||
568 | u8 optlen; | ||
569 | |||
564 | /* Used by IPv6 only, zero for IPv4. */ | 570 | /* Used by IPv6 only, zero for IPv4. */ |
565 | u8 flow_lbl[3]; | 571 | u8 flow_lbl[3]; |
566 | }; | 572 | }; |
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index b47030ba162b..9c798abce736 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c | |||
@@ -39,13 +39,11 @@ static void xfrm4_beet_make_header(struct sk_buff *skb) | |||
39 | static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | 39 | static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
40 | { | 40 | { |
41 | struct ip_beet_phdr *ph; | 41 | struct ip_beet_phdr *ph; |
42 | struct iphdr *iph, *top_iph; | 42 | struct iphdr *top_iph; |
43 | int hdrlen, optlen; | 43 | int hdrlen, optlen; |
44 | 44 | ||
45 | iph = ip_hdr(skb); | ||
46 | |||
47 | hdrlen = 0; | 45 | hdrlen = 0; |
48 | optlen = iph->ihl * 4 - sizeof(*iph); | 46 | optlen = XFRM_MODE_SKB_CB(skb)->optlen; |
49 | if (unlikely(optlen)) | 47 | if (unlikely(optlen)) |
50 | hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4); | 48 | hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4); |
51 | 49 | ||
@@ -53,11 +51,12 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
53 | hdrlen); | 51 | hdrlen); |
54 | skb->mac_header = skb->network_header + | 52 | skb->mac_header = skb->network_header + |
55 | offsetof(struct iphdr, protocol); | 53 | offsetof(struct iphdr, protocol); |
56 | skb->transport_header = skb->network_header + sizeof(*iph); | 54 | skb->transport_header = skb->network_header + sizeof(*top_iph); |
57 | 55 | ||
58 | xfrm4_beet_make_header(skb); | 56 | xfrm4_beet_make_header(skb); |
59 | 57 | ||
60 | ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen); | 58 | ph = (struct ip_beet_phdr *) |
59 | __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdrlen); | ||
61 | 60 | ||
62 | top_iph = ip_hdr(skb); | 61 | top_iph = ip_hdr(skb); |
63 | 62 | ||
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index fdeebe68a379..07735ed280d7 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
@@ -52,10 +52,12 @@ int xfrm4_extract_header(struct sk_buff *skb) | |||
52 | { | 52 | { |
53 | struct iphdr *iph = ip_hdr(skb); | 53 | struct iphdr *iph = ip_hdr(skb); |
54 | 54 | ||
55 | XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); | ||
55 | XFRM_MODE_SKB_CB(skb)->id = iph->id; | 56 | XFRM_MODE_SKB_CB(skb)->id = iph->id; |
56 | XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off; | 57 | XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off; |
57 | XFRM_MODE_SKB_CB(skb)->tos = iph->tos; | 58 | XFRM_MODE_SKB_CB(skb)->tos = iph->tos; |
58 | XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl; | 59 | XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl; |
60 | XFRM_MODE_SKB_CB(skb)->optlen = iph->ihl * 4 - sizeof(*iph); | ||
59 | memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0, | 61 | memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0, |
60 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); | 62 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); |
61 | 63 | ||
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index 0527d11c1ae3..d6ce400f585f 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
@@ -45,6 +45,7 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
45 | skb->mac_header = skb->network_header + | 45 | skb->mac_header = skb->network_header + |
46 | offsetof(struct ipv6hdr, nexthdr); | 46 | offsetof(struct ipv6hdr, nexthdr); |
47 | skb->transport_header = skb->network_header + sizeof(*top_iph); | 47 | skb->transport_header = skb->network_header + sizeof(*top_iph); |
48 | __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl); | ||
48 | 49 | ||
49 | xfrm6_beet_make_header(skb); | 50 | xfrm6_beet_make_header(skb); |
50 | 51 | ||
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index dc817e035e23..ff1e1db8e236 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -174,10 +174,12 @@ int xfrm6_extract_header(struct sk_buff *skb) | |||
174 | { | 174 | { |
175 | struct ipv6hdr *iph = ipv6_hdr(skb); | 175 | struct ipv6hdr *iph = ipv6_hdr(skb); |
176 | 176 | ||
177 | XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); | ||
177 | XFRM_MODE_SKB_CB(skb)->id = 0; | 178 | XFRM_MODE_SKB_CB(skb)->id = 0; |
178 | XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); | 179 | XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); |
179 | XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); | 180 | XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); |
180 | XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; | 181 | XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; |
182 | XFRM_MODE_SKB_CB(skb)->optlen = 0; | ||
181 | memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, | 183 | memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, |
182 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); | 184 | sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); |
183 | 185 | ||