diff options
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_ipcomp.c | 13 | ||||
-rw-r--r-- | net/xfrm/xfrm_proc.c | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_replay.c | 99 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 4 |
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 | ||
23 | u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq) | 24 | u32 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 | ||
234 | err_replay: | 232 | err_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 | ||
433 | err_replay: | 416 | err_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); |