diff options
author | David S. Miller <davem@davemloft.net> | 2013-10-23 16:28:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-23 16:49:34 -0400 |
commit | c3fa32b9764dc45dcf8a2231b1c110abc4a63e0b (patch) | |
tree | 6cf2896a77b65bec64284681e1c3851eb3263e09 /net/xfrm | |
parent | 34d92d5315b64a3e5292b7e9511c1bb617227fb6 (diff) | |
parent | 320437af954cbe66478f1f5e8b34cb5a8d072191 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/usb/qmi_wwan.c
include/net/dst.h
Trivial merge conflicts, both were overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 28 | ||||
-rw-r--r-- | net/xfrm/xfrm_replay.c | 54 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 5 |
3 files changed, 52 insertions, 35 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index ed38d5d81f9e..76e1873811d4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -334,7 +334,8 @@ static void xfrm_policy_kill(struct xfrm_policy *policy) | |||
334 | 334 | ||
335 | atomic_inc(&policy->genid); | 335 | atomic_inc(&policy->genid); |
336 | 336 | ||
337 | del_timer(&policy->polq.hold_timer); | 337 | if (del_timer(&policy->polq.hold_timer)) |
338 | xfrm_pol_put(policy); | ||
338 | xfrm_queue_purge(&policy->polq.hold_queue); | 339 | xfrm_queue_purge(&policy->polq.hold_queue); |
339 | 340 | ||
340 | if (del_timer(&policy->timer)) | 341 | if (del_timer(&policy->timer)) |
@@ -589,7 +590,8 @@ static void xfrm_policy_requeue(struct xfrm_policy *old, | |||
589 | 590 | ||
590 | spin_lock_bh(&pq->hold_queue.lock); | 591 | spin_lock_bh(&pq->hold_queue.lock); |
591 | skb_queue_splice_init(&pq->hold_queue, &list); | 592 | skb_queue_splice_init(&pq->hold_queue, &list); |
592 | del_timer(&pq->hold_timer); | 593 | if (del_timer(&pq->hold_timer)) |
594 | xfrm_pol_put(old); | ||
593 | spin_unlock_bh(&pq->hold_queue.lock); | 595 | spin_unlock_bh(&pq->hold_queue.lock); |
594 | 596 | ||
595 | if (skb_queue_empty(&list)) | 597 | if (skb_queue_empty(&list)) |
@@ -600,7 +602,8 @@ static void xfrm_policy_requeue(struct xfrm_policy *old, | |||
600 | spin_lock_bh(&pq->hold_queue.lock); | 602 | spin_lock_bh(&pq->hold_queue.lock); |
601 | skb_queue_splice(&list, &pq->hold_queue); | 603 | skb_queue_splice(&list, &pq->hold_queue); |
602 | pq->timeout = XFRM_QUEUE_TMO_MIN; | 604 | pq->timeout = XFRM_QUEUE_TMO_MIN; |
603 | mod_timer(&pq->hold_timer, jiffies); | 605 | if (!mod_timer(&pq->hold_timer, jiffies)) |
606 | xfrm_pol_hold(new); | ||
604 | spin_unlock_bh(&pq->hold_queue.lock); | 607 | spin_unlock_bh(&pq->hold_queue.lock); |
605 | } | 608 | } |
606 | 609 | ||
@@ -1769,6 +1772,10 @@ static void xfrm_policy_queue_process(unsigned long arg) | |||
1769 | 1772 | ||
1770 | spin_lock(&pq->hold_queue.lock); | 1773 | spin_lock(&pq->hold_queue.lock); |
1771 | skb = skb_peek(&pq->hold_queue); | 1774 | skb = skb_peek(&pq->hold_queue); |
1775 | if (!skb) { | ||
1776 | spin_unlock(&pq->hold_queue.lock); | ||
1777 | goto out; | ||
1778 | } | ||
1772 | dst = skb_dst(skb); | 1779 | dst = skb_dst(skb); |
1773 | sk = skb->sk; | 1780 | sk = skb->sk; |
1774 | xfrm_decode_session(skb, &fl, dst->ops->family); | 1781 | xfrm_decode_session(skb, &fl, dst->ops->family); |
@@ -1787,8 +1794,9 @@ static void xfrm_policy_queue_process(unsigned long arg) | |||
1787 | goto purge_queue; | 1794 | goto purge_queue; |
1788 | 1795 | ||
1789 | pq->timeout = pq->timeout << 1; | 1796 | pq->timeout = pq->timeout << 1; |
1790 | mod_timer(&pq->hold_timer, jiffies + pq->timeout); | 1797 | if (!mod_timer(&pq->hold_timer, jiffies + pq->timeout)) |
1791 | return; | 1798 | xfrm_pol_hold(pol); |
1799 | goto out; | ||
1792 | } | 1800 | } |
1793 | 1801 | ||
1794 | dst_release(dst); | 1802 | dst_release(dst); |
@@ -1819,11 +1827,14 @@ static void xfrm_policy_queue_process(unsigned long arg) | |||
1819 | err = dst_output(skb); | 1827 | err = dst_output(skb); |
1820 | } | 1828 | } |
1821 | 1829 | ||
1830 | out: | ||
1831 | xfrm_pol_put(pol); | ||
1822 | return; | 1832 | return; |
1823 | 1833 | ||
1824 | purge_queue: | 1834 | purge_queue: |
1825 | pq->timeout = 0; | 1835 | pq->timeout = 0; |
1826 | xfrm_queue_purge(&pq->hold_queue); | 1836 | xfrm_queue_purge(&pq->hold_queue); |
1837 | xfrm_pol_put(pol); | ||
1827 | } | 1838 | } |
1828 | 1839 | ||
1829 | static int xdst_queue_output(struct sk_buff *skb) | 1840 | static int xdst_queue_output(struct sk_buff *skb) |
@@ -1831,7 +1842,8 @@ static int xdst_queue_output(struct sk_buff *skb) | |||
1831 | unsigned long sched_next; | 1842 | unsigned long sched_next; |
1832 | struct dst_entry *dst = skb_dst(skb); | 1843 | struct dst_entry *dst = skb_dst(skb); |
1833 | struct xfrm_dst *xdst = (struct xfrm_dst *) dst; | 1844 | struct xfrm_dst *xdst = (struct xfrm_dst *) dst; |
1834 | struct xfrm_policy_queue *pq = &xdst->pols[0]->polq; | 1845 | struct xfrm_policy *pol = xdst->pols[0]; |
1846 | struct xfrm_policy_queue *pq = &pol->polq; | ||
1835 | 1847 | ||
1836 | if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) { | 1848 | if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) { |
1837 | kfree_skb(skb); | 1849 | kfree_skb(skb); |
@@ -1850,10 +1862,12 @@ static int xdst_queue_output(struct sk_buff *skb) | |||
1850 | if (del_timer(&pq->hold_timer)) { | 1862 | if (del_timer(&pq->hold_timer)) { |
1851 | if (time_before(pq->hold_timer.expires, sched_next)) | 1863 | if (time_before(pq->hold_timer.expires, sched_next)) |
1852 | sched_next = pq->hold_timer.expires; | 1864 | sched_next = pq->hold_timer.expires; |
1865 | xfrm_pol_put(pol); | ||
1853 | } | 1866 | } |
1854 | 1867 | ||
1855 | __skb_queue_tail(&pq->hold_queue, skb); | 1868 | __skb_queue_tail(&pq->hold_queue, skb); |
1856 | mod_timer(&pq->hold_timer, sched_next); | 1869 | if (!mod_timer(&pq->hold_timer, sched_next)) |
1870 | xfrm_pol_hold(pol); | ||
1857 | 1871 | ||
1858 | spin_unlock_bh(&pq->hold_queue.lock); | 1872 | spin_unlock_bh(&pq->hold_queue.lock); |
1859 | 1873 | ||
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 8dafe6d3c6e4..dab57daae408 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
@@ -61,9 +61,9 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event) | |||
61 | 61 | ||
62 | switch (event) { | 62 | switch (event) { |
63 | case XFRM_REPLAY_UPDATE: | 63 | case XFRM_REPLAY_UPDATE: |
64 | if (x->replay_maxdiff && | 64 | if (!x->replay_maxdiff || |
65 | (x->replay.seq - x->preplay.seq < x->replay_maxdiff) && | 65 | ((x->replay.seq - x->preplay.seq < x->replay_maxdiff) && |
66 | (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff)) { | 66 | (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))) { |
67 | if (x->xflags & XFRM_TIME_DEFER) | 67 | if (x->xflags & XFRM_TIME_DEFER) |
68 | event = XFRM_REPLAY_TIMEOUT; | 68 | event = XFRM_REPLAY_TIMEOUT; |
69 | else | 69 | else |
@@ -129,8 +129,7 @@ static int xfrm_replay_check(struct xfrm_state *x, | |||
129 | return 0; | 129 | return 0; |
130 | 130 | ||
131 | diff = x->replay.seq - seq; | 131 | diff = x->replay.seq - seq; |
132 | if (diff >= min_t(unsigned int, x->props.replay_window, | 132 | if (diff >= x->props.replay_window) { |
133 | sizeof(x->replay.bitmap) * 8)) { | ||
134 | x->stats.replay_window++; | 133 | x->stats.replay_window++; |
135 | goto err; | 134 | goto err; |
136 | } | 135 | } |
@@ -302,9 +301,10 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event) | |||
302 | 301 | ||
303 | switch (event) { | 302 | switch (event) { |
304 | case XFRM_REPLAY_UPDATE: | 303 | case XFRM_REPLAY_UPDATE: |
305 | if (x->replay_maxdiff && | 304 | if (!x->replay_maxdiff || |
306 | (replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) && | 305 | ((replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) && |
307 | (replay_esn->oseq - preplay_esn->oseq < x->replay_maxdiff)) { | 306 | (replay_esn->oseq - preplay_esn->oseq |
307 | < x->replay_maxdiff))) { | ||
308 | if (x->xflags & XFRM_TIME_DEFER) | 308 | if (x->xflags & XFRM_TIME_DEFER) |
309 | event = XFRM_REPLAY_TIMEOUT; | 309 | event = XFRM_REPLAY_TIMEOUT; |
310 | else | 310 | else |
@@ -353,28 +353,30 @@ static void xfrm_replay_notify_esn(struct xfrm_state *x, int event) | |||
353 | 353 | ||
354 | switch (event) { | 354 | switch (event) { |
355 | case XFRM_REPLAY_UPDATE: | 355 | case XFRM_REPLAY_UPDATE: |
356 | if (!x->replay_maxdiff) | 356 | if (x->replay_maxdiff) { |
357 | break; | 357 | if (replay_esn->seq_hi == preplay_esn->seq_hi) |
358 | 358 | seq_diff = replay_esn->seq - preplay_esn->seq; | |
359 | if (replay_esn->seq_hi == preplay_esn->seq_hi) | 359 | else |
360 | seq_diff = replay_esn->seq - preplay_esn->seq; | 360 | seq_diff = ~preplay_esn->seq + replay_esn->seq |
361 | else | 361 | + 1; |
362 | seq_diff = ~preplay_esn->seq + replay_esn->seq + 1; | ||
363 | |||
364 | if (replay_esn->oseq_hi == preplay_esn->oseq_hi) | ||
365 | oseq_diff = replay_esn->oseq - preplay_esn->oseq; | ||
366 | else | ||
367 | oseq_diff = ~preplay_esn->oseq + replay_esn->oseq + 1; | ||
368 | |||
369 | if (seq_diff < x->replay_maxdiff && | ||
370 | oseq_diff < x->replay_maxdiff) { | ||
371 | 362 | ||
372 | if (x->xflags & XFRM_TIME_DEFER) | 363 | if (replay_esn->oseq_hi == preplay_esn->oseq_hi) |
373 | event = XFRM_REPLAY_TIMEOUT; | 364 | oseq_diff = replay_esn->oseq |
365 | - preplay_esn->oseq; | ||
374 | else | 366 | else |
375 | return; | 367 | oseq_diff = ~preplay_esn->oseq |
368 | + replay_esn->oseq + 1; | ||
369 | |||
370 | if (seq_diff >= x->replay_maxdiff || | ||
371 | oseq_diff >= x->replay_maxdiff) | ||
372 | break; | ||
376 | } | 373 | } |
377 | 374 | ||
375 | if (x->xflags & XFRM_TIME_DEFER) | ||
376 | event = XFRM_REPLAY_TIMEOUT; | ||
377 | else | ||
378 | return; | ||
379 | |||
378 | break; | 380 | break; |
379 | 381 | ||
380 | case XFRM_REPLAY_TIMEOUT: | 382 | case XFRM_REPLAY_TIMEOUT: |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 3f565e495ac6..f964d4c00ffb 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -446,7 +446,8 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * | |||
446 | memcpy(&x->sel, &p->sel, sizeof(x->sel)); | 446 | memcpy(&x->sel, &p->sel, sizeof(x->sel)); |
447 | memcpy(&x->lft, &p->lft, sizeof(x->lft)); | 447 | memcpy(&x->lft, &p->lft, sizeof(x->lft)); |
448 | x->props.mode = p->mode; | 448 | x->props.mode = p->mode; |
449 | x->props.replay_window = p->replay_window; | 449 | x->props.replay_window = min_t(unsigned int, p->replay_window, |
450 | sizeof(x->replay.bitmap) * 8); | ||
450 | x->props.reqid = p->reqid; | 451 | x->props.reqid = p->reqid; |
451 | x->props.family = p->family; | 452 | x->props.family = p->family; |
452 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); | 453 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); |
@@ -1856,7 +1857,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1856 | if (x->km.state != XFRM_STATE_VALID) | 1857 | if (x->km.state != XFRM_STATE_VALID) |
1857 | goto out; | 1858 | goto out; |
1858 | 1859 | ||
1859 | err = xfrm_replay_verify_len(x->replay_esn, rp); | 1860 | err = xfrm_replay_verify_len(x->replay_esn, re); |
1860 | if (err) | 1861 | if (err) |
1861 | goto out; | 1862 | goto out; |
1862 | 1863 | ||