diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-10-10 18:44:44 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:55:54 -0400 |
commit | 37fedd3aab6517daec628764c5d66dd8761fbe5f (patch) | |
tree | 12227aec3944168bff04173dccd580240f4496aa | |
parent | 7b277b1a5fb147cb828e5d8b9780cee60f31a9bf (diff) |
[IPSEC]: Use IPv6 calling convention as the convention for x->mode->output
The IPv6 calling convention for x->mode->output is more general and could
help an eventual protocol-generic x->type->output implementation. This
patch adopts it for IPv4 as well and modifies the IPv4 type output functions
accordingly.
It also rewrites the IPv6 mac/transport header calculation to be based off
the network header where practical.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/xfrm.h | 12 | ||||
-rw-r--r-- | net/ipv4/ah4.c | 6 | ||||
-rw-r--r-- | net/ipv4/esp4.c | 11 | ||||
-rw-r--r-- | net/ipv4/ipcomp.c | 10 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_beet.c | 17 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_transport.c | 7 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_tunnel.c | 7 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_beet.c | 9 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_ro.c | 9 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_transport.c | 9 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 14 |
11 files changed, 44 insertions, 67 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 1c116dc03e0e..77be396ca633 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -300,6 +300,18 @@ extern void xfrm_put_type(struct xfrm_type *type); | |||
300 | 300 | ||
301 | struct xfrm_mode { | 301 | struct xfrm_mode { |
302 | int (*input)(struct xfrm_state *x, struct sk_buff *skb); | 302 | int (*input)(struct xfrm_state *x, struct sk_buff *skb); |
303 | |||
304 | /* | ||
305 | * Add encapsulation header. | ||
306 | * | ||
307 | * On exit, the transport header will be set to the start of the | ||
308 | * encapsulation header to be filled in by x->type->output and | ||
309 | * the mac header will be set to the nextheader (protocol for | ||
310 | * IPv4) field of the extension header directly preceding the | ||
311 | * encapsulation header, or in its absence, that of the top IP | ||
312 | * header. The value of the network header will always point | ||
313 | * to the top IP header while skb->data will point to the payload. | ||
314 | */ | ||
303 | int (*output)(struct xfrm_state *x,struct sk_buff *skb); | 315 | int (*output)(struct xfrm_state *x,struct sk_buff *skb); |
304 | 316 | ||
305 | struct module *owner; | 317 | struct module *owner; |
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index dbb1f11721e4..e4f7aa39978d 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -82,14 +82,14 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) | |||
82 | goto error; | 82 | goto error; |
83 | } | 83 | } |
84 | 84 | ||
85 | ah = (struct ip_auth_hdr *)((char *)top_iph+top_iph->ihl*4); | 85 | ah = (struct ip_auth_hdr *)skb_transport_header(skb); |
86 | ah->nexthdr = top_iph->protocol; | 86 | ah->nexthdr = *skb_mac_header(skb); |
87 | *skb_mac_header(skb) = IPPROTO_AH; | ||
87 | 88 | ||
88 | top_iph->tos = 0; | 89 | top_iph->tos = 0; |
89 | top_iph->tot_len = htons(skb->len); | 90 | top_iph->tot_len = htons(skb->len); |
90 | top_iph->frag_off = 0; | 91 | top_iph->frag_off = 0; |
91 | top_iph->ttl = 0; | 92 | top_iph->ttl = 0; |
92 | top_iph->protocol = IPPROTO_AH; | ||
93 | top_iph->check = 0; | 93 | top_iph->check = 0; |
94 | 94 | ||
95 | ahp = x->data; | 95 | ahp = x->data; |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 0f5e8387ccb4..93153d105619 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -60,10 +60,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
60 | 60 | ||
61 | skb_push(skb, -skb_network_offset(skb)); | 61 | skb_push(skb, -skb_network_offset(skb)); |
62 | top_iph = ip_hdr(skb); | 62 | top_iph = ip_hdr(skb); |
63 | esph = (struct ip_esp_hdr *)(skb_network_header(skb) + | 63 | esph = (struct ip_esp_hdr *)skb_transport_header(skb); |
64 | top_iph->ihl * 4); | ||
65 | top_iph->tot_len = htons(skb->len + alen); | 64 | top_iph->tot_len = htons(skb->len + alen); |
66 | *(skb_tail_pointer(trailer) - 1) = top_iph->protocol; | 65 | *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); |
66 | *skb_mac_header(skb) = IPPROTO_ESP; | ||
67 | 67 | ||
68 | spin_lock_bh(&x->lock); | 68 | spin_lock_bh(&x->lock); |
69 | 69 | ||
@@ -91,9 +91,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
91 | break; | 91 | break; |
92 | } | 92 | } |
93 | 93 | ||
94 | top_iph->protocol = IPPROTO_UDP; | 94 | *skb_mac_header(skb) = IPPROTO_UDP; |
95 | } else | 95 | } |
96 | top_iph->protocol = IPPROTO_ESP; | ||
97 | 96 | ||
98 | esph->spi = x->id.spi; | 97 | esph->spi = x->id.spi; |
99 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); | 98 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 1929d451dab5..bf74f64fe5fb 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -98,10 +98,10 @@ out: | |||
98 | static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) | 98 | static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) |
99 | { | 99 | { |
100 | struct ipcomp_data *ipcd = x->data; | 100 | struct ipcomp_data *ipcd = x->data; |
101 | const int ihlen = ip_hdrlen(skb); | 101 | const int ihlen = skb_transport_offset(skb); |
102 | const int plen = skb->len - ihlen; | 102 | const int plen = skb->len - ihlen; |
103 | int dlen = IPCOMP_SCRATCH_SIZE; | 103 | int dlen = IPCOMP_SCRATCH_SIZE; |
104 | u8 *start = skb->data + ihlen; | 104 | u8 *start = skb_transport_header(skb); |
105 | const int cpu = get_cpu(); | 105 | const int cpu = get_cpu(); |
106 | u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); | 106 | u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); |
107 | struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); | 107 | struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); |
@@ -154,11 +154,11 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
154 | 154 | ||
155 | /* Install ipcomp header, convert into ipcomp datagram. */ | 155 | /* Install ipcomp header, convert into ipcomp datagram. */ |
156 | iph->tot_len = htons(skb->len); | 156 | iph->tot_len = htons(skb->len); |
157 | ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4); | 157 | ipch = (struct ip_comp_hdr *)skb_transport_header(skb); |
158 | ipch->nexthdr = iph->protocol; | 158 | ipch->nexthdr = *skb_mac_header(skb); |
159 | ipch->flags = 0; | 159 | ipch->flags = 0; |
160 | ipch->cpi = htons((u16 )ntohl(x->id.spi)); | 160 | ipch->cpi = htons((u16 )ntohl(x->id.spi)); |
161 | iph->protocol = IPPROTO_COMP; | 161 | *skb_mac_header(skb) = IPPROTO_COMP; |
162 | ip_send_check(iph); | 162 | ip_send_check(iph); |
163 | return 0; | 163 | return 0; |
164 | 164 | ||
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index 77888f596737..7226c6486c01 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c | |||
@@ -23,17 +23,14 @@ | |||
23 | * The following fields in it shall be filled in by x->type->output: | 23 | * The following fields in it shall be filled in by x->type->output: |
24 | * tot_len | 24 | * tot_len |
25 | * check | 25 | * check |
26 | * | ||
27 | * On exit, skb->h will be set to the start of the payload to be processed | ||
28 | * by x->type->output and skb->nh will be set to the top IP header. | ||
29 | */ | 26 | */ |
30 | static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | 27 | static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
31 | { | 28 | { |
29 | struct ip_beet_phdr *ph; | ||
32 | struct iphdr *iph, *top_iph; | 30 | struct iphdr *iph, *top_iph; |
33 | int hdrlen, optlen; | 31 | int hdrlen, optlen; |
34 | 32 | ||
35 | iph = ip_hdr(skb); | 33 | iph = ip_hdr(skb); |
36 | skb->transport_header = skb->network_header; | ||
37 | 34 | ||
38 | hdrlen = 0; | 35 | hdrlen = 0; |
39 | optlen = iph->ihl * 4 - sizeof(*iph); | 36 | optlen = iph->ihl * 4 - sizeof(*iph); |
@@ -42,17 +39,17 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
42 | 39 | ||
43 | skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len - | 40 | skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x->props.header_len - |
44 | hdrlen); | 41 | hdrlen); |
45 | top_iph = ip_hdr(skb); | 42 | skb->mac_header = skb->network_header + |
46 | skb->transport_header += sizeof(*iph) - hdrlen; | 43 | offsetof(struct iphdr, protocol); |
47 | __skb_pull(skb, sizeof(*iph) - hdrlen); | 44 | skb->transport_header = skb->network_header + sizeof(*iph); |
45 | |||
46 | ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen); | ||
48 | 47 | ||
48 | top_iph = ip_hdr(skb); | ||
49 | memmove(top_iph, iph, sizeof(*iph)); | 49 | memmove(top_iph, iph, sizeof(*iph)); |
50 | if (unlikely(optlen)) { | 50 | if (unlikely(optlen)) { |
51 | struct ip_beet_phdr *ph; | ||
52 | |||
53 | BUG_ON(optlen < 0); | 51 | BUG_ON(optlen < 0); |
54 | 52 | ||
55 | ph = (struct ip_beet_phdr *)skb_transport_header(skb); | ||
56 | ph->padlen = 4 - (optlen & 4); | 53 | ph->padlen = 4 - (optlen & 4); |
57 | ph->hdrlen = optlen / 8; | 54 | ph->hdrlen = optlen / 8; |
58 | ph->nexthdr = top_iph->protocol; | 55 | ph->nexthdr = top_iph->protocol; |
diff --git a/net/ipv4/xfrm4_mode_transport.c b/net/ipv4/xfrm4_mode_transport.c index 10499d2ec65e..fd840c7d75ea 100644 --- a/net/ipv4/xfrm4_mode_transport.c +++ b/net/ipv4/xfrm4_mode_transport.c | |||
@@ -17,17 +17,16 @@ | |||
17 | * | 17 | * |
18 | * The IP header will be moved forward to make space for the encapsulation | 18 | * The IP header will be moved forward to make space for the encapsulation |
19 | * header. | 19 | * header. |
20 | * | ||
21 | * On exit, skb->h will be set to the start of the payload to be processed | ||
22 | * by x->type->output and skb->nh will be set to the top IP header. | ||
23 | */ | 20 | */ |
24 | static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) | 21 | static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb) |
25 | { | 22 | { |
26 | struct iphdr *iph = ip_hdr(skb); | 23 | struct iphdr *iph = ip_hdr(skb); |
27 | int ihl = iph->ihl * 4; | 24 | int ihl = iph->ihl * 4; |
28 | 25 | ||
29 | skb->transport_header = skb->network_header + ihl; | ||
30 | skb_set_network_header(skb, -x->props.header_len); | 26 | skb_set_network_header(skb, -x->props.header_len); |
27 | skb->mac_header = skb->network_header + | ||
28 | offsetof(struct iphdr, protocol); | ||
29 | skb->transport_header = skb->network_header + ihl; | ||
31 | __skb_pull(skb, ihl); | 30 | __skb_pull(skb, ihl); |
32 | memmove(skb_network_header(skb), iph, ihl); | 31 | memmove(skb_network_header(skb), iph, ihl); |
33 | return 0; | 32 | return 0; |
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index bac1a91f0cbe..f1d41ea34785 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
@@ -35,9 +35,6 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) | |||
35 | * in it shall be filled in by x->type->output: | 35 | * in it shall be filled in by x->type->output: |
36 | * tot_len | 36 | * tot_len |
37 | * check | 37 | * check |
38 | * | ||
39 | * On exit, skb->h will be set to the start of the payload to be processed | ||
40 | * by x->type->output and skb->nh will be set to the top IP header. | ||
41 | */ | 38 | */ |
42 | static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | 39 | static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) |
43 | { | 40 | { |
@@ -47,9 +44,11 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
47 | int flags; | 44 | int flags; |
48 | 45 | ||
49 | iph = ip_hdr(skb); | 46 | iph = ip_hdr(skb); |
50 | skb->transport_header = skb->network_header; | ||
51 | 47 | ||
52 | skb_set_network_header(skb, -x->props.header_len); | 48 | skb_set_network_header(skb, -x->props.header_len); |
49 | skb->mac_header = skb->network_header + | ||
50 | offsetof(struct iphdr, protocol); | ||
51 | skb->transport_header = skb->network_header + sizeof(*iph); | ||
53 | top_iph = ip_hdr(skb); | 52 | top_iph = ip_hdr(skb); |
54 | 53 | ||
55 | top_iph->ihl = 5; | 54 | top_iph->ihl = 5; |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index bca018d19ec6..42c6ef839e59 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
@@ -24,13 +24,6 @@ | |||
24 | * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt. | 24 | * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt. |
25 | * The following fields in it shall be filled in by x->type->output: | 25 | * The following fields in it shall be filled in by x->type->output: |
26 | * payload_len | 26 | * payload_len |
27 | * | ||
28 | * On exit, skb->h will be set to the start of the encapsulation header to be | ||
29 | * filled in by x->type->output and the mac header will be set to the | ||
30 | * nextheader field of the extension header directly preceding the | ||
31 | * encapsulation header, or in its absence, that of the top IP header. | ||
32 | * The value of the network header will always point to the top IP header | ||
33 | * while skb->data will point to the payload. | ||
34 | */ | 27 | */ |
35 | static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | 28 | static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
36 | { | 29 | { |
@@ -44,7 +37,7 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
44 | 37 | ||
45 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); | 38 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); |
46 | skb_set_network_header(skb, -x->props.header_len); | 39 | skb_set_network_header(skb, -x->props.header_len); |
47 | skb_set_transport_header(skb, hdr_len - x->props.header_len); | 40 | skb->transport_header = skb->network_header + hdr_len; |
48 | __skb_pull(skb, hdr_len); | 41 | __skb_pull(skb, hdr_len); |
49 | 42 | ||
50 | top_iph = ipv6_hdr(skb); | 43 | top_iph = ipv6_hdr(skb); |
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c index 5c29b367b432..957ae36b6695 100644 --- a/net/ipv6/xfrm6_mode_ro.c +++ b/net/ipv6/xfrm6_mode_ro.c | |||
@@ -37,13 +37,6 @@ | |||
37 | * | 37 | * |
38 | * The IP header and mutable extension headers will be moved forward to make | 38 | * The IP header and mutable extension headers will be moved forward to make |
39 | * space for the route optimization header. | 39 | * space for the route optimization header. |
40 | * | ||
41 | * On exit, skb->h will be set to the start of the encapsulation header to be | ||
42 | * filled in by x->type->output and the mac header will be set to the | ||
43 | * nextheader field of the extension header directly preceding the | ||
44 | * encapsulation header, or in its absence, that of the top IP header. | ||
45 | * The value of the network header will always point to the top IP header | ||
46 | * while skb->data will point to the payload. | ||
47 | */ | 40 | */ |
48 | static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) | 41 | static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) |
49 | { | 42 | { |
@@ -56,7 +49,7 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) | |||
56 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); | 49 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); |
57 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); | 50 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); |
58 | skb_set_network_header(skb, -x->props.header_len); | 51 | skb_set_network_header(skb, -x->props.header_len); |
59 | skb_set_transport_header(skb, hdr_len - x->props.header_len); | 52 | skb->transport_header = skb->network_header + hdr_len; |
60 | __skb_pull(skb, hdr_len); | 53 | __skb_pull(skb, hdr_len); |
61 | memmove(ipv6_hdr(skb), iph, hdr_len); | 54 | memmove(ipv6_hdr(skb), iph, hdr_len); |
62 | 55 | ||
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c index f2ee186494ed..4e344105b3fd 100644 --- a/net/ipv6/xfrm6_mode_transport.c +++ b/net/ipv6/xfrm6_mode_transport.c | |||
@@ -18,13 +18,6 @@ | |||
18 | * | 18 | * |
19 | * The IP header and mutable extension headers will be moved forward to make | 19 | * The IP header and mutable extension headers will be moved forward to make |
20 | * space for the encapsulation header. | 20 | * space for the encapsulation header. |
21 | * | ||
22 | * On exit, skb->h will be set to the start of the encapsulation header to be | ||
23 | * filled in by x->type->output and the mac header will be set to the | ||
24 | * nextheader field of the extension header directly preceding the | ||
25 | * encapsulation header, or in its absence, that of the top IP header. | ||
26 | * The value of the network header will always point to the top IP header | ||
27 | * while skb->data will point to the payload. | ||
28 | */ | 21 | */ |
29 | static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) | 22 | static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) |
30 | { | 23 | { |
@@ -37,7 +30,7 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) | |||
37 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); | 30 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); |
38 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); | 31 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); |
39 | skb_set_network_header(skb, -x->props.header_len); | 32 | skb_set_network_header(skb, -x->props.header_len); |
40 | skb_set_transport_header(skb, hdr_len - x->props.header_len); | 33 | skb->transport_header = skb->network_header + hdr_len; |
41 | __skb_pull(skb, hdr_len); | 34 | __skb_pull(skb, hdr_len); |
42 | memmove(ipv6_hdr(skb), iph, hdr_len); | 35 | memmove(ipv6_hdr(skb), iph, hdr_len); |
43 | return 0; | 36 | return 0; |
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 01bd7d11ea1b..e79c6bdf71c1 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
@@ -36,13 +36,6 @@ static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb) | |||
36 | * The top IP header will be constructed per RFC 2401. The following fields | 36 | * The top IP header will be constructed per RFC 2401. The following fields |
37 | * in it shall be filled in by x->type->output: | 37 | * in it shall be filled in by x->type->output: |
38 | * payload_len | 38 | * payload_len |
39 | * | ||
40 | * On exit, skb->h will be set to the start of the encapsulation header to be | ||
41 | * filled in by x->type->output and the mac header will be set to the | ||
42 | * nextheader field of the extension header directly preceding the | ||
43 | * encapsulation header, or in its absence, that of the top IP header. | ||
44 | * The value of the network header will always point to the top IP header | ||
45 | * while skb->data will point to the payload. | ||
46 | */ | 39 | */ |
47 | static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | 40 | static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) |
48 | { | 41 | { |
@@ -53,11 +46,10 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
53 | 46 | ||
54 | iph = ipv6_hdr(skb); | 47 | iph = ipv6_hdr(skb); |
55 | 48 | ||
56 | skb_set_mac_header(skb, offsetof(struct ipv6hdr, nexthdr) - | ||
57 | x->props.header_len); | ||
58 | skb_set_network_header(skb, -x->props.header_len); | 49 | skb_set_network_header(skb, -x->props.header_len); |
59 | skb_set_transport_header(skb, sizeof(struct ipv6hdr) - | 50 | skb->mac_header = skb->network_header + |
60 | x->props.header_len); | 51 | offsetof(struct ipv6hdr, nexthdr); |
52 | skb->transport_header = skb->network_header + sizeof(*iph); | ||
61 | top_iph = ipv6_hdr(skb); | 53 | top_iph = ipv6_hdr(skb); |
62 | 54 | ||
63 | top_iph->version = 6; | 55 | top_iph->version = 6; |