Blame view

net/tipc/name_distr.c 9.23 KB
b97bf3fd8   Per Liden   [TIPC] Initial merge
1
2
  /*
   * net/tipc/name_distr.c: TIPC name distribution code
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
3
   *
593a5f22d   Per Liden   [TIPC] More updat...
4
   * Copyright (c) 2000-2006, Ericsson AB
431697eb6   Allan Stephens   tipc: Prevent nul...
5
   * Copyright (c) 2005, 2010-2011, Wind River Systems
b97bf3fd8   Per Liden   [TIPC] Initial merge
6
7
   * All rights reserved.
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
8
   * Redistribution and use in source and binary forms, with or without
b97bf3fd8   Per Liden   [TIPC] Initial merge
9
10
   * modification, are permitted provided that the following conditions are met:
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
11
12
13
14
15
16
17
18
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 3. Neither the names of the copyright holders nor the names of its
   *    contributors may be used to endorse or promote products derived from
   *    this software without specific prior written permission.
b97bf3fd8   Per Liden   [TIPC] Initial merge
19
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
b97bf3fd8   Per Liden   [TIPC] Initial merge
34
35
36
37
   * POSSIBILITY OF SUCH DAMAGE.
   */
  
  #include "core.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
38
  #include "link.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
39
  #include "name_distr.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
40
41
42
43
44
45
46
47
48
  #define ITEM_SIZE sizeof(struct distr_item)
  
  /**
   * struct distr_item - publication info distributed to other nodes
   * @type: name sequence type
   * @lower: name sequence lower bound
   * @upper: name sequence upper bound
   * @ref: publishing port reference
   * @key: publication key
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
49
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
50
   * ===> All fields are stored in network byte order. <===
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
51
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
52
53
54
55
   * First 3 fields identify (name or) name sequence being published.
   * Reference field uniquely identifies port that published name sequence.
   * Key field uniquely identifies publication, in the event a port has
   * multiple publications of the same name sequence.
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
56
57
   *
   * Note: There is no field that identifies the publishing node because it is
b97bf3fd8   Per Liden   [TIPC] Initial merge
58
59
60
61
   * the same for all items contained within a publication message.
   */
  
  struct distr_item {
3e6c8cd56   Al Viro   [TIPC]: endiannes...
62
63
64
65
66
  	__be32 type;
  	__be32 lower;
  	__be32 upper;
  	__be32 ref;
  	__be32 key;
b97bf3fd8   Per Liden   [TIPC] Initial merge
67
68
69
  };
  
  /**
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
70
   * List of externally visible publications by this node --
b97bf3fd8   Per Liden   [TIPC] Initial merge
71
72
73
74
   * that is, all publications having scope > TIPC_NODE_SCOPE.
   */
  
  static LIST_HEAD(publ_root);
e3ec9c7d5   Allan Stephens   tipc: remove zero...
75
  static u32 publ_cnt;
b97bf3fd8   Per Liden   [TIPC] Initial merge
76
77
78
79
80
81
82
83
84
85
86
87
  
  /**
   * publ_to_item - add publication info to a publication message
   */
  
  static void publ_to_item(struct distr_item *i, struct publication *p)
  {
  	i->type = htonl(p->type);
  	i->lower = htonl(p->lower);
  	i->upper = htonl(p->upper);
  	i->ref = htonl(p->ref);
  	i->key = htonl(p->key);
b97bf3fd8   Per Liden   [TIPC] Initial merge
88
89
90
91
92
93
94
95
  }
  
  /**
   * named_prepare_buf - allocate & initialize a publication message
   */
  
  static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
  {
741d9eb7b   Allan Stephens   tipc: Cleanup of ...
96
  	struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size);
b97bf3fd8   Per Liden   [TIPC] Initial merge
97
98
99
100
  	struct tipc_msg *msg;
  
  	if (buf != NULL) {
  		msg = buf_msg(buf);
741d9eb7b   Allan Stephens   tipc: Cleanup of ...
101
102
  		tipc_msg_init(msg, NAME_DISTRIBUTOR, type, INT_H_SIZE, dest);
  		msg_set_size(msg, INT_H_SIZE + size);
b97bf3fd8   Per Liden   [TIPC] Initial merge
103
104
105
  	}
  	return buf;
  }
8f92df6ad   Allan Stephens   tipc: Remove prot...
106
107
108
109
  static void named_cluster_distribute(struct sk_buff *buf)
  {
  	struct sk_buff *buf_copy;
  	struct tipc_node *n_ptr;
8f92df6ad   Allan Stephens   tipc: Remove prot...
110

672d99e19   Allan Stephens   tipc: Convert nod...
111
  	list_for_each_entry(n_ptr, &tipc_node_list, list) {
8f19afb2d   Paul Gortmaker   tipc: cosmetic - ...
112
  		if (tipc_node_active_links(n_ptr)) {
8f92df6ad   Allan Stephens   tipc: Remove prot...
113
114
115
116
117
118
119
120
121
122
  			buf_copy = skb_copy(buf, GFP_ATOMIC);
  			if (!buf_copy)
  				break;
  			msg_set_destnode(buf_msg(buf_copy), n_ptr->addr);
  			tipc_link_send(buf_copy, n_ptr->addr, n_ptr->addr);
  		}
  	}
  
  	buf_discard(buf);
  }
b97bf3fd8   Per Liden   [TIPC] Initial merge
123
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
124
   * tipc_named_publish - tell other nodes about a new publication by this node
b97bf3fd8   Per Liden   [TIPC] Initial merge
125
   */
4323add67   Per Liden   [TIPC] Avoid poll...
126
  void tipc_named_publish(struct publication *publ)
b97bf3fd8   Per Liden   [TIPC] Initial merge
127
128
129
  {
  	struct sk_buff *buf;
  	struct distr_item *item;
08c31f716   Allan Stephens   [TIPC]: Name publ...
130
  	list_add_tail(&publ->local_list, &publ_root);
b97bf3fd8   Per Liden   [TIPC] Initial merge
131
132
133
134
  	publ_cnt++;
  
  	buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0);
  	if (!buf) {
a10bd924a   Allan Stephens   [TIPC]: Enhanced ...
135
136
  		warn("Publication distribution failure
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
137
138
139
140
141
  		return;
  	}
  
  	item = (struct distr_item *)msg_data(buf_msg(buf));
  	publ_to_item(item, publ);
8f92df6ad   Allan Stephens   tipc: Remove prot...
142
  	named_cluster_distribute(buf);
b97bf3fd8   Per Liden   [TIPC] Initial merge
143
144
145
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
146
   * tipc_named_withdraw - tell other nodes about a withdrawn publication by this node
b97bf3fd8   Per Liden   [TIPC] Initial merge
147
   */
4323add67   Per Liden   [TIPC] Avoid poll...
148
  void tipc_named_withdraw(struct publication *publ)
b97bf3fd8   Per Liden   [TIPC] Initial merge
149
150
151
152
153
154
155
156
157
  {
  	struct sk_buff *buf;
  	struct distr_item *item;
  
  	list_del(&publ->local_list);
  	publ_cnt--;
  
  	buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0);
  	if (!buf) {
25985edce   Lucas De Marchi   Fix common misspe...
158
159
  		warn("Withdrawal distribution failure
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
160
161
162
163
164
  		return;
  	}
  
  	item = (struct distr_item *)msg_data(buf_msg(buf));
  	publ_to_item(item, publ);
8f92df6ad   Allan Stephens   tipc: Remove prot...
165
  	named_cluster_distribute(buf);
b97bf3fd8   Per Liden   [TIPC] Initial merge
166
167
168
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
169
   * tipc_named_node_up - tell specified node about all publications by this node
b97bf3fd8   Per Liden   [TIPC] Initial merge
170
   */
1c553bb52   Paul Gortmaker   tipc: relocate/co...
171
  void tipc_named_node_up(unsigned long nodearg)
b97bf3fd8   Per Liden   [TIPC] Initial merge
172
  {
149ce37c8   Allan Stephens   tipc: Prevent fra...
173
  	struct tipc_node *n_ptr;
a18c4bc3e   Paul Gortmaker   tipc: rename stru...
174
  	struct tipc_link *l_ptr;
b97bf3fd8   Per Liden   [TIPC] Initial merge
175
  	struct publication *publ;
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
176
177
  	struct distr_item *item = NULL;
  	struct sk_buff *buf = NULL;
9aa88c2a5   Allan Stephens   tipc: Enhance sen...
178
  	struct list_head message_list;
1c553bb52   Paul Gortmaker   tipc: relocate/co...
179
  	u32 node = (u32)nodearg;
b97bf3fd8   Per Liden   [TIPC] Initial merge
180
181
  	u32 left = 0;
  	u32 rest;
149ce37c8   Allan Stephens   tipc: Prevent fra...
182
183
184
185
186
  	u32 max_item_buf = 0;
  
  	/* compute maximum amount of publication data to send per message */
  
  	read_lock_bh(&tipc_net_lock);
1c553bb52   Paul Gortmaker   tipc: relocate/co...
187
  	n_ptr = tipc_node_find(node);
149ce37c8   Allan Stephens   tipc: Prevent fra...
188
189
190
191
192
193
194
195
196
197
198
  	if (n_ptr) {
  		tipc_node_lock(n_ptr);
  		l_ptr = n_ptr->active_links[0];
  		if (l_ptr)
  			max_item_buf = ((l_ptr->max_pkt - INT_H_SIZE) /
  				ITEM_SIZE) * ITEM_SIZE;
  		tipc_node_unlock(n_ptr);
  	}
  	read_unlock_bh(&tipc_net_lock);
  	if (!max_item_buf)
  		return;
b97bf3fd8   Per Liden   [TIPC] Initial merge
199

9aa88c2a5   Allan Stephens   tipc: Enhance sen...
200
201
202
  	/* create list of publication messages, then send them as a unit */
  
  	INIT_LIST_HEAD(&message_list);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
203
  	read_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
204
205
206
207
208
209
  	rest = publ_cnt * ITEM_SIZE;
  
  	list_for_each_entry(publ, &publ_root, local_list) {
  		if (!buf) {
  			left = (rest <= max_item_buf) ? rest : max_item_buf;
  			rest -= left;
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
210
  			buf = named_prepare_buf(PUBLICATION, left, node);
a10bd924a   Allan Stephens   [TIPC]: Enhanced ...
211
212
213
  			if (!buf) {
  				warn("Bulk publication distribution failure
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
214
215
216
217
218
219
220
221
  				goto exit;
  			}
  			item = (struct distr_item *)msg_data(buf_msg(buf));
  		}
  		publ_to_item(item, publ);
  		item++;
  		left -= ITEM_SIZE;
  		if (!left) {
9aa88c2a5   Allan Stephens   tipc: Enhance sen...
222
  			list_add_tail((struct list_head *)buf, &message_list);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
223
  			buf = NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
224
225
226
  		}
  	}
  exit:
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
227
  	read_unlock_bh(&tipc_nametbl_lock);
9aa88c2a5   Allan Stephens   tipc: Enhance sen...
228
229
  
  	tipc_link_send_names(&message_list, (u32)node);
b97bf3fd8   Per Liden   [TIPC] Initial merge
230
231
232
  }
  
  /**
f13791733   Allan Stephens   tipc: Cosmetic ch...
233
   * named_purge_publ - remove publication associated with a failed node
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
234
235
   *
   * Invoked for each publication issued by a newly failed node.
b97bf3fd8   Per Liden   [TIPC] Initial merge
236
237
238
239
   * Removes publication structure from name table & deletes it.
   * In rare cases the link may have come back up again when this
   * function is called, and we have two items representing the same
   * publication. Nudge this item's key to distinguish it from the other.
b97bf3fd8   Per Liden   [TIPC] Initial merge
240
   */
f13791733   Allan Stephens   tipc: Cosmetic ch...
241
  static void named_purge_publ(struct publication *publ)
b97bf3fd8   Per Liden   [TIPC] Initial merge
242
243
  {
  	struct publication *p;
f131072c3   Allan Stephens   [TIPC]: First pha...
244

c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
245
  	write_lock_bh(&tipc_nametbl_lock);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
246
247
  	publ->key += 1222345;
  	p = tipc_nametbl_remove_publ(publ->type, publ->lower,
4323add67   Per Liden   [TIPC] Avoid poll...
248
  				     publ->node, publ->ref, publ->key);
431697eb6   Allan Stephens   tipc: Prevent nul...
249
250
  	if (p)
  		tipc_nodesub_unsubscribe(&p->subscr);
4323add67   Per Liden   [TIPC] Avoid poll...
251
  	write_unlock_bh(&tipc_nametbl_lock);
f131072c3   Allan Stephens   [TIPC]: First pha...
252

c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
253
  	if (p != publ) {
f131072c3   Allan Stephens   [TIPC]: First pha...
254
255
256
257
258
259
  		err("Unable to remove publication from failed node
  "
  		    "(type=%u, lower=%u, node=0x%x, ref=%u, key=%u)
  ",
  		    publ->type, publ->lower, publ->node, publ->ref, publ->key);
  	}
e83504f72   Allan Stephens   tipc: remove poin...
260
  	kfree(p);
b97bf3fd8   Per Liden   [TIPC] Initial merge
261
262
263
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
264
   * tipc_named_recv - process name table update message sent by another node
b97bf3fd8   Per Liden   [TIPC] Initial merge
265
   */
4323add67   Per Liden   [TIPC] Avoid poll...
266
  void tipc_named_recv(struct sk_buff *buf)
b97bf3fd8   Per Liden   [TIPC] Initial merge
267
268
269
270
271
  {
  	struct publication *publ;
  	struct tipc_msg *msg = buf_msg(buf);
  	struct distr_item *item = (struct distr_item *)msg_data(msg);
  	u32 count = msg_data_sz(msg) / ITEM_SIZE;
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
272
  	write_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
273
274
  	while (count--) {
  		if (msg_type(msg) == PUBLICATION) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
275
  			publ = tipc_nametbl_insert_publ(ntohl(item->type),
4323add67   Per Liden   [TIPC] Avoid poll...
276
277
278
  							ntohl(item->lower),
  							ntohl(item->upper),
  							TIPC_CLUSTER_SCOPE,
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
279
  							msg_orignode(msg),
4323add67   Per Liden   [TIPC] Avoid poll...
280
281
  							ntohl(item->ref),
  							ntohl(item->key));
b97bf3fd8   Per Liden   [TIPC] Initial merge
282
  			if (publ) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
283
284
  				tipc_nodesub_subscribe(&publ->subscr,
  						       msg_orignode(msg),
4323add67   Per Liden   [TIPC] Avoid poll...
285
  						       publ,
f13791733   Allan Stephens   tipc: Cosmetic ch...
286
287
  						       (net_ev_handler)
  						       named_purge_publ);
b97bf3fd8   Per Liden   [TIPC] Initial merge
288
289
  			}
  		} else if (msg_type(msg) == WITHDRAWAL) {
4323add67   Per Liden   [TIPC] Avoid poll...
290
291
292
293
294
  			publ = tipc_nametbl_remove_publ(ntohl(item->type),
  							ntohl(item->lower),
  							msg_orignode(msg),
  							ntohl(item->ref),
  							ntohl(item->key));
b97bf3fd8   Per Liden   [TIPC] Initial merge
295
296
  
  			if (publ) {
4323add67   Per Liden   [TIPC] Avoid poll...
297
  				tipc_nodesub_unsubscribe(&publ->subscr);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
298
  				kfree(publ);
f131072c3   Allan Stephens   [TIPC]: First pha...
299
300
301
302
303
304
305
306
  			} else {
  				err("Unable to remove publication by node 0x%x
  "
  				    "(type=%u, lower=%u, ref=%u, key=%u)
  ",
  				    msg_orignode(msg),
  				    ntohl(item->type), ntohl(item->lower),
  				    ntohl(item->ref), ntohl(item->key));
b97bf3fd8   Per Liden   [TIPC] Initial merge
307
308
  			}
  		} else {
a10bd924a   Allan Stephens   [TIPC]: Enhanced ...
309
310
  			warn("Unrecognized name table message received
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
311
312
313
  		}
  		item++;
  	}
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
314
  	write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
315
316
317
318
  	buf_discard(buf);
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
319
   * tipc_named_reinit - re-initialize local publication list
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
320
   *
945af1c39   Allan Stephens   tipc: Eliminate u...
321
   * This routine is called whenever TIPC networking is enabled.
b97bf3fd8   Per Liden   [TIPC] Initial merge
322
   * All existing publications by this node that have "cluster" or "zone" scope
945af1c39   Allan Stephens   tipc: Eliminate u...
323
   * are updated to reflect the node's new network address.
b97bf3fd8   Per Liden   [TIPC] Initial merge
324
   */
4323add67   Per Liden   [TIPC] Avoid poll...
325
  void tipc_named_reinit(void)
b97bf3fd8   Per Liden   [TIPC] Initial merge
326
327
  {
  	struct publication *publ;
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
328
  	write_lock_bh(&tipc_nametbl_lock);
945af1c39   Allan Stephens   tipc: Eliminate u...
329
330
  
  	list_for_each_entry(publ, &publ_root, local_list)
b97bf3fd8   Per Liden   [TIPC] Initial merge
331
  		publ->node = tipc_own_addr;
945af1c39   Allan Stephens   tipc: Eliminate u...
332

c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
333
  	write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
334
  }