aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/sunrpc/sched.c33
-rw-r--r--net/sunrpc/xprt.c2
-rw-r--r--net/sunrpc/xprtsock.c23
-rw-r--r--net/xfrm/xfrm_state.c90
5 files changed, 100 insertions, 51 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index da944eca2ca..9c8309ed35c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -1192,6 +1192,9 @@ module_init(inet6_init);
1192 1192
1193static void __exit inet6_exit(void) 1193static void __exit inet6_exit(void)
1194{ 1194{
1195 if (disable_ipv6)
1196 return;
1197
1195 /* First of all disallow new sockets creation. */ 1198 /* First of all disallow new sockets creation. */
1196 sock_unregister(PF_INET6); 1199 sock_unregister(PF_INET6);
1197 /* Disallow any further netlink messages */ 1200 /* Disallow any further netlink messages */
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 385f427beda..ff50a054686 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -293,11 +293,6 @@ static void rpc_make_runnable(struct rpc_task *task)
293 rpc_clear_queued(task); 293 rpc_clear_queued(task);
294 if (rpc_test_and_set_running(task)) 294 if (rpc_test_and_set_running(task))
295 return; 295 return;
296 /* We might have raced */
297 if (RPC_IS_QUEUED(task)) {
298 rpc_clear_running(task);
299 return;
300 }
301 if (RPC_IS_ASYNC(task)) { 296 if (RPC_IS_ASYNC(task)) {
302 int status; 297 int status;
303 298
@@ -607,7 +602,9 @@ void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
607 */ 602 */
608static void __rpc_execute(struct rpc_task *task) 603static void __rpc_execute(struct rpc_task *task)
609{ 604{
610 int status = 0; 605 struct rpc_wait_queue *queue;
606 int task_is_async = RPC_IS_ASYNC(task);
607 int status = 0;
611 608
612 dprintk("RPC: %5u __rpc_execute flags=0x%x\n", 609 dprintk("RPC: %5u __rpc_execute flags=0x%x\n",
613 task->tk_pid, task->tk_flags); 610 task->tk_pid, task->tk_flags);
@@ -647,15 +644,25 @@ static void __rpc_execute(struct rpc_task *task)
647 */ 644 */
648 if (!RPC_IS_QUEUED(task)) 645 if (!RPC_IS_QUEUED(task))
649 continue; 646 continue;
650 rpc_clear_running(task); 647 /*
651 if (RPC_IS_ASYNC(task)) { 648 * The queue->lock protects against races with
652 /* Careful! we may have raced... */ 649 * rpc_make_runnable().
653 if (RPC_IS_QUEUED(task)) 650 *
654 return; 651 * Note that once we clear RPC_TASK_RUNNING on an asynchronous
655 if (rpc_test_and_set_running(task)) 652 * rpc_task, rpc_make_runnable() can assign it to a
656 return; 653 * different workqueue. We therefore cannot assume that the
654 * rpc_task pointer may still be dereferenced.
655 */
656 queue = task->tk_waitqueue;
657 spin_lock_bh(&queue->lock);
658 if (!RPC_IS_QUEUED(task)) {
659 spin_unlock_bh(&queue->lock);
657 continue; 660 continue;
658 } 661 }
662 rpc_clear_running(task);
663 spin_unlock_bh(&queue->lock);
664 if (task_is_async)
665 return;
659 666
660 /* sync task: sleep here */ 667 /* sync task: sleep here */
661 dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid); 668 dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 29e401bb612..62098d101a1 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -663,7 +663,7 @@ void xprt_connect(struct rpc_task *task)
663 xprt, (xprt_connected(xprt) ? "is" : "is not")); 663 xprt, (xprt_connected(xprt) ? "is" : "is not"));
664 664
665 if (!xprt_bound(xprt)) { 665 if (!xprt_bound(xprt)) {
666 task->tk_status = -EIO; 666 task->tk_status = -EAGAIN;
667 return; 667 return;
668 } 668 }
669 if (!xprt_lock_write(xprt, task)) 669 if (!xprt_lock_write(xprt, task))
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 5cbb404c4cd..29c71e645b2 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -467,7 +467,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
467 int err, sent = 0; 467 int err, sent = 0;
468 468
469 if (unlikely(!sock)) 469 if (unlikely(!sock))
470 return -ENOTCONN; 470 return -ENOTSOCK;
471 471
472 clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); 472 clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
473 if (base != 0) { 473 if (base != 0) {
@@ -577,6 +577,8 @@ static int xs_udp_send_request(struct rpc_task *task)
577 req->rq_svec->iov_base, 577 req->rq_svec->iov_base,
578 req->rq_svec->iov_len); 578 req->rq_svec->iov_len);
579 579
580 if (!xprt_bound(xprt))
581 return -ENOTCONN;
580 status = xs_sendpages(transport->sock, 582 status = xs_sendpages(transport->sock,
581 xs_addr(xprt), 583 xs_addr(xprt),
582 xprt->addrlen, xdr, 584 xprt->addrlen, xdr,
@@ -594,6 +596,10 @@ static int xs_udp_send_request(struct rpc_task *task)
594 } 596 }
595 597
596 switch (status) { 598 switch (status) {
599 case -ENOTSOCK:
600 status = -ENOTCONN;
601 /* Should we call xs_close() here? */
602 break;
597 case -EAGAIN: 603 case -EAGAIN:
598 xs_nospace(task); 604 xs_nospace(task);
599 break; 605 break;
@@ -693,6 +699,10 @@ static int xs_tcp_send_request(struct rpc_task *task)
693 } 699 }
694 700
695 switch (status) { 701 switch (status) {
702 case -ENOTSOCK:
703 status = -ENOTCONN;
704 /* Should we call xs_close() here? */
705 break;
696 case -EAGAIN: 706 case -EAGAIN:
697 xs_nospace(task); 707 xs_nospace(task);
698 break; 708 break;
@@ -1523,7 +1533,7 @@ static void xs_udp_connect_worker4(struct work_struct *work)
1523 struct socket *sock = transport->sock; 1533 struct socket *sock = transport->sock;
1524 int err, status = -EIO; 1534 int err, status = -EIO;
1525 1535
1526 if (xprt->shutdown || !xprt_bound(xprt)) 1536 if (xprt->shutdown)
1527 goto out; 1537 goto out;
1528 1538
1529 /* Start by resetting any existing state */ 1539 /* Start by resetting any existing state */
@@ -1564,7 +1574,7 @@ static void xs_udp_connect_worker6(struct work_struct *work)
1564 struct socket *sock = transport->sock; 1574 struct socket *sock = transport->sock;
1565 int err, status = -EIO; 1575 int err, status = -EIO;
1566 1576
1567 if (xprt->shutdown || !xprt_bound(xprt)) 1577 if (xprt->shutdown)
1568 goto out; 1578 goto out;
1569 1579
1570 /* Start by resetting any existing state */ 1580 /* Start by resetting any existing state */
@@ -1648,6 +1658,9 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1648 write_unlock_bh(&sk->sk_callback_lock); 1658 write_unlock_bh(&sk->sk_callback_lock);
1649 } 1659 }
1650 1660
1661 if (!xprt_bound(xprt))
1662 return -ENOTCONN;
1663
1651 /* Tell the socket layer to start connecting... */ 1664 /* Tell the socket layer to start connecting... */
1652 xprt->stat.connect_count++; 1665 xprt->stat.connect_count++;
1653 xprt->stat.connect_start = jiffies; 1666 xprt->stat.connect_start = jiffies;
@@ -1668,7 +1681,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
1668 struct socket *sock = transport->sock; 1681 struct socket *sock = transport->sock;
1669 int err, status = -EIO; 1682 int err, status = -EIO;
1670 1683
1671 if (xprt->shutdown || !xprt_bound(xprt)) 1684 if (xprt->shutdown)
1672 goto out; 1685 goto out;
1673 1686
1674 if (!sock) { 1687 if (!sock) {
@@ -1728,7 +1741,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
1728 struct socket *sock = transport->sock; 1741 struct socket *sock = transport->sock;
1729 int err, status = -EIO; 1742 int err, status = -EIO;
1730 1743
1731 if (xprt->shutdown || !xprt_bound(xprt)) 1744 if (xprt->shutdown)
1732 goto out; 1745 goto out;
1733 1746
1734 if (!sock) { 1747 if (!sock) {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index e25ff62ab2a..62a5425cc6a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -748,12 +748,51 @@ static void xfrm_hash_grow_check(struct net *net, int have_hash_collision)
748 schedule_work(&net->xfrm.state_hash_work); 748 schedule_work(&net->xfrm.state_hash_work);
749} 749}
750 750
751static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
752 struct flowi *fl, unsigned short family,
753 xfrm_address_t *daddr, xfrm_address_t *saddr,
754 struct xfrm_state **best, int *acq_in_progress,
755 int *error)
756{
757 /* Resolution logic:
758 * 1. There is a valid state with matching selector. Done.
759 * 2. Valid state with inappropriate selector. Skip.
760 *
761 * Entering area of "sysdeps".
762 *
763 * 3. If state is not valid, selector is temporary, it selects
764 * only session which triggered previous resolution. Key
765 * manager will do something to install a state with proper
766 * selector.
767 */
768 if (x->km.state == XFRM_STATE_VALID) {
769 if ((x->sel.family &&
770 !xfrm_selector_match(&x->sel, fl, x->sel.family)) ||
771 !security_xfrm_state_pol_flow_match(x, pol, fl))
772 return;
773
774 if (!*best ||
775 (*best)->km.dying > x->km.dying ||
776 ((*best)->km.dying == x->km.dying &&
777 (*best)->curlft.add_time < x->curlft.add_time))
778 *best = x;
779 } else if (x->km.state == XFRM_STATE_ACQ) {
780 *acq_in_progress = 1;
781 } else if (x->km.state == XFRM_STATE_ERROR ||
782 x->km.state == XFRM_STATE_EXPIRED) {
783 if (xfrm_selector_match(&x->sel, fl, x->sel.family) &&
784 security_xfrm_state_pol_flow_match(x, pol, fl))
785 *error = -ESRCH;
786 }
787}
788
751struct xfrm_state * 789struct xfrm_state *
752xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 790xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
753 struct flowi *fl, struct xfrm_tmpl *tmpl, 791 struct flowi *fl, struct xfrm_tmpl *tmpl,
754 struct xfrm_policy *pol, int *err, 792 struct xfrm_policy *pol, int *err,
755 unsigned short family) 793 unsigned short family)
756{ 794{
795 static xfrm_address_t saddr_wildcard = { };
757 struct net *net = xp_net(pol); 796 struct net *net = xp_net(pol);
758 unsigned int h; 797 unsigned int h;
759 struct hlist_node *entry; 798 struct hlist_node *entry;
@@ -773,40 +812,27 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
773 xfrm_state_addr_check(x, daddr, saddr, family) && 812 xfrm_state_addr_check(x, daddr, saddr, family) &&
774 tmpl->mode == x->props.mode && 813 tmpl->mode == x->props.mode &&
775 tmpl->id.proto == x->id.proto && 814 tmpl->id.proto == x->id.proto &&
776 (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) { 815 (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
777 /* Resolution logic: 816 xfrm_state_look_at(pol, x, fl, family, daddr, saddr,
778 1. There is a valid state with matching selector. 817 &best, &acquire_in_progress, &error);
779 Done. 818 }
780 2. Valid state with inappropriate selector. Skip. 819 if (best)
781 820 goto found;
782 Entering area of "sysdeps". 821
783 822 h = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family);
784 3. If state is not valid, selector is temporary, 823 hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) {
785 it selects only session which triggered 824 if (x->props.family == family &&
786 previous resolution. Key manager will do 825 x->props.reqid == tmpl->reqid &&
787 something to install a state with proper 826 !(x->props.flags & XFRM_STATE_WILDRECV) &&
788 selector. 827 xfrm_state_addr_check(x, daddr, saddr, family) &&
789 */ 828 tmpl->mode == x->props.mode &&
790 if (x->km.state == XFRM_STATE_VALID) { 829 tmpl->id.proto == x->id.proto &&
791 if ((x->sel.family && !xfrm_selector_match(&x->sel, fl, x->sel.family)) || 830 (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
792 !security_xfrm_state_pol_flow_match(x, pol, fl)) 831 xfrm_state_look_at(pol, x, fl, family, daddr, saddr,
793 continue; 832 &best, &acquire_in_progress, &error);
794 if (!best ||
795 best->km.dying > x->km.dying ||
796 (best->km.dying == x->km.dying &&
797 best->curlft.add_time < x->curlft.add_time))
798 best = x;
799 } else if (x->km.state == XFRM_STATE_ACQ) {
800 acquire_in_progress = 1;
801 } else if (x->km.state == XFRM_STATE_ERROR ||
802 x->km.state == XFRM_STATE_EXPIRED) {
803 if (xfrm_selector_match(&x->sel, fl, x->sel.family) &&
804 security_xfrm_state_pol_flow_match(x, pol, fl))
805 error = -ESRCH;
806 }
807 }
808 } 833 }
809 834
835found:
810 x = best; 836 x = best;
811 if (!x && !error && !acquire_in_progress) { 837 if (!x && !error && !acquire_in_progress) {
812 if (tmpl->id.spi && 838 if (tmpl->id.spi &&