aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/bcast.c5
-rw-r--r--net/tipc/link.c23
-rw-r--r--net/tipc/socket.c49
3 files changed, 37 insertions, 40 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 59b2f2a538e1..295bdc26f103 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -358,10 +358,9 @@ int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)
358 358
359 /* Prepare clone of message for local node */ 359 /* Prepare clone of message for local node */
360 skb = tipc_msg_reassemble(list); 360 skb = tipc_msg_reassemble(list);
361 if (unlikely(!skb)) { 361 if (unlikely(!skb))
362 __skb_queue_purge(list);
363 return -EHOSTUNREACH; 362 return -EHOSTUNREACH;
364 } 363
365 /* Broadcast to all nodes */ 364 /* Broadcast to all nodes */
366 if (likely(bclink)) { 365 if (likely(bclink)) {
367 tipc_bclink_lock(net); 366 tipc_bclink_lock(net);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index f8e0e2ceceb4..ea32679b6737 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -340,7 +340,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id)
340 * @link: congested link 340 * @link: congested link
341 * @list: message that was attempted sent 341 * @list: message that was attempted sent
342 * Create pseudo msg to send back to user when congestion abates 342 * Create pseudo msg to send back to user when congestion abates
343 * Only consumes message if there is an error 343 * Does not consume buffer list
344 */ 344 */
345static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) 345static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
346{ 346{
@@ -354,7 +354,7 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
354 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) { 354 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
355 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name); 355 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name);
356 tipc_link_reset(link); 356 tipc_link_reset(link);
357 goto err; 357 return -ENOBUFS;
358 } 358 }
359 /* Non-blocking sender: */ 359 /* Non-blocking sender: */
360 if (TIPC_SKB_CB(skb_peek(list))->wakeup_pending) 360 if (TIPC_SKB_CB(skb_peek(list))->wakeup_pending)
@@ -364,15 +364,12 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
364 skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, 364 skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0,
365 addr, addr, oport, 0, 0); 365 addr, addr, oport, 0, 0);
366 if (!skb) 366 if (!skb)
367 goto err; 367 return -ENOBUFS;
368 TIPC_SKB_CB(skb)->chain_sz = skb_queue_len(list); 368 TIPC_SKB_CB(skb)->chain_sz = skb_queue_len(list);
369 TIPC_SKB_CB(skb)->chain_imp = imp; 369 TIPC_SKB_CB(skb)->chain_imp = imp;
370 skb_queue_tail(&link->wakeupq, skb); 370 skb_queue_tail(&link->wakeupq, skb);
371 link->stats.link_congs++; 371 link->stats.link_congs++;
372 return -ELINKCONG; 372 return -ELINKCONG;
373err:
374 __skb_queue_purge(list);
375 return -ENOBUFS;
376} 373}
377 374
378/** 375/**
@@ -641,8 +638,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
641 * @link: link to use 638 * @link: link to use
642 * @list: chain of buffers containing message 639 * @list: chain of buffers containing message
643 * 640 *
644 * Consumes the buffer chain, except when returning -ELINKCONG, 641 * Consumes the buffer chain, except when returning an error code,
645 * since the caller then may want to make more send attempts.
646 * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS 642 * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS
647 * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted 643 * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted
648 */ 644 */
@@ -666,10 +662,9 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
666 if (unlikely(link->backlog[i].len >= link->backlog[i].limit)) 662 if (unlikely(link->backlog[i].len >= link->backlog[i].limit))
667 return link_schedule_user(link, list); 663 return link_schedule_user(link, list);
668 } 664 }
669 if (unlikely(msg_size(msg) > mtu)) { 665 if (unlikely(msg_size(msg) > mtu))
670 __skb_queue_purge(list);
671 return -EMSGSIZE; 666 return -EMSGSIZE;
672 } 667
673 /* Prepare each packet for sending, and add to relevant queue: */ 668 /* Prepare each packet for sending, and add to relevant queue: */
674 while (skb_queue_len(list)) { 669 while (skb_queue_len(list)) {
675 skb = skb_peek(list); 670 skb = skb_peek(list);
@@ -722,7 +717,7 @@ static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb)
722 717
723/* tipc_link_xmit_skb(): send single buffer to destination 718/* tipc_link_xmit_skb(): send single buffer to destination
724 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE 719 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
725 * messages, which will not be rejected 720 * messages, which will not cause link congestion
726 * The only exception is datagram messages rerouted after secondary 721 * The only exception is datagram messages rerouted after secondary
727 * lookup, which are rare and safe to dispose of anyway. 722 * lookup, which are rare and safe to dispose of anyway.
728 * TODO: Return real return value, and let callers use 723 * TODO: Return real return value, and let callers use
@@ -736,7 +731,7 @@ int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
736 731
737 skb2list(skb, &head); 732 skb2list(skb, &head);
738 rc = tipc_link_xmit(net, &head, dnode, selector); 733 rc = tipc_link_xmit(net, &head, dnode, selector);
739 if (rc == -ELINKCONG) 734 if (rc)
740 kfree_skb(skb); 735 kfree_skb(skb);
741 return 0; 736 return 0;
742} 737}
@@ -748,7 +743,7 @@ int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
748 * @dsz: amount of user data to be sent 743 * @dsz: amount of user data to be sent
749 * @dnode: address of destination node 744 * @dnode: address of destination node
750 * @selector: a number used for deterministic link selection 745 * @selector: a number used for deterministic link selection
751 * Consumes the buffer chain, except when returning -ELINKCONG 746 * Consumes the buffer chain, except when returning error
752 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE 747 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
753 */ 748 */
754int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, 749int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 3a7567f690f3..87fef25f6519 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -686,21 +686,22 @@ new_mtu:
686 686
687 do { 687 do {
688 rc = tipc_bclink_xmit(net, pktchain); 688 rc = tipc_bclink_xmit(net, pktchain);
689 if (likely(rc >= 0)) { 689 if (likely(!rc))
690 rc = dsz; 690 return dsz;
691 break; 691
692 if (rc == -ELINKCONG) {
693 tsk->link_cong = 1;
694 rc = tipc_wait_for_sndmsg(sock, &timeo);
695 if (!rc)
696 continue;
692 } 697 }
698 __skb_queue_purge(pktchain);
693 if (rc == -EMSGSIZE) { 699 if (rc == -EMSGSIZE) {
694 msg->msg_iter = save; 700 msg->msg_iter = save;
695 goto new_mtu; 701 goto new_mtu;
696 } 702 }
697 if (rc != -ELINKCONG) 703 break;
698 break; 704 } while (1);
699 tipc_sk(sk)->link_cong = 1;
700 rc = tipc_wait_for_sndmsg(sock, &timeo);
701 if (rc)
702 __skb_queue_purge(pktchain);
703 } while (!rc);
704 return rc; 705 return rc;
705} 706}
706 707
@@ -925,23 +926,24 @@ new_mtu:
925 skb = skb_peek(pktchain); 926 skb = skb_peek(pktchain);
926 TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong; 927 TIPC_SKB_CB(skb)->wakeup_pending = tsk->link_cong;
927 rc = tipc_link_xmit(net, pktchain, dnode, tsk->portid); 928 rc = tipc_link_xmit(net, pktchain, dnode, tsk->portid);
928 if (likely(rc >= 0)) { 929 if (likely(!rc)) {
929 if (sock->state != SS_READY) 930 if (sock->state != SS_READY)
930 sock->state = SS_CONNECTING; 931 sock->state = SS_CONNECTING;
931 rc = dsz; 932 return dsz;
932 break;
933 } 933 }
934 if (rc == -ELINKCONG) {
935 tsk->link_cong = 1;
936 rc = tipc_wait_for_sndmsg(sock, &timeo);
937 if (!rc)
938 continue;
939 }
940 __skb_queue_purge(pktchain);
934 if (rc == -EMSGSIZE) { 941 if (rc == -EMSGSIZE) {
935 m->msg_iter = save; 942 m->msg_iter = save;
936 goto new_mtu; 943 goto new_mtu;
937 } 944 }
938 if (rc != -ELINKCONG) 945 break;
939 break; 946 } while (1);
940 tsk->link_cong = 1;
941 rc = tipc_wait_for_sndmsg(sock, &timeo);
942 if (rc)
943 __skb_queue_purge(pktchain);
944 } while (!rc);
945 947
946 return rc; 948 return rc;
947} 949}
@@ -1048,10 +1050,11 @@ next:
1048 tsk->sent_unacked++; 1050 tsk->sent_unacked++;
1049 sent += send; 1051 sent += send;
1050 if (sent == dsz) 1052 if (sent == dsz)
1051 break; 1053 return dsz;
1052 goto next; 1054 goto next;
1053 } 1055 }
1054 if (rc == -EMSGSIZE) { 1056 if (rc == -EMSGSIZE) {
1057 __skb_queue_purge(pktchain);
1055 tsk->max_pkt = tipc_node_get_mtu(net, dnode, 1058 tsk->max_pkt = tipc_node_get_mtu(net, dnode,
1056 portid); 1059 portid);
1057 m->msg_iter = save; 1060 m->msg_iter = save;
@@ -1059,13 +1062,13 @@ next:
1059 } 1062 }
1060 if (rc != -ELINKCONG) 1063 if (rc != -ELINKCONG)
1061 break; 1064 break;
1065
1062 tsk->link_cong = 1; 1066 tsk->link_cong = 1;
1063 } 1067 }
1064 rc = tipc_wait_for_sndpkt(sock, &timeo); 1068 rc = tipc_wait_for_sndpkt(sock, &timeo);
1065 if (rc)
1066 __skb_queue_purge(pktchain);
1067 } while (!rc); 1069 } while (!rc);
1068 1070
1071 __skb_queue_purge(pktchain);
1069 return sent ? sent : rc; 1072 return sent ? sent : rc;
1070} 1073}
1071 1074