aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 536298c2eda2..a1d026f12b0e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -627,6 +627,12 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
627 retval = -EINVAL; 627 retval = -EINVAL;
628 goto err_bindx_rem; 628 goto err_bindx_rem;
629 } 629 }
630
631 if (!af->addr_valid(sa_addr, sp, NULL)) {
632 retval = -EADDRNOTAVAIL;
633 goto err_bindx_rem;
634 }
635
630 if (sa_addr->v4.sin_port != htons(bp->port)) { 636 if (sa_addr->v4.sin_port != htons(bp->port)) {
631 retval = -EINVAL; 637 retval = -EINVAL;
632 goto err_bindx_rem; 638 goto err_bindx_rem;
@@ -5638,6 +5644,36 @@ void sctp_wait_for_close(struct sock *sk, long timeout)
5638 finish_wait(sk->sk_sleep, &wait); 5644 finish_wait(sk->sk_sleep, &wait);
5639} 5645}
5640 5646
5647static void sctp_sock_rfree_frag(struct sk_buff *skb)
5648{
5649 struct sk_buff *frag;
5650
5651 if (!skb->data_len)
5652 goto done;
5653
5654 /* Don't forget the fragments. */
5655 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
5656 sctp_sock_rfree_frag(frag);
5657
5658done:
5659 sctp_sock_rfree(skb);
5660}
5661
5662static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk)
5663{
5664 struct sk_buff *frag;
5665
5666 if (!skb->data_len)
5667 goto done;
5668
5669 /* Don't forget the fragments. */
5670 for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
5671 sctp_skb_set_owner_r_frag(frag, sk);
5672
5673done:
5674 sctp_skb_set_owner_r(skb, sk);
5675}
5676
5641/* Populate the fields of the newsk from the oldsk and migrate the assoc 5677/* Populate the fields of the newsk from the oldsk and migrate the assoc
5642 * and its messages to the newsk. 5678 * and its messages to the newsk.
5643 */ 5679 */
@@ -5692,10 +5728,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5692 sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { 5728 sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
5693 event = sctp_skb2event(skb); 5729 event = sctp_skb2event(skb);
5694 if (event->asoc == assoc) { 5730 if (event->asoc == assoc) {
5695 sctp_sock_rfree(skb); 5731 sctp_sock_rfree_frag(skb);
5696 __skb_unlink(skb, &oldsk->sk_receive_queue); 5732 __skb_unlink(skb, &oldsk->sk_receive_queue);
5697 __skb_queue_tail(&newsk->sk_receive_queue, skb); 5733 __skb_queue_tail(&newsk->sk_receive_queue, skb);
5698 sctp_skb_set_owner_r(skb, newsk); 5734 sctp_skb_set_owner_r_frag(skb, newsk);
5699 } 5735 }
5700 } 5736 }
5701 5737
@@ -5723,10 +5759,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5723 sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { 5759 sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
5724 event = sctp_skb2event(skb); 5760 event = sctp_skb2event(skb);
5725 if (event->asoc == assoc) { 5761 if (event->asoc == assoc) {
5726 sctp_sock_rfree(skb); 5762 sctp_sock_rfree_frag(skb);
5727 __skb_unlink(skb, &oldsp->pd_lobby); 5763 __skb_unlink(skb, &oldsp->pd_lobby);
5728 __skb_queue_tail(queue, skb); 5764 __skb_queue_tail(queue, skb);
5729 sctp_skb_set_owner_r(skb, newsk); 5765 sctp_skb_set_owner_r_frag(skb, newsk);
5730 } 5766 }
5731 } 5767 }
5732 5768
@@ -5738,6 +5774,16 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5738 5774
5739 } 5775 }
5740 5776
5777 sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) {
5778 sctp_sock_rfree_frag(skb);
5779 sctp_skb_set_owner_r_frag(skb, newsk);
5780 }
5781
5782 sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) {
5783 sctp_sock_rfree_frag(skb);
5784 sctp_skb_set_owner_r_frag(skb, newsk);
5785 }
5786
5741 /* Set the type of socket to indicate that it is peeled off from the 5787 /* Set the type of socket to indicate that it is peeled off from the
5742 * original UDP-style socket or created with the accept() call on a 5788 * original UDP-style socket or created with the accept() call on a
5743 * TCP-style socket.. 5789 * TCP-style socket..