aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.h5
-rw-r--r--net/tipc/name_distr.c67
-rw-r--r--net/tipc/name_distr.h1
-rw-r--r--net/tipc/name_table.c5
-rw-r--r--net/tipc/node.c60
-rw-r--r--net/tipc/node.h3
6 files changed, 74 insertions, 67 deletions
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 18e95a8020cd..5504d63503df 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -118,6 +118,11 @@ static inline int tipc_netid(struct net *net)
118 return tipc_net(net)->net_id; 118 return tipc_net(net)->net_id;
119} 119}
120 120
121static inline struct list_head *tipc_nodes(struct net *net)
122{
123 return &tipc_net(net)->node_list;
124}
125
121static inline u16 mod(u16 x) 126static inline u16 mod(u16 x)
122{ 127{
123 return x & 0xffffu; 128 return x & 0xffffu;
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index f51c8bdbea1c..ebe9d0ff6e9e 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -84,31 +84,6 @@ static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
84 return buf; 84 return buf;
85} 85}
86 86
87void named_cluster_distribute(struct net *net, struct sk_buff *skb)
88{
89 struct tipc_net *tn = net_generic(net, tipc_net_id);
90 struct sk_buff *oskb;
91 struct tipc_node *node;
92 u32 dnode;
93
94 rcu_read_lock();
95 list_for_each_entry_rcu(node, &tn->node_list, list) {
96 dnode = node->addr;
97 if (in_own_node(net, dnode))
98 continue;
99 if (!tipc_node_is_up(node))
100 continue;
101 oskb = pskb_copy(skb, GFP_ATOMIC);
102 if (!oskb)
103 break;
104 msg_set_destnode(buf_msg(oskb), dnode);
105 tipc_node_xmit_skb(net, oskb, dnode, 0);
106 }
107 rcu_read_unlock();
108
109 kfree_skb(skb);
110}
111
112/** 87/**
113 * tipc_named_publish - tell other nodes about a new publication by this node 88 * tipc_named_publish - tell other nodes about a new publication by this node
114 */ 89 */
@@ -226,42 +201,6 @@ void tipc_named_node_up(struct net *net, u32 dnode)
226 tipc_node_xmit(net, &head, dnode, 0); 201 tipc_node_xmit(net, &head, dnode, 0);
227} 202}
228 203
229static void tipc_publ_subscribe(struct net *net, struct publication *publ,
230 u32 addr)
231{
232 struct tipc_node *node;
233
234 if (in_own_node(net, addr))
235 return;
236
237 node = tipc_node_find(net, addr);
238 if (!node) {
239 pr_warn("Node subscription rejected, unknown node 0x%x\n",
240 addr);
241 return;
242 }
243
244 tipc_node_lock(node);
245 list_add_tail(&publ->nodesub_list, &node->publ_list);
246 tipc_node_unlock(node);
247 tipc_node_put(node);
248}
249
250static void tipc_publ_unsubscribe(struct net *net, struct publication *publ,
251 u32 addr)
252{
253 struct tipc_node *node;
254
255 node = tipc_node_find(net, addr);
256 if (!node)
257 return;
258
259 tipc_node_lock(node);
260 list_del_init(&publ->nodesub_list);
261 tipc_node_unlock(node);
262 tipc_node_put(node);
263}
264
265/** 204/**
266 * tipc_publ_purge - remove publication associated with a failed node 205 * tipc_publ_purge - remove publication associated with a failed node
267 * 206 *
@@ -277,7 +216,7 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
277 p = tipc_nametbl_remove_publ(net, publ->type, publ->lower, 216 p = tipc_nametbl_remove_publ(net, publ->type, publ->lower,
278 publ->node, publ->ref, publ->key); 217 publ->node, publ->ref, publ->key);
279 if (p) 218 if (p)
280 tipc_publ_unsubscribe(net, p, addr); 219 tipc_node_unsubscribe(net, &p->nodesub_list, addr);
281 spin_unlock_bh(&tn->nametbl_lock); 220 spin_unlock_bh(&tn->nametbl_lock);
282 221
283 if (p != publ) { 222 if (p != publ) {
@@ -317,7 +256,7 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
317 TIPC_CLUSTER_SCOPE, node, 256 TIPC_CLUSTER_SCOPE, node,
318 ntohl(i->ref), ntohl(i->key)); 257 ntohl(i->ref), ntohl(i->key));
319 if (publ) { 258 if (publ) {
320 tipc_publ_subscribe(net, publ, node); 259 tipc_node_subscribe(net, &publ->nodesub_list, node);
321 return true; 260 return true;
322 } 261 }
323 } else if (dtype == WITHDRAWAL) { 262 } else if (dtype == WITHDRAWAL) {
@@ -326,7 +265,7 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
326 node, ntohl(i->ref), 265 node, ntohl(i->ref),
327 ntohl(i->key)); 266 ntohl(i->key));
328 if (publ) { 267 if (publ) {
329 tipc_publ_unsubscribe(net, publ, node); 268 tipc_node_unsubscribe(net, &publ->nodesub_list, node);
330 kfree_rcu(publ, rcu); 269 kfree_rcu(publ, rcu);
331 return true; 270 return true;
332 } 271 }
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index dd2d9fd80da2..1264ba0af937 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -69,7 +69,6 @@ struct distr_item {
69 69
70struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ); 70struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ);
71struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ); 71struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);
72void named_cluster_distribute(struct net *net, struct sk_buff *buf);
73void tipc_named_node_up(struct net *net, u32 dnode); 72void tipc_named_node_up(struct net *net, u32 dnode);
74void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue); 73void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue);
75void tipc_named_reinit(struct net *net); 74void tipc_named_reinit(struct net *net);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 0f47f08bf38f..91fce70291a8 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -42,6 +42,7 @@
42#include "subscr.h" 42#include "subscr.h"
43#include "bcast.h" 43#include "bcast.h"
44#include "addr.h" 44#include "addr.h"
45#include "node.h"
45#include <net/genetlink.h> 46#include <net/genetlink.h>
46 47
47#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ 48#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
@@ -677,7 +678,7 @@ struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
677 spin_unlock_bh(&tn->nametbl_lock); 678 spin_unlock_bh(&tn->nametbl_lock);
678 679
679 if (buf) 680 if (buf)
680 named_cluster_distribute(net, buf); 681 tipc_node_broadcast(net, buf);
681 return publ; 682 return publ;
682} 683}
683 684
@@ -709,7 +710,7 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref,
709 spin_unlock_bh(&tn->nametbl_lock); 710 spin_unlock_bh(&tn->nametbl_lock);
710 711
711 if (skb) { 712 if (skb) {
712 named_cluster_distribute(net, skb); 713 tipc_node_broadcast(net, skb);
713 return 1; 714 return 1;
714 } 715 }
715 return 0; 716 return 0;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 7756804034e2..932195258551 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -234,6 +234,42 @@ void tipc_node_stop(struct net *net)
234 spin_unlock_bh(&tn->node_list_lock); 234 spin_unlock_bh(&tn->node_list_lock);
235} 235}
236 236
237void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr)
238{
239 struct tipc_node *n;
240
241 if (in_own_node(net, addr))
242 return;
243
244 n = tipc_node_find(net, addr);
245 if (!n) {
246 pr_warn("Node subscribe rejected, unknown node 0x%x\n", addr);
247 return;
248 }
249 tipc_node_lock(n);
250 list_add_tail(subscr, &n->publ_list);
251 tipc_node_unlock(n);
252 tipc_node_put(n);
253}
254
255void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr)
256{
257 struct tipc_node *n;
258
259 if (in_own_node(net, addr))
260 return;
261
262 n = tipc_node_find(net, addr);
263 if (!n) {
264 pr_warn("Node unsubscribe rejected, unknown node 0x%x\n", addr);
265 return;
266 }
267 tipc_node_lock(n);
268 list_del_init(subscr);
269 tipc_node_unlock(n);
270 tipc_node_put(n);
271}
272
237int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port) 273int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port)
238{ 274{
239 struct tipc_node *node; 275 struct tipc_node *node;
@@ -1075,6 +1111,30 @@ int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
1075 return 0; 1111 return 0;
1076} 1112}
1077 1113
1114void tipc_node_broadcast(struct net *net, struct sk_buff *skb)
1115{
1116 struct sk_buff *txskb;
1117 struct tipc_node *n;
1118 u32 dst;
1119
1120 rcu_read_lock();
1121 list_for_each_entry_rcu(n, tipc_nodes(net), list) {
1122 dst = n->addr;
1123 if (in_own_node(net, dst))
1124 continue;
1125 if (!tipc_node_is_up(n))
1126 continue;
1127 txskb = pskb_copy(skb, GFP_ATOMIC);
1128 if (!txskb)
1129 break;
1130 msg_set_destnode(buf_msg(txskb), dst);
1131 tipc_node_xmit_skb(net, txskb, dst, 0);
1132 }
1133 rcu_read_unlock();
1134
1135 kfree_skb(skb);
1136}
1137
1078/** 1138/**
1079 * tipc_node_bc_rcv - process TIPC broadcast packet arriving from off-node 1139 * tipc_node_bc_rcv - process TIPC broadcast packet arriving from off-node
1080 * @net: the applicable net namespace 1140 * @net: the applicable net namespace
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 6734562d3c6e..dd79e9742bd6 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -149,6 +149,9 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
149 int selector); 149 int selector);
150int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest, 150int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,
151 u32 selector); 151 u32 selector);
152void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr);
153void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr);
154void tipc_node_broadcast(struct net *net, struct sk_buff *skb);
152int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port); 155int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
153void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port); 156void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
154int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); 157int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);