aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_ipcomp.c13
-rw-r--r--net/xfrm/xfrm_proc.c1
-rw-r--r--net/xfrm/xfrm_replay.c99
-rw-r--r--net/xfrm/xfrm_user.c4
4 files changed, 46 insertions, 71 deletions
diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index fc91ad7ee26e..e5246fbe36c4 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -70,26 +70,29 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
70 70
71 while ((scratch += len, dlen -= len) > 0) { 71 while ((scratch += len, dlen -= len) > 0) {
72 skb_frag_t *frag; 72 skb_frag_t *frag;
73 struct page *page;
73 74
74 err = -EMSGSIZE; 75 err = -EMSGSIZE;
75 if (WARN_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) 76 if (WARN_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS))
76 goto out; 77 goto out;
77 78
78 frag = skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags; 79 frag = skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
79 frag->page = alloc_page(GFP_ATOMIC); 80 page = alloc_page(GFP_ATOMIC);
80 81
81 err = -ENOMEM; 82 err = -ENOMEM;
82 if (!frag->page) 83 if (!page)
83 goto out; 84 goto out;
84 85
86 __skb_frag_set_page(frag, page);
87
85 len = PAGE_SIZE; 88 len = PAGE_SIZE;
86 if (dlen < len) 89 if (dlen < len)
87 len = dlen; 90 len = dlen;
88 91
89 memcpy(page_address(frag->page), scratch, len);
90
91 frag->page_offset = 0; 92 frag->page_offset = 0;
92 frag->size = len; 93 skb_frag_size_set(frag, len);
94 memcpy(skb_frag_address(frag), scratch, len);
95
93 skb->truesize += len; 96 skb->truesize += len;
94 skb->data_len += len; 97 skb->data_len += len;
95 skb->len += len; 98 skb->len += len;
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index 58d9ae005597..d0a1af8ed584 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -12,6 +12,7 @@
12 */ 12 */
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/seq_file.h> 14#include <linux/seq_file.h>
15#include <linux/export.h>
15#include <net/snmp.h> 16#include <net/snmp.h>
16#include <net/xfrm.h> 17#include <net/xfrm.h>
17 18
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index b11ea692bd7d..39e02c54ed26 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -18,6 +18,7 @@
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 19 */
20 20
21#include <linux/export.h>
21#include <net/xfrm.h> 22#include <net/xfrm.h>
22 23
23u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq) 24u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq)
@@ -203,8 +204,6 @@ static int xfrm_replay_check_bmp(struct xfrm_state *x,
203 if (!replay_esn->replay_window) 204 if (!replay_esn->replay_window)
204 return 0; 205 return 0;
205 206
206 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
207
208 if (unlikely(seq == 0)) 207 if (unlikely(seq == 0))
209 goto err; 208 goto err;
210 209
@@ -216,19 +215,18 @@ static int xfrm_replay_check_bmp(struct xfrm_state *x,
216 goto err; 215 goto err;
217 } 216 }
218 217
219 if (pos >= diff) { 218 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
219
220 if (pos >= diff)
220 bitnr = (pos - diff) % replay_esn->replay_window; 221 bitnr = (pos - diff) % replay_esn->replay_window;
221 nr = bitnr >> 5; 222 else
222 bitnr = bitnr & 0x1F;
223 if (replay_esn->bmp[nr] & (1U << bitnr))
224 goto err_replay;
225 } else {
226 bitnr = replay_esn->replay_window - (diff - pos); 223 bitnr = replay_esn->replay_window - (diff - pos);
227 nr = bitnr >> 5; 224
228 bitnr = bitnr & 0x1F; 225 nr = bitnr >> 5;
229 if (replay_esn->bmp[nr] & (1U << bitnr)) 226 bitnr = bitnr & 0x1F;
230 goto err_replay; 227 if (replay_esn->bmp[nr] & (1U << bitnr))
231 } 228 goto err_replay;
229
232 return 0; 230 return 0;
233 231
234err_replay: 232err_replay:
@@ -259,39 +257,27 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
259 bitnr = bitnr & 0x1F; 257 bitnr = bitnr & 0x1F;
260 replay_esn->bmp[nr] &= ~(1U << bitnr); 258 replay_esn->bmp[nr] &= ~(1U << bitnr);
261 } 259 }
262
263 bitnr = (pos + diff) % replay_esn->replay_window;
264 nr = bitnr >> 5;
265 bitnr = bitnr & 0x1F;
266 replay_esn->bmp[nr] |= (1U << bitnr);
267 } else { 260 } else {
268 nr = (replay_esn->replay_window - 1) >> 5; 261 nr = (replay_esn->replay_window - 1) >> 5;
269 for (i = 0; i <= nr; i++) 262 for (i = 0; i <= nr; i++)
270 replay_esn->bmp[i] = 0; 263 replay_esn->bmp[i] = 0;
271
272 bitnr = (pos + diff) % replay_esn->replay_window;
273 nr = bitnr >> 5;
274 bitnr = bitnr & 0x1F;
275 replay_esn->bmp[nr] |= (1U << bitnr);
276 } 264 }
277 265
266 bitnr = (pos + diff) % replay_esn->replay_window;
278 replay_esn->seq = seq; 267 replay_esn->seq = seq;
279 } else { 268 } else {
280 diff = replay_esn->seq - seq; 269 diff = replay_esn->seq - seq;
281 270
282 if (pos >= diff) { 271 if (pos >= diff)
283 bitnr = (pos - diff) % replay_esn->replay_window; 272 bitnr = (pos - diff) % replay_esn->replay_window;
284 nr = bitnr >> 5; 273 else
285 bitnr = bitnr & 0x1F;
286 replay_esn->bmp[nr] |= (1U << bitnr);
287 } else {
288 bitnr = replay_esn->replay_window - (diff - pos); 274 bitnr = replay_esn->replay_window - (diff - pos);
289 nr = bitnr >> 5;
290 bitnr = bitnr & 0x1F;
291 replay_esn->bmp[nr] |= (1U << bitnr);
292 }
293 } 275 }
294 276
277 nr = bitnr >> 5;
278 bitnr = bitnr & 0x1F;
279 replay_esn->bmp[nr] |= (1U << bitnr);
280
295 if (xfrm_aevent_is_on(xs_net(x))) 281 if (xfrm_aevent_is_on(xs_net(x)))
296 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); 282 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
297} 283}
@@ -390,8 +376,6 @@ static int xfrm_replay_check_esn(struct xfrm_state *x,
390 if (!wsize) 376 if (!wsize)
391 return 0; 377 return 0;
392 378
393 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
394
395 if (unlikely(seq == 0 && replay_esn->seq_hi == 0 && 379 if (unlikely(seq == 0 && replay_esn->seq_hi == 0 &&
396 (replay_esn->seq < replay_esn->replay_window - 1))) 380 (replay_esn->seq < replay_esn->replay_window - 1)))
397 goto err; 381 goto err;
@@ -415,19 +399,18 @@ static int xfrm_replay_check_esn(struct xfrm_state *x,
415 goto err; 399 goto err;
416 } 400 }
417 401
418 if (pos >= diff) { 402 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
403
404 if (pos >= diff)
419 bitnr = (pos - diff) % replay_esn->replay_window; 405 bitnr = (pos - diff) % replay_esn->replay_window;
420 nr = bitnr >> 5; 406 else
421 bitnr = bitnr & 0x1F;
422 if (replay_esn->bmp[nr] & (1U << bitnr))
423 goto err_replay;
424 } else {
425 bitnr = replay_esn->replay_window - (diff - pos); 407 bitnr = replay_esn->replay_window - (diff - pos);
426 nr = bitnr >> 5; 408
427 bitnr = bitnr & 0x1F; 409 nr = bitnr >> 5;
428 if (replay_esn->bmp[nr] & (1U << bitnr)) 410 bitnr = bitnr & 0x1F;
429 goto err_replay; 411 if (replay_esn->bmp[nr] & (1U << bitnr))
430 } 412 goto err_replay;
413
431 return 0; 414 return 0;
432 415
433err_replay: 416err_replay:
@@ -465,22 +448,13 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
465 bitnr = bitnr & 0x1F; 448 bitnr = bitnr & 0x1F;
466 replay_esn->bmp[nr] &= ~(1U << bitnr); 449 replay_esn->bmp[nr] &= ~(1U << bitnr);
467 } 450 }
468
469 bitnr = (pos + diff) % replay_esn->replay_window;
470 nr = bitnr >> 5;
471 bitnr = bitnr & 0x1F;
472 replay_esn->bmp[nr] |= (1U << bitnr);
473 } else { 451 } else {
474 nr = (replay_esn->replay_window - 1) >> 5; 452 nr = (replay_esn->replay_window - 1) >> 5;
475 for (i = 0; i <= nr; i++) 453 for (i = 0; i <= nr; i++)
476 replay_esn->bmp[i] = 0; 454 replay_esn->bmp[i] = 0;
477
478 bitnr = (pos + diff) % replay_esn->replay_window;
479 nr = bitnr >> 5;
480 bitnr = bitnr & 0x1F;
481 replay_esn->bmp[nr] |= (1U << bitnr);
482 } 455 }
483 456
457 bitnr = (pos + diff) % replay_esn->replay_window;
484 replay_esn->seq = seq; 458 replay_esn->seq = seq;
485 459
486 if (unlikely(wrap > 0)) 460 if (unlikely(wrap > 0))
@@ -488,19 +462,16 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
488 } else { 462 } else {
489 diff = replay_esn->seq - seq; 463 diff = replay_esn->seq - seq;
490 464
491 if (pos >= diff) { 465 if (pos >= diff)
492 bitnr = (pos - diff) % replay_esn->replay_window; 466 bitnr = (pos - diff) % replay_esn->replay_window;
493 nr = bitnr >> 5; 467 else
494 bitnr = bitnr & 0x1F;
495 replay_esn->bmp[nr] |= (1U << bitnr);
496 } else {
497 bitnr = replay_esn->replay_window - (diff - pos); 468 bitnr = replay_esn->replay_window - (diff - pos);
498 nr = bitnr >> 5;
499 bitnr = bitnr & 0x1F;
500 replay_esn->bmp[nr] |= (1U << bitnr);
501 }
502 } 469 }
503 470
471 nr = bitnr >> 5;
472 bitnr = bitnr & 0x1F;
473 replay_esn->bmp[nr] |= (1U << bitnr);
474
504 if (xfrm_aevent_is_on(xs_net(x))) 475 if (xfrm_aevent_is_on(xs_net(x)))
505 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); 476 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
506} 477}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0256b8a0a7cf..d0a42df5160e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2927,7 +2927,7 @@ static int __net_init xfrm_user_net_init(struct net *net)
2927 if (nlsk == NULL) 2927 if (nlsk == NULL)
2928 return -ENOMEM; 2928 return -ENOMEM;
2929 net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */ 2929 net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
2930 rcu_assign_pointer(net->xfrm.nlsk, nlsk); 2930 RCU_INIT_POINTER(net->xfrm.nlsk, nlsk);
2931 return 0; 2931 return 0;
2932} 2932}
2933 2933
@@ -2935,7 +2935,7 @@ static void __net_exit xfrm_user_net_exit(struct list_head *net_exit_list)
2935{ 2935{
2936 struct net *net; 2936 struct net *net;
2937 list_for_each_entry(net, net_exit_list, exit_list) 2937 list_for_each_entry(net, net_exit_list, exit_list)
2938 rcu_assign_pointer(net->xfrm.nlsk, NULL); 2938 RCU_INIT_POINTER(net->xfrm.nlsk, NULL);
2939 synchronize_net(); 2939 synchronize_net();
2940 list_for_each_entry(net, net_exit_list, exit_list) 2940 list_for_each_entry(net, net_exit_list, exit_list)
2941 netlink_kernel_release(net->xfrm.nlsk_stash); 2941 netlink_kernel_release(net->xfrm.nlsk_stash);