aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c49
-rw-r--r--net/tipc/bcast.h24
-rw-r--r--net/tipc/name_table.c44
-rw-r--r--net/tipc/name_table.h18
-rw-r--r--net/tipc/socket.c48
-rw-r--r--net/tipc/socket.h2
6 files changed, 84 insertions, 101 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 2dfaf272928a..3eaa931e2e8c 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/bcast.c: TIPC broadcast code 2 * net/tipc/bcast.c: TIPC broadcast code
3 * 3 *
4 * Copyright (c) 2004-2006, 2014, Ericsson AB 4 * Copyright (c) 2004-2006, 2014-2015, Ericsson AB
5 * Copyright (c) 2004, Intel Corporation. 5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) 2005, 2010-2011, Wind River Systems 6 * Copyright (c) 2005, 2010-2011, Wind River Systems
7 * All rights reserved. 7 * All rights reserved.
@@ -1037,50 +1037,3 @@ static void tipc_nmap_diff(struct tipc_node_map *nm_a,
1037 } 1037 }
1038 } 1038 }
1039} 1039}
1040
1041/**
1042 * tipc_port_list_add - add a port to a port list, ensuring no duplicates
1043 */
1044void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port)
1045{
1046 struct tipc_port_list *item = pl_ptr;
1047 int i;
1048 int item_sz = PLSIZE;
1049 int cnt = pl_ptr->count;
1050
1051 for (; ; cnt -= item_sz, item = item->next) {
1052 if (cnt < PLSIZE)
1053 item_sz = cnt;
1054 for (i = 0; i < item_sz; i++)
1055 if (item->ports[i] == port)
1056 return;
1057 if (i < PLSIZE) {
1058 item->ports[i] = port;
1059 pl_ptr->count++;
1060 return;
1061 }
1062 if (!item->next) {
1063 item->next = kmalloc(sizeof(*item), GFP_ATOMIC);
1064 if (!item->next) {
1065 pr_warn("Incomplete multicast delivery, no memory\n");
1066 return;
1067 }
1068 item->next->next = NULL;
1069 }
1070 }
1071}
1072
1073/**
1074 * tipc_port_list_free - free dynamically created entries in port_list chain
1075 *
1076 */
1077void tipc_port_list_free(struct tipc_port_list *pl_ptr)
1078{
1079 struct tipc_port_list *item;
1080 struct tipc_port_list *next;
1081
1082 for (item = pl_ptr->next; item; item = next) {
1083 next = item->next;
1084 kfree(item);
1085 }
1086}
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 6ea190dccfe1..8f4d4dc38e11 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/bcast.h: Include file for TIPC broadcast code 2 * net/tipc/bcast.h: Include file for TIPC broadcast code
3 * 3 *
4 * Copyright (c) 2003-2006, 2014, Ericsson AB 4 * Copyright (c) 2003-2006, 2014-2015, Ericsson AB
5 * Copyright (c) 2005, 2010-2011, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -41,22 +41,6 @@
41#include "link.h" 41#include "link.h"
42#include "node.h" 42#include "node.h"
43 43
44#define TIPC_BCLINK_RESET 1
45#define PLSIZE 32
46#define BCBEARER MAX_BEARERS
47
48/**
49 * struct tipc_port_list - set of node local destination ports
50 * @count: # of ports in set (only valid for first entry in list)
51 * @next: pointer to next entry in list
52 * @ports: array of port references
53 */
54struct tipc_port_list {
55 int count;
56 struct tipc_port_list *next;
57 u32 ports[PLSIZE];
58};
59
60/** 44/**
61 * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link 45 * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link
62 * @primary: pointer to primary bearer 46 * @primary: pointer to primary bearer
@@ -71,6 +55,9 @@ struct tipc_bcbearer_pair {
71 struct tipc_bearer *secondary; 55 struct tipc_bearer *secondary;
72}; 56};
73 57
58#define TIPC_BCLINK_RESET 1
59#define BCBEARER MAX_BEARERS
60
74/** 61/**
75 * struct tipc_bcbearer - bearer used by broadcast link 62 * struct tipc_bcbearer - bearer used by broadcast link
76 * @bearer: (non-standard) broadcast bearer structure 63 * @bearer: (non-standard) broadcast bearer structure
@@ -126,9 +113,6 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a,
126 return !memcmp(nm_a, nm_b, sizeof(*nm_a)); 113 return !memcmp(nm_a, nm_b, sizeof(*nm_a));
127} 114}
128 115
129void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port);
130void tipc_port_list_free(struct tipc_port_list *pl_ptr);
131
132int tipc_bclink_init(struct net *net); 116int tipc_bclink_init(struct net *net);
133void tipc_bclink_stop(struct net *net); 117void tipc_bclink_stop(struct net *net);
134void tipc_bclink_set_flags(struct net *tn, unsigned int flags); 118void tipc_bclink_set_flags(struct net *tn, unsigned int flags);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index ce09b863528c..18a3d44238bc 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/name_table.c: TIPC name table code 2 * net/tipc/name_table.c: TIPC name table code
3 * 3 *
4 * Copyright (c) 2000-2006, 2014, Ericsson AB 4 * Copyright (c) 2000-2006, 2014-2015, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2014, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2014, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -618,7 +618,7 @@ not_found:
618 * Returns non-zero if any off-node ports overlap 618 * Returns non-zero if any off-node ports overlap
619 */ 619 */
620int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, 620int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
621 u32 limit, struct tipc_port_list *dports) 621 u32 limit, struct tipc_plist *dports)
622{ 622{
623 struct name_seq *seq; 623 struct name_seq *seq;
624 struct sub_seq *sseq; 624 struct sub_seq *sseq;
@@ -643,7 +643,7 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
643 info = sseq->info; 643 info = sseq->info;
644 list_for_each_entry(publ, &info->node_list, node_list) { 644 list_for_each_entry(publ, &info->node_list, node_list) {
645 if (publ->scope <= limit) 645 if (publ->scope <= limit)
646 tipc_port_list_add(dports, publ->ref); 646 tipc_plist_push(dports, publ->ref);
647 } 647 }
648 648
649 if (info->cluster_list_size != info->node_list_size) 649 if (info->cluster_list_size != info->node_list_size)
@@ -1212,3 +1212,41 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
1212 1212
1213 return skb->len; 1213 return skb->len;
1214} 1214}
1215
1216void tipc_plist_push(struct tipc_plist *pl, u32 port)
1217{
1218 struct tipc_plist *nl;
1219
1220 if (likely(!pl->port)) {
1221 pl->port = port;
1222 return;
1223 }
1224 if (pl->port == port)
1225 return;
1226 list_for_each_entry(nl, &pl->list, list) {
1227 if (nl->port == port)
1228 return;
1229 }
1230 nl = kmalloc(sizeof(*nl), GFP_ATOMIC);
1231 if (nl) {
1232 nl->port = port;
1233 list_add(&nl->list, &pl->list);
1234 }
1235}
1236
1237u32 tipc_plist_pop(struct tipc_plist *pl)
1238{
1239 struct tipc_plist *nl;
1240 u32 port = 0;
1241
1242 if (likely(list_empty(&pl->list))) {
1243 port = pl->port;
1244 pl->port = 0;
1245 return port;
1246 }
1247 nl = list_first_entry(&pl->list, typeof(*nl), list);
1248 port = nl->port;
1249 list_del(&nl->list);
1250 kfree(nl);
1251 return port;
1252}
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index f67b3d8d4b2f..52501fdaafa5 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -38,7 +38,7 @@
38#define _TIPC_NAME_TABLE_H 38#define _TIPC_NAME_TABLE_H
39 39
40struct tipc_subscription; 40struct tipc_subscription;
41struct tipc_port_list; 41struct tipc_plist;
42 42
43/* 43/*
44 * TIPC name types reserved for internal TIPC use (both current and planned) 44 * TIPC name types reserved for internal TIPC use (both current and planned)
@@ -101,7 +101,7 @@ struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area,
101 int req_tlv_space); 101 int req_tlv_space);
102u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); 102u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node);
103int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, 103int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
104 u32 limit, struct tipc_port_list *dports); 104 u32 limit, struct tipc_plist *dports);
105struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, 105struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
106 u32 upper, u32 scope, u32 port_ref, 106 u32 upper, u32 scope, u32 port_ref,
107 u32 key); 107 u32 key);
@@ -118,4 +118,18 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
118int tipc_nametbl_init(struct net *net); 118int tipc_nametbl_init(struct net *net);
119void tipc_nametbl_stop(struct net *net); 119void tipc_nametbl_stop(struct net *net);
120 120
121struct tipc_plist {
122 struct list_head list;
123 u32 port;
124};
125
126static inline void tipc_plist_init(struct tipc_plist *pl)
127{
128 INIT_LIST_HEAD(&pl->list);
129 pl->port = 0;
130}
131
132void tipc_plist_push(struct tipc_plist *pl, u32 port);
133u32 tipc_plist_pop(struct tipc_plist *pl);
134
121#endif 135#endif
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/**
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index e3dbdc0e1be7..95b015909ac1 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -1,6 +1,6 @@
1/* net/tipc/socket.h: Include file for TIPC socket code 1/* net/tipc/socket.h: Include file for TIPC socket code
2 * 2 *
3 * Copyright (c) 2014, Ericsson AB 3 * Copyright (c) 2014-2015, Ericsson AB
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without