Blame view
net/tipc/name_distr.c
9.23 KB
b97bf3fd8 [TIPC] Initial merge |
1 2 |
/* * net/tipc/name_distr.c: TIPC name distribution code |
c43072852 [NET] TIPC: Fix w... |
3 |
* |
593a5f22d [TIPC] More updat... |
4 |
* Copyright (c) 2000-2006, Ericsson AB |
431697eb6 tipc: Prevent nul... |
5 |
* Copyright (c) 2005, 2010-2011, Wind River Systems |
b97bf3fd8 [TIPC] Initial merge |
6 7 |
* All rights reserved. * |
9ea1fd3c1 [TIPC] License he... |
8 |
* Redistribution and use in source and binary forms, with or without |
b97bf3fd8 [TIPC] Initial merge |
9 10 |
* modification, are permitted provided that the following conditions are met: * |
9ea1fd3c1 [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 [TIPC] Initial merge |
19 |
* |
9ea1fd3c1 [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 [TIPC] Initial merge |
34 35 36 37 |
* POSSIBILITY OF SUCH DAMAGE. */ #include "core.h" |
b97bf3fd8 [TIPC] Initial merge |
38 |
#include "link.h" |
b97bf3fd8 [TIPC] Initial merge |
39 |
#include "name_distr.h" |
b97bf3fd8 [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 [NET] TIPC: Fix w... |
49 |
* |
b97bf3fd8 [TIPC] Initial merge |
50 |
* ===> All fields are stored in network byte order. <=== |
c43072852 [NET] TIPC: Fix w... |
51 |
* |
b97bf3fd8 [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 [NET] TIPC: Fix w... |
56 57 |
* * Note: There is no field that identifies the publishing node because it is |
b97bf3fd8 [TIPC] Initial merge |
58 59 60 61 |
* the same for all items contained within a publication message. */ struct distr_item { |
3e6c8cd56 [TIPC]: endiannes... |
62 63 64 65 66 |
__be32 type; __be32 lower; __be32 upper; __be32 ref; __be32 key; |
b97bf3fd8 [TIPC] Initial merge |
67 68 69 |
}; /** |
c43072852 [NET] TIPC: Fix w... |
70 |
* List of externally visible publications by this node -- |
b97bf3fd8 [TIPC] Initial merge |
71 72 73 74 |
* that is, all publications having scope > TIPC_NODE_SCOPE. */ static LIST_HEAD(publ_root); |
e3ec9c7d5 tipc: remove zero... |
75 |
static u32 publ_cnt; |
b97bf3fd8 [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 [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 tipc: Cleanup of ... |
96 |
struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size); |
b97bf3fd8 [TIPC] Initial merge |
97 98 99 100 |
struct tipc_msg *msg; if (buf != NULL) { msg = buf_msg(buf); |
741d9eb7b 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 [TIPC] Initial merge |
103 104 105 |
} return buf; } |
8f92df6ad 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 tipc: Remove prot... |
110 |
|
672d99e19 tipc: Convert nod... |
111 |
list_for_each_entry(n_ptr, &tipc_node_list, list) { |
8f19afb2d tipc: cosmetic - ... |
112 |
if (tipc_node_active_links(n_ptr)) { |
8f92df6ad 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 [TIPC] Initial merge |
123 |
/** |
4323add67 [TIPC] Avoid poll... |
124 |
* tipc_named_publish - tell other nodes about a new publication by this node |
b97bf3fd8 [TIPC] Initial merge |
125 |
*/ |
4323add67 [TIPC] Avoid poll... |
126 |
void tipc_named_publish(struct publication *publ) |
b97bf3fd8 [TIPC] Initial merge |
127 128 129 |
{ struct sk_buff *buf; struct distr_item *item; |
08c31f716 [TIPC]: Name publ... |
130 |
list_add_tail(&publ->local_list, &publ_root); |
b97bf3fd8 [TIPC] Initial merge |
131 132 133 134 |
publ_cnt++; buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); if (!buf) { |
a10bd924a [TIPC]: Enhanced ... |
135 136 |
warn("Publication distribution failure "); |
b97bf3fd8 [TIPC] Initial merge |
137 138 139 140 141 |
return; } item = (struct distr_item *)msg_data(buf_msg(buf)); publ_to_item(item, publ); |
8f92df6ad tipc: Remove prot... |
142 |
named_cluster_distribute(buf); |
b97bf3fd8 [TIPC] Initial merge |
143 144 145 |
} /** |
4323add67 [TIPC] Avoid poll... |
146 |
* tipc_named_withdraw - tell other nodes about a withdrawn publication by this node |
b97bf3fd8 [TIPC] Initial merge |
147 |
*/ |
4323add67 [TIPC] Avoid poll... |
148 |
void tipc_named_withdraw(struct publication *publ) |
b97bf3fd8 [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 Fix common misspe... |
158 159 |
warn("Withdrawal distribution failure "); |
b97bf3fd8 [TIPC] Initial merge |
160 161 162 163 164 |
return; } item = (struct distr_item *)msg_data(buf_msg(buf)); publ_to_item(item, publ); |
8f92df6ad tipc: Remove prot... |
165 |
named_cluster_distribute(buf); |
b97bf3fd8 [TIPC] Initial merge |
166 167 168 |
} /** |
4323add67 [TIPC] Avoid poll... |
169 |
* tipc_named_node_up - tell specified node about all publications by this node |
b97bf3fd8 [TIPC] Initial merge |
170 |
*/ |
1c553bb52 tipc: relocate/co... |
171 |
void tipc_named_node_up(unsigned long nodearg) |
b97bf3fd8 [TIPC] Initial merge |
172 |
{ |
149ce37c8 tipc: Prevent fra... |
173 |
struct tipc_node *n_ptr; |
a18c4bc3e tipc: rename stru... |
174 |
struct tipc_link *l_ptr; |
b97bf3fd8 [TIPC] Initial merge |
175 |
struct publication *publ; |
1fc54d8f4 [TIPC]: Fix simpl... |
176 177 |
struct distr_item *item = NULL; struct sk_buff *buf = NULL; |
9aa88c2a5 tipc: Enhance sen... |
178 |
struct list_head message_list; |
1c553bb52 tipc: relocate/co... |
179 |
u32 node = (u32)nodearg; |
b97bf3fd8 [TIPC] Initial merge |
180 181 |
u32 left = 0; u32 rest; |
149ce37c8 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 tipc: relocate/co... |
187 |
n_ptr = tipc_node_find(node); |
149ce37c8 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 [TIPC] Initial merge |
199 |
|
9aa88c2a5 tipc: Enhance sen... |
200 201 202 |
/* create list of publication messages, then send them as a unit */ INIT_LIST_HEAD(&message_list); |
c43072852 [NET] TIPC: Fix w... |
203 |
read_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [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 [NET] TIPC: Fix w... |
210 |
buf = named_prepare_buf(PUBLICATION, left, node); |
a10bd924a [TIPC]: Enhanced ... |
211 212 213 |
if (!buf) { warn("Bulk publication distribution failure "); |
b97bf3fd8 [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 tipc: Enhance sen... |
222 |
list_add_tail((struct list_head *)buf, &message_list); |
1fc54d8f4 [TIPC]: Fix simpl... |
223 |
buf = NULL; |
b97bf3fd8 [TIPC] Initial merge |
224 225 226 |
} } exit: |
c43072852 [NET] TIPC: Fix w... |
227 |
read_unlock_bh(&tipc_nametbl_lock); |
9aa88c2a5 tipc: Enhance sen... |
228 229 |
tipc_link_send_names(&message_list, (u32)node); |
b97bf3fd8 [TIPC] Initial merge |
230 231 232 |
} /** |
f13791733 tipc: Cosmetic ch... |
233 |
* named_purge_publ - remove publication associated with a failed node |
c43072852 [NET] TIPC: Fix w... |
234 235 |
* * Invoked for each publication issued by a newly failed node. |
b97bf3fd8 [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 [TIPC] Initial merge |
240 |
*/ |
f13791733 tipc: Cosmetic ch... |
241 |
static void named_purge_publ(struct publication *publ) |
b97bf3fd8 [TIPC] Initial merge |
242 243 |
{ struct publication *p; |
f131072c3 [TIPC]: First pha... |
244 |
|
c43072852 [NET] TIPC: Fix w... |
245 |
write_lock_bh(&tipc_nametbl_lock); |
c43072852 [NET] TIPC: Fix w... |
246 247 |
publ->key += 1222345; p = tipc_nametbl_remove_publ(publ->type, publ->lower, |
4323add67 [TIPC] Avoid poll... |
248 |
publ->node, publ->ref, publ->key); |
431697eb6 tipc: Prevent nul... |
249 250 |
if (p) tipc_nodesub_unsubscribe(&p->subscr); |
4323add67 [TIPC] Avoid poll... |
251 |
write_unlock_bh(&tipc_nametbl_lock); |
f131072c3 [TIPC]: First pha... |
252 |
|
c43072852 [NET] TIPC: Fix w... |
253 |
if (p != publ) { |
f131072c3 [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 tipc: remove poin... |
260 |
kfree(p); |
b97bf3fd8 [TIPC] Initial merge |
261 262 263 |
} /** |
4323add67 [TIPC] Avoid poll... |
264 |
* tipc_named_recv - process name table update message sent by another node |
b97bf3fd8 [TIPC] Initial merge |
265 |
*/ |
4323add67 [TIPC] Avoid poll... |
266 |
void tipc_named_recv(struct sk_buff *buf) |
b97bf3fd8 [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 [NET] TIPC: Fix w... |
272 |
write_lock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
273 274 |
while (count--) { if (msg_type(msg) == PUBLICATION) { |
c43072852 [NET] TIPC: Fix w... |
275 |
publ = tipc_nametbl_insert_publ(ntohl(item->type), |
4323add67 [TIPC] Avoid poll... |
276 277 278 |
ntohl(item->lower), ntohl(item->upper), TIPC_CLUSTER_SCOPE, |
c43072852 [NET] TIPC: Fix w... |
279 |
msg_orignode(msg), |
4323add67 [TIPC] Avoid poll... |
280 281 |
ntohl(item->ref), ntohl(item->key)); |
b97bf3fd8 [TIPC] Initial merge |
282 |
if (publ) { |
c43072852 [NET] TIPC: Fix w... |
283 284 |
tipc_nodesub_subscribe(&publ->subscr, msg_orignode(msg), |
4323add67 [TIPC] Avoid poll... |
285 |
publ, |
f13791733 tipc: Cosmetic ch... |
286 287 |
(net_ev_handler) named_purge_publ); |
b97bf3fd8 [TIPC] Initial merge |
288 289 |
} } else if (msg_type(msg) == WITHDRAWAL) { |
4323add67 [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 [TIPC] Initial merge |
295 296 |
if (publ) { |
4323add67 [TIPC] Avoid poll... |
297 |
tipc_nodesub_unsubscribe(&publ->subscr); |
c43072852 [NET] TIPC: Fix w... |
298 |
kfree(publ); |
f131072c3 [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 [TIPC] Initial merge |
307 308 |
} } else { |
a10bd924a [TIPC]: Enhanced ... |
309 310 |
warn("Unrecognized name table message received "); |
b97bf3fd8 [TIPC] Initial merge |
311 312 313 |
} item++; } |
c43072852 [NET] TIPC: Fix w... |
314 |
write_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
315 316 317 318 |
buf_discard(buf); } /** |
4323add67 [TIPC] Avoid poll... |
319 |
* tipc_named_reinit - re-initialize local publication list |
c43072852 [NET] TIPC: Fix w... |
320 |
* |
945af1c39 tipc: Eliminate u... |
321 |
* This routine is called whenever TIPC networking is enabled. |
b97bf3fd8 [TIPC] Initial merge |
322 |
* All existing publications by this node that have "cluster" or "zone" scope |
945af1c39 tipc: Eliminate u... |
323 |
* are updated to reflect the node's new network address. |
b97bf3fd8 [TIPC] Initial merge |
324 |
*/ |
4323add67 [TIPC] Avoid poll... |
325 |
void tipc_named_reinit(void) |
b97bf3fd8 [TIPC] Initial merge |
326 327 |
{ struct publication *publ; |
c43072852 [NET] TIPC: Fix w... |
328 |
write_lock_bh(&tipc_nametbl_lock); |
945af1c39 tipc: Eliminate u... |
329 330 |
list_for_each_entry(publ, &publ_root, local_list) |
b97bf3fd8 [TIPC] Initial merge |
331 |
publ->node = tipc_own_addr; |
945af1c39 tipc: Eliminate u... |
332 |
|
c43072852 [NET] TIPC: Fix w... |
333 |
write_unlock_bh(&tipc_nametbl_lock); |
b97bf3fd8 [TIPC] Initial merge |
334 |
} |