aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipcomp6.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-05-28 02:06:13 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-18 00:28:41 -0400
commit31a4ab93025719e62e7cf7ce899f71c34ecde5a0 (patch)
tree60404c5fd1124882753b38e334656a15f8de0804 /net/ipv6/ipcomp6.c
parentb59f45d0b2878ab76f8053b0973654e6621828ee (diff)
[IPSEC] proto: Move transport mode input path into xfrm_mode_transport
Now that we have xfrm_mode objects we can move the transport mode specific input decapsulation code into xfrm_mode_transport. This removes duplicate code as well as unnecessary header movement in case of tunnel mode SAs since we will discard the original IP header immediately. This also fixes a minor bug for transport-mode ESP where the IP payload length is set to the correct value minus the header length (with extension headers for IPv6). Of course the other neat thing is that we no longer have to allocate temporary buffers to hold the IP headers for ESP and IPComp. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ipcomp6.c')
-rw-r--r--net/ipv6/ipcomp6.c27
1 files changed, 5 insertions, 22 deletions
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 48636436028a..cec3be544b69 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -66,10 +66,8 @@ static LIST_HEAD(ipcomp6_tfms_list);
66static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) 66static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
67{ 67{
68 int err = 0; 68 int err = 0;
69 u8 nexthdr = 0;
70 int hdr_len = skb->h.raw - skb->nh.raw;
71 unsigned char *tmp_hdr = NULL;
72 struct ipv6hdr *iph; 69 struct ipv6hdr *iph;
70 struct ipv6_comp_hdr *ipch;
73 int plen, dlen; 71 int plen, dlen;
74 struct ipcomp_data *ipcd = x->data; 72 struct ipcomp_data *ipcd = x->data;
75 u8 *start, *scratch; 73 u8 *start, *scratch;
@@ -86,17 +84,9 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
86 84
87 /* Remove ipcomp header and decompress original payload */ 85 /* Remove ipcomp header and decompress original payload */
88 iph = skb->nh.ipv6h; 86 iph = skb->nh.ipv6h;
89 tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC); 87 ipch = (void *)skb->data;
90 if (!tmp_hdr) 88 skb->h.raw = skb->nh.raw + sizeof(*ipch);
91 goto out; 89 __skb_pull(skb, sizeof(*ipch));
92 memcpy(tmp_hdr, iph, hdr_len);
93 nexthdr = *(u8 *)skb->data;
94 skb_pull(skb, sizeof(struct ipv6_comp_hdr));
95 skb->nh.raw += sizeof(struct ipv6_comp_hdr);
96 memcpy(skb->nh.raw, tmp_hdr, hdr_len);
97 iph = skb->nh.ipv6h;
98 iph->payload_len = htons(ntohs(iph->payload_len) - sizeof(struct ipv6_comp_hdr));
99 skb->h.raw = skb->data;
100 90
101 /* decompression */ 91 /* decompression */
102 plen = skb->len; 92 plen = skb->len;
@@ -125,18 +115,11 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
125 115
126 skb_put(skb, dlen - plen); 116 skb_put(skb, dlen - plen);
127 memcpy(skb->data, scratch, dlen); 117 memcpy(skb->data, scratch, dlen);
118 err = ipch->nexthdr;
128 119
129 iph = skb->nh.ipv6h;
130 iph->payload_len = htons(skb->len);
131
132out_put_cpu: 120out_put_cpu:
133 put_cpu(); 121 put_cpu();
134out: 122out:
135 kfree(tmp_hdr);
136 if (err)
137 goto error_out;
138 return nexthdr;
139error_out:
140 return err; 123 return err;
141} 124}
142 125