aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-02-05 08:36:43 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-05 19:00:03 -0500
commit3c724acdd5049907555a831f814bfd5927c3350c (patch)
treeccf441eecb318238d03e8fa86a7f803d6e3914c7 /net/tipc/socket.c
parent708ac32cb5e1305cf3670e147eedcc699d110ed0 (diff)
tipc: simplify socket multicast reception
The structure 'tipc_port_list' is used to collect port numbers representing multicast destination socket on a receiving node. The list is not based on a standard linked list, and is in reality optimized for the uncommon case that there are more than one multicast destinations per node. This makes the list handling unecessarily complex, and as a consequence, even the socket multicast reception becomes more complex. In this commit, we replace 'tipc_port_list' with a new 'struct tipc_plist', which is based on a standard list. We give the new list stack (push/pop) semantics, someting that simplifies the implementation of the function tipc_sk_mcast_rcv(). Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index c1a4611649ab..26aec8414ac1 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, 2012-2014, Ericsson AB 4 * Copyright (c) 2001-2007, 2012-2015, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -778,48 +778,42 @@ new_mtu:
778 778
779/* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets 779/* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets
780 */ 780 */
781void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf) 781void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *skb)
782{ 782{
783 struct tipc_msg *msg = buf_msg(buf); 783 struct tipc_msg *msg = buf_msg(skb);
784 struct tipc_port_list dports = {0, NULL, }; 784 struct tipc_plist dports;
785 struct tipc_port_list *item; 785 struct sk_buff *cskb;
786 struct sk_buff *b; 786 u32 portid;
787 uint i, last, dst = 0;
788 u32 scope = TIPC_CLUSTER_SCOPE; 787 u32 scope = TIPC_CLUSTER_SCOPE;
789 struct sk_buff_head msgs; 788 struct sk_buff_head msgq;
789 uint hsz = skb_headroom(skb) + msg_hdr_sz(msg);
790
791 skb_queue_head_init(&msgq);
792 tipc_plist_init(&dports);
790 793
791 if (in_own_node(net, msg_orignode(msg))) 794 if (in_own_node(net, msg_orignode(msg)))
792 scope = TIPC_NODE_SCOPE; 795 scope = TIPC_NODE_SCOPE;
793 796
794 if (unlikely(!msg_mcast(msg))) { 797 if (unlikely(!msg_mcast(msg))) {
795 pr_warn("Received non-multicast msg in multicast\n"); 798 pr_warn("Received non-multicast msg in multicast\n");
796 kfree_skb(buf);
797 goto exit; 799 goto exit;
798 } 800 }
799 /* Create destination port list: */ 801 /* Create destination port list: */
800 tipc_nametbl_mc_translate(net, msg_nametype(msg), msg_namelower(msg), 802 tipc_nametbl_mc_translate(net, msg_nametype(msg), msg_namelower(msg),
801 msg_nameupper(msg), scope, &dports); 803 msg_nameupper(msg), scope, &dports);
802 last = dports.count; 804 portid = tipc_plist_pop(&dports);
803 if (!last) { 805 for (; portid; portid = tipc_plist_pop(&dports)) {
804 kfree_skb(buf); 806 cskb = __pskb_copy(skb, hsz, GFP_ATOMIC);
805 return; 807 if (!cskb) {
806 } 808 pr_warn("Failed do clone mcast rcv buffer\n");
807 809 continue;
808 for (item = &dports; item; item = item->next) {
809 for (i = 0; i < PLSIZE && ++dst <= last; i++) {
810 b = (dst != last) ? skb_clone(buf, GFP_ATOMIC) : buf;
811 if (!b) {
812 pr_warn("Failed do clone mcast rcv buffer\n");
813 continue;
814 }
815 msg_set_destport(msg, item->ports[i]);
816 skb_queue_head_init(&msgs);
817 skb_queue_tail(&msgs, b);
818 tipc_sk_rcv(net, &msgs);
819 } 810 }
811 msg_set_destport(buf_msg(cskb), portid);
812 skb_queue_tail(&msgq, cskb);
820 } 813 }
814 tipc_sk_rcv(net, &msgq);
821exit: 815exit:
822 tipc_port_list_free(&dports); 816 kfree_skb(skb);
823} 817}
824 818
825/** 819/**