aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-09 16:25:59 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:00 -0400
commit007f0211a8872f32381f5d44becf8eb2f27f3c30 (patch)
tree9f6879726b6f016379368ebbde6ce3ec13faaa39 /net/ipv6
parent1ecafede835321ebdc396531245adc37d22366f7 (diff)
[IPSEC]: Store IPv6 nh pointer in mac_header on output
Current the x->mode->output functions store the IPv6 nh pointer in the skb network header. This is inconvenient because the network header then has to be fixed up before the packet can leave the IPsec stack. The mac header field is unused on output so we can use that to store this instead. This patch does that and removes the network header fix-up in xfrm_output. It also uses ipv6_hdr where appropriate in the x->type->output functions. There is also a minor clean-up in esp4 to make it use the same code as esp6 to help any subsequent effort to merge the two. Lastly it kills two redundant skb_set_* statements in BEET that were simply copied over from transport mode. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ah6.c6
-rw-r--r--net/ipv6/esp6.c7
-rw-r--r--net/ipv6/ipcomp6.c6
-rw-r--r--net/ipv6/mip6.c12
-rw-r--r--net/ipv6/xfrm6_mode_beet.c16
-rw-r--r--net/ipv6/xfrm6_mode_ro.c13
-rw-r--r--net/ipv6/xfrm6_mode_transport.c13
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c13
-rw-r--r--net/ipv6/xfrm6_tunnel.c2
9 files changed, 45 insertions, 43 deletions
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index ae68a900f605..ff904a711f3a 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -235,11 +235,11 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
235 char hdrs[0]; 235 char hdrs[0];
236 } *tmp_ext; 236 } *tmp_ext;
237 237
238 top_iph = (struct ipv6hdr *)skb->data; 238 top_iph = ipv6_hdr(skb);
239 top_iph->payload_len = htons(skb->len - sizeof(*top_iph)); 239 top_iph->payload_len = htons(skb->len - sizeof(*top_iph));
240 240
241 nexthdr = *skb_network_header(skb); 241 nexthdr = *skb_mac_header(skb);
242 *skb_network_header(skb) = IPPROTO_AH; 242 *skb_mac_header(skb) = IPPROTO_AH;
243 243
244 /* When there are no extension headers, we only need to save the first 244 /* When there are no extension headers, we only need to save the first
245 * 8 bytes of the base IP header. 245 * 8 bytes of the base IP header.
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 0c5fb81451b7..9fc19400b851 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -88,11 +88,12 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
88 tail[clen-skb->len - 2] = (clen - skb->len) - 2; 88 tail[clen-skb->len - 2] = (clen - skb->len) - 2;
89 pskb_put(skb, trailer, clen - skb->len); 89 pskb_put(skb, trailer, clen - skb->len);
90 90
91 top_iph = (struct ipv6hdr *)__skb_push(skb, hdr_len); 91 __skb_push(skb, -skb_network_offset(skb));
92 top_iph = ipv6_hdr(skb);
92 esph = (struct ipv6_esp_hdr *)skb_transport_header(skb); 93 esph = (struct ipv6_esp_hdr *)skb_transport_header(skb);
93 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph)); 94 top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph));
94 *(skb_tail_pointer(trailer) - 1) = *skb_network_header(skb); 95 *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);
95 *skb_network_header(skb) = IPPROTO_ESP; 96 *skb_mac_header(skb) = IPPROTO_ESP;
96 97
97 esph->spi = x->id.spi; 98 esph->spi = x->id.spi;
98 esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); 99 esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 91b2a75b7d09..71a14c09975c 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -157,15 +157,15 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
157 pskb_trim(skb, hdr_len + dlen + sizeof(struct ip_comp_hdr)); 157 pskb_trim(skb, hdr_len + dlen + sizeof(struct ip_comp_hdr));
158 158
159 /* insert ipcomp header and replace datagram */ 159 /* insert ipcomp header and replace datagram */
160 top_iph = (struct ipv6hdr *)skb->data; 160 top_iph = ipv6_hdr(skb);
161 161
162 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 162 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
163 163
164 ipch = (struct ipv6_comp_hdr *)start; 164 ipch = (struct ipv6_comp_hdr *)start;
165 ipch->nexthdr = *skb_network_header(skb); 165 ipch->nexthdr = *skb_mac_header(skb);
166 ipch->flags = 0; 166 ipch->flags = 0;
167 ipch->cpi = htons((u16 )ntohl(x->id.spi)); 167 ipch->cpi = htons((u16 )ntohl(x->id.spi));
168 *skb_network_header(skb) = IPPROTO_COMP; 168 *skb_mac_header(skb) = IPPROTO_COMP;
169 169
170out_ok: 170out_ok:
171 return 0; 171 return 0;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 8a1399ce38ce..7261c29898cb 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -153,11 +153,11 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
153 u8 nexthdr; 153 u8 nexthdr;
154 int len; 154 int len;
155 155
156 iph = (struct ipv6hdr *)skb->data; 156 iph = ipv6_hdr(skb);
157 iph->payload_len = htons(skb->len - sizeof(*iph)); 157 iph->payload_len = htons(skb->len - sizeof(*iph));
158 158
159 nexthdr = *skb_network_header(skb); 159 nexthdr = *skb_mac_header(skb);
160 *skb_network_header(skb) = IPPROTO_DSTOPTS; 160 *skb_mac_header(skb) = IPPROTO_DSTOPTS;
161 161
162 dstopt = (struct ipv6_destopt_hdr *)skb_transport_header(skb); 162 dstopt = (struct ipv6_destopt_hdr *)skb_transport_header(skb);
163 dstopt->nexthdr = nexthdr; 163 dstopt->nexthdr = nexthdr;
@@ -365,11 +365,11 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
365 struct rt2_hdr *rt2; 365 struct rt2_hdr *rt2;
366 u8 nexthdr; 366 u8 nexthdr;
367 367
368 iph = (struct ipv6hdr *)skb->data; 368 iph = ipv6_hdr(skb);
369 iph->payload_len = htons(skb->len - sizeof(*iph)); 369 iph->payload_len = htons(skb->len - sizeof(*iph));
370 370
371 nexthdr = *skb_network_header(skb); 371 nexthdr = *skb_mac_header(skb);
372 *skb_network_header(skb) = IPPROTO_ROUTING; 372 *skb_mac_header(skb) = IPPROTO_ROUTING;
373 373
374 rt2 = (struct rt2_hdr *)skb_transport_header(skb); 374 rt2 = (struct rt2_hdr *)skb_transport_header(skb);
375 rt2->rt_hdr.nexthdr = nexthdr; 375 rt2->rt_hdr.nexthdr = nexthdr;
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 2e61d6ddece3..65e6b2a7fb31 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -26,10 +26,11 @@
26 * payload_len 26 * payload_len
27 * 27 *
28 * On exit, skb->h will be set to the start of the encapsulation header to be 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 skb->nh will be set to the nextheader field 29 * filled in by x->type->output and the mac header will be set to the
30 * of the extension header directly preceding the encapsulation header, or in 30 * nextheader field of the extension header directly preceding the
31 * its absence, that of the top IP header. The value of skb->data will always 31 * encapsulation header, or in its absence, that of the top IP header.
32 * point to the top IP header. 32 * The value of skb->data and the network header will always point to the
33 * top IP header.
33 */ 34 */
34static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) 35static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
35{ 36{
@@ -41,15 +42,12 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
41 iph = ipv6_hdr(skb); 42 iph = ipv6_hdr(skb);
42 43
43 hdr_len = ip6_find_1stfragopt(skb, &prevhdr); 44 hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
44 skb_set_network_header(skb,
45 (prevhdr - x->props.header_len) - skb->data);
46 skb_set_transport_header(skb, hdr_len);
47 memmove(skb->data, iph, hdr_len); 45 memmove(skb->data, iph, hdr_len);
48 46
47 skb_set_mac_header(skb, offsetof(struct ipv6hdr, nexthdr));
49 skb_reset_network_header(skb); 48 skb_reset_network_header(skb);
49 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
50 top_iph = ipv6_hdr(skb); 50 top_iph = ipv6_hdr(skb);
51 skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
52 skb->network_header += offsetof(struct ipv6hdr, nexthdr);
53 51
54 ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); 52 ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
55 ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); 53 ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index a15637384b20..25758048af54 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -39,10 +39,11 @@
39 * space for the route optimization header. 39 * space for the route optimization header.
40 * 40 *
41 * On exit, skb->h will be set to the start of the encapsulation header to be 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 skb->nh will be set to the nextheader field 42 * filled in by x->type->output and the mac header will be set to the
43 * of the extension header directly preceding the encapsulation header, or in 43 * nextheader field of the extension header directly preceding the
44 * its absence, that of the top IP header. The value of skb->data will always 44 * encapsulation header, or in its absence, that of the top IP header.
45 * point to the top IP header. 45 * The value of skb->data and the network header will always point to the
46 * top IP header.
46 */ 47 */
47static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) 48static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
48{ 49{
@@ -54,8 +55,8 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
54 iph = ipv6_hdr(skb); 55 iph = ipv6_hdr(skb);
55 56
56 hdr_len = x->type->hdr_offset(x, skb, &prevhdr); 57 hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
57 skb_set_network_header(skb, 58 skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
58 (prevhdr - x->props.header_len) - skb->data); 59 skb_reset_network_header(skb);
59 skb_set_transport_header(skb, hdr_len); 60 skb_set_transport_header(skb, hdr_len);
60 memmove(skb->data, iph, hdr_len); 61 memmove(skb->data, iph, hdr_len);
61 62
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c
index c026bfea820a..65c166b5d72c 100644
--- a/net/ipv6/xfrm6_mode_transport.c
+++ b/net/ipv6/xfrm6_mode_transport.c
@@ -20,10 +20,11 @@
20 * space for the encapsulation header. 20 * space for the encapsulation header.
21 * 21 *
22 * On exit, skb->h will be set to the start of the encapsulation header to be 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 skb->nh will be set to the nextheader field 23 * filled in by x->type->output and the mac header will be set to the
24 * of the extension header directly preceding the encapsulation header, or in 24 * nextheader field of the extension header directly preceding the
25 * its absence, that of the top IP header. The value of skb->data will always 25 * encapsulation header, or in its absence, that of the top IP header.
26 * point to the top IP header. 26 * The value of skb->data and the network header will always point to the
27 * top IP header.
27 */ 28 */
28static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) 29static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
29{ 30{
@@ -35,8 +36,8 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
35 iph = ipv6_hdr(skb); 36 iph = ipv6_hdr(skb);
36 37
37 hdr_len = x->type->hdr_offset(x, skb, &prevhdr); 38 hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
38 skb_set_network_header(skb, 39 skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
39 (prevhdr - x->props.header_len) - skb->data); 40 skb_reset_network_header(skb);
40 skb_set_transport_header(skb, hdr_len); 41 skb_set_transport_header(skb, hdr_len);
41 memmove(skb->data, iph, hdr_len); 42 memmove(skb->data, iph, hdr_len);
42 return 0; 43 return 0;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 9fc95bc6509f..3dd40af75e81 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -38,10 +38,11 @@ static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
38 * payload_len 38 * payload_len
39 * 39 *
40 * On exit, skb->h will be set to the start of the encapsulation header to be 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 skb->nh will be set to the nextheader field 41 * filled in by x->type->output and the mac header will be set to the
42 * of the extension header directly preceding the encapsulation header, or in 42 * nextheader field of the extension header directly preceding the
43 * its absence, that of the top IP header. The value of skb->data will always 43 * encapsulation header, or in its absence, that of the top IP header.
44 * point to the top IP header. 44 * The value of skb->data and the network header will always point to the
45 * top IP header.
45 */ 46 */
46static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 47static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
47{ 48{
@@ -53,10 +54,10 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
53 skb_push(skb, x->props.header_len); 54 skb_push(skb, x->props.header_len);
54 iph = ipv6_hdr(skb); 55 iph = ipv6_hdr(skb);
55 56
57 skb_set_mac_header(skb, offsetof(struct ipv6hdr, nexthdr));
56 skb_reset_network_header(skb); 58 skb_reset_network_header(skb);
59 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
57 top_iph = ipv6_hdr(skb); 60 top_iph = ipv6_hdr(skb);
58 skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
59 skb->network_header += offsetof(struct ipv6hdr, nexthdr);
60 61
61 top_iph->version = 6; 62 top_iph->version = 6;
62 if (xdst->route->ops->family == AF_INET6) { 63 if (xdst->route->ops->family == AF_INET6) {
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 30f3236c402a..aeb06076fdd0 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -244,7 +244,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
244{ 244{
245 struct ipv6hdr *top_iph; 245 struct ipv6hdr *top_iph;
246 246
247 top_iph = (struct ipv6hdr *)skb->data; 247 top_iph = ipv6_hdr(skb);
248 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 248 top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
249 249
250 return 0; 250 return 0;