diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/core.h | 5 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 67 | ||||
-rw-r--r-- | net/tipc/name_distr.h | 1 | ||||
-rw-r--r-- | net/tipc/name_table.c | 5 | ||||
-rw-r--r-- | net/tipc/node.c | 60 | ||||
-rw-r--r-- | net/tipc/node.h | 3 |
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 | ||
121 | static inline struct list_head *tipc_nodes(struct net *net) | ||
122 | { | ||
123 | return &tipc_net(net)->node_list; | ||
124 | } | ||
125 | |||
121 | static inline u16 mod(u16 x) | 126 | static 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 | ||
87 | void 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 | ||
229 | static 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 | |||
250 | static 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 | ||
70 | struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ); | 70 | struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ); |
71 | struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ); | 71 | struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ); |
72 | void named_cluster_distribute(struct net *net, struct sk_buff *buf); | ||
73 | void tipc_named_node_up(struct net *net, u32 dnode); | 72 | void tipc_named_node_up(struct net *net, u32 dnode); |
74 | void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue); | 73 | void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue); |
75 | void tipc_named_reinit(struct net *net); | 74 | void 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 | ||
237 | void 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 | |||
255 | void 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 | |||
237 | int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port) | 273 | int 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 | ||
1114 | void 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); |
150 | int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest, | 150 | int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest, |
151 | u32 selector); | 151 | u32 selector); |
152 | void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr); | ||
153 | void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr); | ||
154 | void tipc_node_broadcast(struct net *net, struct sk_buff *skb); | ||
152 | int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port); | 155 | int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port); |
153 | void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port); | 156 | void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port); |
154 | int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); | 157 | int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); |