diff options
-rw-r--r-- | net/ipv4/ah4.c | 15 | ||||
-rw-r--r-- | net/ipv4/esp4.c | 18 | ||||
-rw-r--r-- | net/ipv4/ipcomp.c | 23 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_transport.c | 14 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 10 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 20 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 27 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_transport.c | 15 |
8 files changed, 59 insertions, 83 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index e2e4771fa4c6..c7782230080d 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -119,6 +119,7 @@ error: | |||
119 | static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | 119 | static int ah_input(struct xfrm_state *x, struct sk_buff *skb) |
120 | { | 120 | { |
121 | int ah_hlen; | 121 | int ah_hlen; |
122 | int ihl; | ||
122 | struct iphdr *iph; | 123 | struct iphdr *iph; |
123 | struct ip_auth_hdr *ah; | 124 | struct ip_auth_hdr *ah; |
124 | struct ah_data *ahp; | 125 | struct ah_data *ahp; |
@@ -149,13 +150,14 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | |||
149 | ah = (struct ip_auth_hdr*)skb->data; | 150 | ah = (struct ip_auth_hdr*)skb->data; |
150 | iph = skb->nh.iph; | 151 | iph = skb->nh.iph; |
151 | 152 | ||
152 | memcpy(work_buf, iph, iph->ihl*4); | 153 | ihl = skb->data - skb->nh.raw; |
154 | memcpy(work_buf, iph, ihl); | ||
153 | 155 | ||
154 | iph->ttl = 0; | 156 | iph->ttl = 0; |
155 | iph->tos = 0; | 157 | iph->tos = 0; |
156 | iph->frag_off = 0; | 158 | iph->frag_off = 0; |
157 | iph->check = 0; | 159 | iph->check = 0; |
158 | if (iph->ihl != 5) { | 160 | if (ihl > sizeof(*iph)) { |
159 | u32 dummy; | 161 | u32 dummy; |
160 | if (ip_clear_mutable_options(iph, &dummy)) | 162 | if (ip_clear_mutable_options(iph, &dummy)) |
161 | goto out; | 163 | goto out; |
@@ -164,7 +166,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | |||
164 | u8 auth_data[MAX_AH_AUTH_LEN]; | 166 | u8 auth_data[MAX_AH_AUTH_LEN]; |
165 | 167 | ||
166 | memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); | 168 | memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); |
167 | skb_push(skb, skb->data - skb->nh.raw); | 169 | skb_push(skb, ihl); |
168 | ahp->icv(ahp, skb, ah->auth_data); | 170 | ahp->icv(ahp, skb, ah->auth_data); |
169 | if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { | 171 | if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { |
170 | x->stats.integrity_failed++; | 172 | x->stats.integrity_failed++; |
@@ -172,11 +174,8 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | |||
172 | } | 174 | } |
173 | } | 175 | } |
174 | ((struct iphdr*)work_buf)->protocol = ah->nexthdr; | 176 | ((struct iphdr*)work_buf)->protocol = ah->nexthdr; |
175 | skb->nh.raw = skb_pull(skb, ah_hlen); | 177 | skb->h.raw = memcpy(skb->nh.raw += ah_hlen, work_buf, ihl); |
176 | memcpy(skb->nh.raw, work_buf, iph->ihl*4); | 178 | __skb_pull(skb, ah_hlen + ihl); |
177 | skb->nh.iph->tot_len = htons(skb->len); | ||
178 | skb_pull(skb, skb->nh.iph->ihl*4); | ||
179 | skb->h.raw = skb->data; | ||
180 | 179 | ||
181 | return 0; | 180 | return 0; |
182 | 181 | ||
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 9d1881c07a32..9bbdd4494551 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -143,10 +143,9 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
143 | int alen = esp->auth.icv_trunc_len; | 143 | int alen = esp->auth.icv_trunc_len; |
144 | int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; | 144 | int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; |
145 | int nfrags; | 145 | int nfrags; |
146 | int encap_len = 0; | 146 | int ihl; |
147 | u8 nexthdr[2]; | 147 | u8 nexthdr[2]; |
148 | struct scatterlist *sg; | 148 | struct scatterlist *sg; |
149 | u8 workbuf[60]; | ||
150 | int padlen; | 149 | int padlen; |
151 | 150 | ||
152 | if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) | 151 | if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) |
@@ -177,7 +176,6 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
177 | skb->ip_summed = CHECKSUM_NONE; | 176 | skb->ip_summed = CHECKSUM_NONE; |
178 | 177 | ||
179 | esph = (struct ip_esp_hdr*)skb->data; | 178 | esph = (struct ip_esp_hdr*)skb->data; |
180 | iph = skb->nh.iph; | ||
181 | 179 | ||
182 | /* Get ivec. This can be wrong, check against another impls. */ | 180 | /* Get ivec. This can be wrong, check against another impls. */ |
183 | if (esp->conf.ivlen) | 181 | if (esp->conf.ivlen) |
@@ -204,12 +202,12 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
204 | 202 | ||
205 | /* ... check padding bits here. Silly. :-) */ | 203 | /* ... check padding bits here. Silly. :-) */ |
206 | 204 | ||
205 | iph = skb->nh.iph; | ||
206 | ihl = iph->ihl * 4; | ||
207 | |||
207 | if (x->encap) { | 208 | if (x->encap) { |
208 | struct xfrm_encap_tmpl *encap = x->encap; | 209 | struct xfrm_encap_tmpl *encap = x->encap; |
209 | struct udphdr *uh; | 210 | struct udphdr *uh = (void *)(skb->nh.raw + ihl); |
210 | |||
211 | uh = (struct udphdr *)(iph + 1); | ||
212 | encap_len = (void*)esph - (void*)uh; | ||
213 | 211 | ||
214 | /* | 212 | /* |
215 | * 1) if the NAT-T peer's IP or port changed then | 213 | * 1) if the NAT-T peer's IP or port changed then |
@@ -246,11 +244,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
246 | 244 | ||
247 | iph->protocol = nexthdr[1]; | 245 | iph->protocol = nexthdr[1]; |
248 | pskb_trim(skb, skb->len - alen - padlen - 2); | 246 | pskb_trim(skb, skb->len - alen - padlen - 2); |
249 | memcpy(workbuf, skb->nh.raw, iph->ihl*4); | 247 | skb->h.raw = __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen) - ihl; |
250 | skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); | ||
251 | skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; | ||
252 | memcpy(skb->nh.raw, workbuf, iph->ihl*4); | ||
253 | skb->nh.iph->tot_len = htons(skb->len); | ||
254 | 248 | ||
255 | return 0; | 249 | return 0; |
256 | 250 | ||
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 95278b22b669..8e243589045f 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -45,7 +45,6 @@ static LIST_HEAD(ipcomp_tfms_list); | |||
45 | static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) | 45 | static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) |
46 | { | 46 | { |
47 | int err, plen, dlen; | 47 | int err, plen, dlen; |
48 | struct iphdr *iph; | ||
49 | struct ipcomp_data *ipcd = x->data; | 48 | struct ipcomp_data *ipcd = x->data; |
50 | u8 *start, *scratch; | 49 | u8 *start, *scratch; |
51 | struct crypto_tfm *tfm; | 50 | struct crypto_tfm *tfm; |
@@ -74,8 +73,6 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) | |||
74 | 73 | ||
75 | skb_put(skb, dlen - plen); | 74 | skb_put(skb, dlen - plen); |
76 | memcpy(skb->data, scratch, dlen); | 75 | memcpy(skb->data, scratch, dlen); |
77 | iph = skb->nh.iph; | ||
78 | iph->tot_len = htons(dlen + iph->ihl * 4); | ||
79 | out: | 76 | out: |
80 | put_cpu(); | 77 | put_cpu(); |
81 | return err; | 78 | return err; |
@@ -83,14 +80,9 @@ out: | |||
83 | 80 | ||
84 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | 81 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
85 | { | 82 | { |
86 | u8 nexthdr; | ||
87 | int err = 0; | 83 | int err = 0; |
88 | struct iphdr *iph; | 84 | struct iphdr *iph; |
89 | union { | 85 | struct ip_comp_hdr *ipch; |
90 | struct iphdr iph; | ||
91 | char buf[60]; | ||
92 | } tmp_iph; | ||
93 | |||
94 | 86 | ||
95 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && | 87 | if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && |
96 | skb_linearize(skb, GFP_ATOMIC) != 0) { | 88 | skb_linearize(skb, GFP_ATOMIC) != 0) { |
@@ -102,15 +94,10 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
102 | 94 | ||
103 | /* Remove ipcomp header and decompress original payload */ | 95 | /* Remove ipcomp header and decompress original payload */ |
104 | iph = skb->nh.iph; | 96 | iph = skb->nh.iph; |
105 | memcpy(&tmp_iph, iph, iph->ihl * 4); | 97 | ipch = (void *)skb->data; |
106 | nexthdr = *(u8 *)skb->data; | 98 | iph->protocol = ipch->nexthdr; |
107 | skb_pull(skb, sizeof(struct ip_comp_hdr)); | 99 | skb->h.raw = skb->nh.raw + sizeof(*ipch); |
108 | skb->nh.raw += sizeof(struct ip_comp_hdr); | 100 | __skb_pull(skb, sizeof(*ipch)); |
109 | memcpy(skb->nh.raw, &tmp_iph, tmp_iph.iph.ihl * 4); | ||
110 | iph = skb->nh.iph; | ||
111 | iph->tot_len = htons(ntohs(iph->tot_len) - sizeof(struct ip_comp_hdr)); | ||
112 | iph->protocol = nexthdr; | ||
113 | skb->h.raw = skb->data; | ||
114 | err = ipcomp_decompress(x, skb); | 101 | err = ipcomp_decompress(x, skb); |
115 | 102 | ||
116 | out: | 103 | out: |
diff --git a/net/ipv4/xfrm4_mode_transport.c b/net/ipv4/xfrm4_mode_transport.c index e46d9a4ccc55..a9e6b3dd19c9 100644 --- a/net/ipv4/xfrm4_mode_transport.c +++ b/net/ipv4/xfrm4_mode_transport.c | |||
@@ -38,8 +38,22 @@ static int xfrm4_transport_output(struct sk_buff *skb) | |||
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
40 | 40 | ||
41 | /* Remove encapsulation header. | ||
42 | * | ||
43 | * The IP header will be moved over the top of the encapsulation header. | ||
44 | * | ||
45 | * On entry, skb->h shall point to where the IP header should be and skb->nh | ||
46 | * shall be set to where the IP header currently is. skb->data shall point | ||
47 | * to the start of the payload. | ||
48 | */ | ||
41 | static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) | 49 | static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) |
42 | { | 50 | { |
51 | int ihl = skb->data - skb->h.raw; | ||
52 | |||
53 | if (skb->h.raw != skb->nh.raw) | ||
54 | skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl); | ||
55 | skb->nh.iph->tot_len = htons(skb->len + ihl); | ||
56 | skb->h.raw = skb->data; | ||
43 | return 0; | 57 | return 0; |
44 | } | 58 | } |
45 | 59 | ||
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 6778173a3dda..d31c0d6c0448 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -292,7 +292,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
292 | 292 | ||
293 | memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); | 293 | memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); |
294 | memset(ah->auth_data, 0, ahp->icv_trunc_len); | 294 | memset(ah->auth_data, 0, ahp->icv_trunc_len); |
295 | skb_push(skb, skb->data - skb->nh.raw); | 295 | skb_push(skb, hdr_len); |
296 | ahp->icv(ahp, skb, ah->auth_data); | 296 | ahp->icv(ahp, skb, ah->auth_data); |
297 | if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { | 297 | if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { |
298 | LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); | 298 | LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); |
@@ -301,12 +301,8 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
304 | skb->nh.raw = skb_pull(skb, ah_hlen); | 304 | skb->h.raw = memcpy(skb->nh.raw += ah_hlen, tmp_hdr, hdr_len); |
305 | memcpy(skb->nh.raw, tmp_hdr, hdr_len); | 305 | __skb_pull(skb, ah_hlen + hdr_len); |
306 | skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); | ||
307 | skb_pull(skb, hdr_len); | ||
308 | skb->h.raw = skb->data; | ||
309 | |||
310 | 306 | ||
311 | kfree(tmp_hdr); | 307 | kfree(tmp_hdr); |
312 | 308 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 22f046079037..a15a6f320f70 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -142,25 +142,17 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
142 | 142 | ||
143 | int hdr_len = skb->h.raw - skb->nh.raw; | 143 | int hdr_len = skb->h.raw - skb->nh.raw; |
144 | int nfrags; | 144 | int nfrags; |
145 | unsigned char *tmp_hdr = NULL; | ||
146 | int ret = 0; | 145 | int ret = 0; |
147 | 146 | ||
148 | if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) { | 147 | if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) { |
149 | ret = -EINVAL; | 148 | ret = -EINVAL; |
150 | goto out_nofree; | 149 | goto out; |
151 | } | 150 | } |
152 | 151 | ||
153 | if (elen <= 0 || (elen & (blksize-1))) { | 152 | if (elen <= 0 || (elen & (blksize-1))) { |
154 | ret = -EINVAL; | 153 | ret = -EINVAL; |
155 | goto out_nofree; | 154 | goto out; |
156 | } | ||
157 | |||
158 | tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC); | ||
159 | if (!tmp_hdr) { | ||
160 | ret = -ENOMEM; | ||
161 | goto out_nofree; | ||
162 | } | 155 | } |
163 | memcpy(tmp_hdr, skb->nh.raw, hdr_len); | ||
164 | 156 | ||
165 | /* If integrity check is required, do this. */ | 157 | /* If integrity check is required, do this. */ |
166 | if (esp->auth.icv_full_len) { | 158 | if (esp->auth.icv_full_len) { |
@@ -222,16 +214,12 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
222 | /* ... check padding bits here. Silly. :-) */ | 214 | /* ... check padding bits here. Silly. :-) */ |
223 | 215 | ||
224 | pskb_trim(skb, skb->len - alen - padlen - 2); | 216 | pskb_trim(skb, skb->len - alen - padlen - 2); |
225 | skb->h.raw = skb_pull(skb, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen); | ||
226 | skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; | ||
227 | memcpy(skb->nh.raw, tmp_hdr, hdr_len); | ||
228 | skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); | ||
229 | ret = nexthdr[1]; | 217 | ret = nexthdr[1]; |
230 | } | 218 | } |
231 | 219 | ||
220 | skb->h.raw = __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen) - hdr_len; | ||
221 | |||
232 | out: | 222 | out: |
233 | kfree(tmp_hdr); | ||
234 | out_nofree: | ||
235 | return ret; | 223 | return ret; |
236 | } | 224 | } |
237 | 225 | ||
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); | |||
66 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | 66 | static 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 | |||
132 | out_put_cpu: | 120 | out_put_cpu: |
133 | put_cpu(); | 121 | put_cpu(); |
134 | out: | 122 | out: |
135 | kfree(tmp_hdr); | ||
136 | if (err) | ||
137 | goto error_out; | ||
138 | return nexthdr; | ||
139 | error_out: | ||
140 | return err; | 123 | return err; |
141 | } | 124 | } |
142 | 125 | ||
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c index 5efbbae08ef0..711d713e36d8 100644 --- a/net/ipv6/xfrm6_mode_transport.c +++ b/net/ipv6/xfrm6_mode_transport.c | |||
@@ -42,8 +42,23 @@ static int xfrm6_transport_output(struct sk_buff *skb) | |||
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | /* Remove encapsulation header. | ||
46 | * | ||
47 | * The IP header will be moved over the top of the encapsulation header. | ||
48 | * | ||
49 | * On entry, skb->h shall point to where the IP header should be and skb->nh | ||
50 | * shall be set to where the IP header currently is. skb->data shall point | ||
51 | * to the start of the payload. | ||
52 | */ | ||
45 | static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) | 53 | static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) |
46 | { | 54 | { |
55 | int ihl = skb->data - skb->h.raw; | ||
56 | |||
57 | if (skb->h.raw != skb->nh.raw) | ||
58 | skb->nh.raw = memmove(skb->h.raw, skb->nh.raw, ihl); | ||
59 | skb->nh.ipv6h->payload_len = htons(skb->len + ihl - | ||
60 | sizeof(struct ipv6hdr)); | ||
61 | skb->h.raw = skb->data; | ||
47 | return 0; | 62 | return 0; |
48 | } | 63 | } |
49 | 64 | ||