summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/irda/af_irda.c3
-rw-r--r--net/key/af_key.c2
-rw-r--r--net/netlink/af_netlink.c6
-rw-r--r--net/sctp/ulpqueue.c9
4 files changed, 13 insertions, 7 deletions
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index eabd6838f50a..0eb7d596d470 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -138,7 +138,6 @@ static void irda_disconnect_indication(void *instance, void *sap,
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
- sock_orphan(sk);
release_sock(sk);
/* Close our TSAP.
@@ -1446,7 +1445,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
*/
ret = sock_error(sk);
if (ret)
- break;
+ ;
else if (sk->sk_shutdown & RCV_SHUTDOWN)
;
else if (noblock)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index cf77930ee516..345019345f09 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2072,7 +2072,7 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
rq->sadb_x_ipsecrequest_proto = t->id.proto;
if ((mode = pfkey_mode_from_xfrm(t->mode)) < 0)
return -EINVAL;
- mode = pfkey_mode_from_xfrm(t->mode);
+ rq->sadb_x_ipsecrequest_mode = mode;
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
if (t->reqid)
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index e73d8f546c6b..c48b0f49f003 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -443,6 +443,7 @@ static int netlink_release(struct socket *sock)
return 0;
netlink_remove(sk);
+ sock_orphan(sk);
nlk = nlk_sk(sk);
spin_lock(&nlk->cb_lock);
@@ -457,7 +458,6 @@ static int netlink_release(struct socket *sock)
/* OK. Socket is unlinked, and, therefore,
no new packets will arrive */
- sock_orphan(sk);
sock->sk = NULL;
wake_up_interruptible_all(&nlk->wait);
@@ -1412,9 +1412,9 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
return -ECONNREFUSED;
}
nlk = nlk_sk(sk);
- /* A dump is in progress... */
+ /* A dump or destruction is in progress... */
spin_lock(&nlk->cb_lock);
- if (nlk->cb) {
+ if (nlk->cb || sock_flag(sk, SOCK_DEAD)) {
spin_unlock(&nlk->cb_lock);
netlink_destroy_callback(cb);
sock_put(sk);
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index bfb197e37da3..b29e3e4b72c9 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -190,7 +190,14 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
if (!sctp_sk(sk)->pd_mode) {
queue = &sk->sk_receive_queue;
} else if (ulpq->pd_mode) {
- if (event->msg_flags & MSG_NOTIFICATION)
+ /* If the association is in partial delivery, we
+ * need to finish delivering the partially processed
+ * packet before passing any other data. This is
+ * because we don't truly support stream interleaving.
+ */
+ if ((event->msg_flags & MSG_NOTIFICATION) ||
+ (SCTP_DATA_NOT_FRAG ==
+ (event->msg_flags & SCTP_DATA_FRAG_MASK)))
queue = &sctp_sk(sk)->pd_lobby;
else {
clear_pd = event->msg_flags & MSG_EOR;