Blame view
net/tipc/discover.c
10 KB
b97bf3fd8 [TIPC] Initial merge |
1 2 |
/* * net/tipc/discover.c |
c43072852 [NET] TIPC: Fix w... |
3 |
* |
9da1c8b69 [TIPC] Update of ... |
4 |
* Copyright (c) 2003-2006, Ericsson AB |
2d627b92f tipc: Combine bea... |
5 |
* Copyright (c) 2005-2006, 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 "discover.h" |
b97bf3fd8 [TIPC] Initial merge |
40 41 |
#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */ |
972a77fbf tipc: Revise timi... |
42 43 44 |
#define TIPC_LINK_REQ_FAST 1000 /* max delay if bearer has no links */ #define TIPC_LINK_REQ_SLOW 60000 /* max delay if bearer has links */ #define TIPC_LINK_REQ_INACTIVE 0xffffffff /* indicates no timer in use */ |
b97bf3fd8 [TIPC] Initial merge |
45 46 47 |
/** |
a18c4bc3e tipc: rename stru... |
48 |
* struct tipc_link_req - information about an ongoing link setup request |
b97bf3fd8 [TIPC] Initial merge |
49 50 |
* @bearer: bearer issuing requests * @dest: destination address for request messages |
66e019a6a tipc: Strengthen ... |
51 |
* @domain: network domain to which links can be established |
1209966cd tipc: Add monitor... |
52 |
* @num_nodes: number of nodes currently discovered (i.e. with an active link) |
b97bf3fd8 [TIPC] Initial merge |
53 54 55 56 |
* @buf: request message to be (repeatedly) sent * @timer: timer governing period between requests * @timer_intv: current interval between requests (in ms) */ |
a18c4bc3e tipc: rename stru... |
57 |
struct tipc_link_req { |
2d627b92f tipc: Combine bea... |
58 |
struct tipc_bearer *bearer; |
b97bf3fd8 [TIPC] Initial merge |
59 |
struct tipc_media_addr dest; |
66e019a6a tipc: Strengthen ... |
60 |
u32 domain; |
1209966cd tipc: Add monitor... |
61 |
int num_nodes; |
b97bf3fd8 [TIPC] Initial merge |
62 63 64 65 |
struct sk_buff *buf; struct timer_list timer; unsigned int timer_intv; }; |
c43072852 [NET] TIPC: Fix w... |
66 |
/** |
4323add67 [TIPC] Avoid poll... |
67 |
* tipc_disc_init_msg - initialize a link setup message |
b97bf3fd8 [TIPC] Initial merge |
68 |
* @type: message type (request or response) |
b97bf3fd8 [TIPC] Initial merge |
69 70 71 |
* @dest_domain: network domain of node(s) which should respond to message * @b_ptr: ptr to bearer issuing message */ |
988f088a8 [TIPC]: Cleanups |
72 |
static struct sk_buff *tipc_disc_init_msg(u32 type, |
988f088a8 [TIPC]: Cleanups |
73 |
u32 dest_domain, |
2d627b92f tipc: Combine bea... |
74 |
struct tipc_bearer *b_ptr) |
b97bf3fd8 [TIPC] Initial merge |
75 |
{ |
d901a42b2 tipc: Eliminate u... |
76 |
struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE); |
b97bf3fd8 [TIPC] Initial merge |
77 78 79 80 |
struct tipc_msg *msg; if (buf) { msg = buf_msg(buf); |
d901a42b2 tipc: Eliminate u... |
81 |
tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain); |
40aecb1b1 tipc: Message rej... |
82 |
msg_set_non_seq(msg, 1); |
b97bf3fd8 [TIPC] Initial merge |
83 84 |
msg_set_dest_domain(msg, dest_domain); msg_set_bc_netid(msg, tipc_net_id); |
3d749a6a2 tipc: Hide media-... |
85 |
b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg)); |
b97bf3fd8 [TIPC] Initial merge |
86 87 88 89 90 |
} return buf; } /** |
e91ed0bcd [TIPC]: Added dup... |
91 92 93 94 95 |
* disc_dupl_alert - issue node address duplication alert * @b_ptr: pointer to bearer detecting duplication * @node_addr: duplicated node address * @media_addr: media address advertised by duplicated node */ |
2d627b92f tipc: Combine bea... |
96 |
static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr, |
e91ed0bcd [TIPC]: Added dup... |
97 98 99 100 101 |
struct tipc_media_addr *media_addr) { char node_addr_str[16]; char media_addr_str[64]; struct print_buf pb; |
c68ca7b72 tipc: add tipc_ p... |
102 |
tipc_addr_string_fill(node_addr_str, node_addr); |
e91ed0bcd [TIPC]: Added dup... |
103 104 105 106 107 |
tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str)); tipc_media_addr_printf(&pb, media_addr); tipc_printbuf_validate(&pb); warn("Duplicate %s using %s seen on <%s> ", |
2d627b92f tipc: Combine bea... |
108 |
node_addr_str, media_addr_str, b_ptr->name); |
e91ed0bcd [TIPC]: Added dup... |
109 110 111 |
} /** |
4323add67 [TIPC] Avoid poll... |
112 |
* tipc_disc_recv_msg - handle incoming link setup message (request or response) |
b97bf3fd8 [TIPC] Initial merge |
113 |
* @buf: buffer containing message |
1265a0210 tipc: Minor optim... |
114 |
* @b_ptr: bearer that message arrived on |
b97bf3fd8 [TIPC] Initial merge |
115 |
*/ |
2d627b92f tipc: Combine bea... |
116 |
void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr) |
b97bf3fd8 [TIPC] Initial merge |
117 |
{ |
a728750e4 tipc: Cosmetic ch... |
118 |
struct tipc_node *n_ptr; |
a18c4bc3e tipc: rename stru... |
119 |
struct tipc_link *link; |
a728750e4 tipc: Cosmetic ch... |
120 121 |
struct tipc_media_addr media_addr, *addr; struct sk_buff *rbuf; |
b97bf3fd8 [TIPC] Initial merge |
122 123 124 125 126 |
struct tipc_msg *msg = buf_msg(buf); u32 dest = msg_dest_domain(msg); u32 orig = msg_prevnode(msg); u32 net_id = msg_bc_netid(msg); u32 type = msg_type(msg); |
a728750e4 tipc: Cosmetic ch... |
127 |
int link_fully_up; |
b97bf3fd8 [TIPC] Initial merge |
128 |
|
d6d4577ae tipc: Ignore neig... |
129 |
media_addr.broadcast = 1; |
3d749a6a2 tipc: Hide media-... |
130 |
b_ptr->media->msg2addr(&media_addr, msg_media_addr(msg)); |
b97bf3fd8 [TIPC] Initial merge |
131 |
buf_discard(buf); |
a728750e4 tipc: Cosmetic ch... |
132 |
/* Validate discovery message from requesting node */ |
b97bf3fd8 [TIPC] Initial merge |
133 134 |
if (net_id != tipc_net_id) return; |
d6d4577ae tipc: Ignore neig... |
135 136 |
if (media_addr.broadcast) return; |
4323add67 [TIPC] Avoid poll... |
137 |
if (!tipc_addr_domain_valid(dest)) |
b97bf3fd8 [TIPC] Initial merge |
138 |
return; |
4323add67 [TIPC] Avoid poll... |
139 |
if (!tipc_addr_node_valid(orig)) |
b97bf3fd8 [TIPC] Initial merge |
140 |
return; |
e91ed0bcd [TIPC]: Added dup... |
141 |
if (orig == tipc_own_addr) { |
2d627b92f tipc: Combine bea... |
142 |
if (memcmp(&media_addr, &b_ptr->addr, sizeof(media_addr))) |
e91ed0bcd [TIPC]: Added dup... |
143 |
disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); |
b97bf3fd8 [TIPC] Initial merge |
144 |
return; |
e91ed0bcd [TIPC]: Added dup... |
145 |
} |
c68ca7b72 tipc: add tipc_ p... |
146 |
if (!tipc_in_scope(dest, tipc_own_addr)) |
b97bf3fd8 [TIPC] Initial merge |
147 |
return; |
66e019a6a tipc: Strengthen ... |
148 |
if (!tipc_in_scope(b_ptr->link_req->domain, orig)) |
a728750e4 tipc: Cosmetic ch... |
149 |
return; |
5a68d5ee0 tipc: Prevent mis... |
150 |
|
a728750e4 tipc: Cosmetic ch... |
151 152 153 154 155 |
/* Locate structure corresponding to requesting node */ n_ptr = tipc_node_find(orig); if (!n_ptr) { n_ptr = tipc_node_create(orig); if (!n_ptr) |
5a68d5ee0 tipc: Prevent mis... |
156 |
return; |
a728750e4 tipc: Cosmetic ch... |
157 158 |
} tipc_node_lock(n_ptr); |
a728750e4 tipc: Cosmetic ch... |
159 160 161 162 |
link = n_ptr->links[b_ptr->identity]; /* Create a link endpoint for this bearer, if necessary */ if (!link) { |
37b9c08a8 tipc: Optimizatio... |
163 |
link = tipc_link_create(n_ptr, b_ptr, &media_addr); |
b97bf3fd8 [TIPC] Initial merge |
164 |
if (!link) { |
a728750e4 tipc: Cosmetic ch... |
165 166 |
tipc_node_unlock(n_ptr); return; |
b97bf3fd8 [TIPC] Initial merge |
167 |
} |
a728750e4 tipc: Cosmetic ch... |
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
} /* * Ensure requesting node's media address is correct * * If media address doesn't match and the link is working, reject the * request (must be from a duplicate node). * * If media address doesn't match and the link is not working, accept * the new media address and reset the link to ensure it starts up * cleanly. */ addr = &link->media_addr; if (memcmp(addr, &media_addr, sizeof(*addr))) { if (tipc_link_is_up(link) || (!link->started)) { disc_dupl_alert(b_ptr, orig, &media_addr); tipc_node_unlock(n_ptr); |
b97bf3fd8 [TIPC] Initial merge |
185 |
return; |
b97bf3fd8 [TIPC] Initial merge |
186 |
} |
a728750e4 tipc: Cosmetic ch... |
187 188 189 190 191 192 193 194 195 |
warn("Resetting link <%s>, peer interface address changed ", link->name); memcpy(addr, &media_addr, sizeof(*addr)); tipc_link_reset(link); } /* Accept discovery message & send response, if necessary */ link_fully_up = link_working_working(link); |
fa2bae2d5 tipc: Give Tx of ... |
196 |
|
f9107ebe7 tipc: Don't respo... |
197 |
if ((type == DSC_REQ_MSG) && !link_fully_up && !b_ptr->blocked) { |
fa2bae2d5 tipc: Give Tx of ... |
198 199 200 201 202 |
rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr); if (rbuf) { b_ptr->media->send_msg(rbuf, b_ptr, &media_addr); buf_discard(rbuf); } |
b97bf3fd8 [TIPC] Initial merge |
203 |
} |
fa2bae2d5 tipc: Give Tx of ... |
204 205 |
tipc_node_unlock(n_ptr); |
b97bf3fd8 [TIPC] Initial merge |
206 207 208 |
} /** |
1209966cd tipc: Add monitor... |
209 |
* disc_update - update frequency of periodic link setup requests |
b97bf3fd8 [TIPC] Initial merge |
210 |
* @req: ptr to link request structure |
972a77fbf tipc: Revise timi... |
211 212 213 |
* * Reinitiates discovery process if discovery object has no associated nodes * and is either not currently searching or is searching at a slow rate |
b97bf3fd8 [TIPC] Initial merge |
214 |
*/ |
a18c4bc3e tipc: rename stru... |
215 |
static void disc_update(struct tipc_link_req *req) |
b97bf3fd8 [TIPC] Initial merge |
216 |
{ |
972a77fbf tipc: Revise timi... |
217 218 219 220 |
if (!req->num_nodes) { if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) || (req->timer_intv > TIPC_LINK_REQ_FAST)) { req->timer_intv = TIPC_LINK_REQ_INIT; |
b97bf3fd8 [TIPC] Initial merge |
221 222 |
k_start_timer(&req->timer, req->timer_intv); } |
b97bf3fd8 [TIPC] Initial merge |
223 |
} |
c43072852 [NET] TIPC: Fix w... |
224 |
} |
b97bf3fd8 [TIPC] Initial merge |
225 226 |
/** |
1209966cd tipc: Add monitor... |
227 228 229 |
* tipc_disc_add_dest - increment set of discovered nodes * @req: ptr to link request structure */ |
a18c4bc3e tipc: rename stru... |
230 |
void tipc_disc_add_dest(struct tipc_link_req *req) |
1209966cd tipc: Add monitor... |
231 232 |
{ req->num_nodes++; |
1209966cd tipc: Add monitor... |
233 234 235 236 237 238 |
} /** * tipc_disc_remove_dest - decrement set of discovered nodes * @req: ptr to link request structure */ |
a18c4bc3e tipc: rename stru... |
239 |
void tipc_disc_remove_dest(struct tipc_link_req *req) |
1209966cd tipc: Add monitor... |
240 241 242 243 244 245 |
{ req->num_nodes--; disc_update(req); } /** |
691a62075 tipc: Enhance sen... |
246 247 248 |
* disc_send_msg - send link setup request message * @req: ptr to link request structure */ |
a18c4bc3e tipc: rename stru... |
249 |
static void disc_send_msg(struct tipc_link_req *req) |
691a62075 tipc: Enhance sen... |
250 251 252 253 254 255 |
{ if (!req->bearer->blocked) tipc_bearer_send(req->bearer, req->buf, &req->dest); } /** |
b97bf3fd8 [TIPC] Initial merge |
256 257 |
* disc_timeout - send a periodic link setup request * @req: ptr to link request structure |
c43072852 [NET] TIPC: Fix w... |
258 |
* |
b97bf3fd8 [TIPC] Initial merge |
259 260 |
* Called whenever a link setup request timer associated with a bearer expires. */ |
a18c4bc3e tipc: rename stru... |
261 |
static void disc_timeout(struct tipc_link_req *req) |
b97bf3fd8 [TIPC] Initial merge |
262 |
{ |
972a77fbf tipc: Revise timi... |
263 |
int max_delay; |
2d627b92f tipc: Combine bea... |
264 |
spin_lock_bh(&req->bearer->lock); |
b97bf3fd8 [TIPC] Initial merge |
265 |
|
972a77fbf tipc: Revise timi... |
266 |
/* Stop searching if only desired node has been found */ |
b97bf3fd8 [TIPC] Initial merge |
267 |
|
972a77fbf tipc: Revise timi... |
268 269 270 |
if (tipc_node(req->domain) && req->num_nodes) { req->timer_intv = TIPC_LINK_REQ_INACTIVE; goto exit; |
b97bf3fd8 [TIPC] Initial merge |
271 |
} |
b97bf3fd8 [TIPC] Initial merge |
272 |
|
972a77fbf tipc: Revise timi... |
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
/* * Send discovery message, then update discovery timer * * Keep doubling time between requests until limit is reached; * hold at fast polling rate if don't have any associated nodes, * otherwise hold at slow polling rate */ disc_send_msg(req); req->timer_intv *= 2; if (req->num_nodes) max_delay = TIPC_LINK_REQ_SLOW; else max_delay = TIPC_LINK_REQ_FAST; if (req->timer_intv > max_delay) req->timer_intv = max_delay; k_start_timer(&req->timer, req->timer_intv); exit: |
2d627b92f tipc: Combine bea... |
293 |
spin_unlock_bh(&req->bearer->lock); |
b97bf3fd8 [TIPC] Initial merge |
294 295 296 |
} /** |
3a777ff8b tipc: Enhance han... |
297 |
* tipc_disc_create - create object to send periodic link setup requests |
b97bf3fd8 [TIPC] Initial merge |
298 299 |
* @b_ptr: ptr to bearer issuing requests * @dest: destination address for request messages |
66e019a6a tipc: Strengthen ... |
300 |
* @dest_domain: network domain to which links can be established |
c43072852 [NET] TIPC: Fix w... |
301 |
* |
3a777ff8b tipc: Enhance han... |
302 |
* Returns 0 if successful, otherwise -errno. |
b97bf3fd8 [TIPC] Initial merge |
303 |
*/ |
3a777ff8b tipc: Enhance han... |
304 305 |
int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest, u32 dest_domain) |
b97bf3fd8 [TIPC] Initial merge |
306 |
{ |
a18c4bc3e tipc: rename stru... |
307 |
struct tipc_link_req *req; |
b97bf3fd8 [TIPC] Initial merge |
308 |
|
9df3f3d28 [TIPC]: Removing ... |
309 |
req = kmalloc(sizeof(*req), GFP_ATOMIC); |
b97bf3fd8 [TIPC] Initial merge |
310 |
if (!req) |
3a777ff8b tipc: Enhance han... |
311 |
return -ENOMEM; |
b97bf3fd8 [TIPC] Initial merge |
312 |
|
2e07dda16 tipc: Remove unus... |
313 |
req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr); |
b97bf3fd8 [TIPC] Initial merge |
314 315 |
if (!req->buf) { kfree(req); |
3a777ff8b tipc: Enhance han... |
316 |
return -ENOMSG; |
b97bf3fd8 [TIPC] Initial merge |
317 318 319 320 |
} memcpy(&req->dest, dest, sizeof(*dest)); req->bearer = b_ptr; |
66e019a6a tipc: Strengthen ... |
321 |
req->domain = dest_domain; |
1209966cd tipc: Add monitor... |
322 |
req->num_nodes = 0; |
b97bf3fd8 [TIPC] Initial merge |
323 324 325 |
req->timer_intv = TIPC_LINK_REQ_INIT; k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); k_start_timer(&req->timer, req->timer_intv); |
3a777ff8b tipc: Enhance han... |
326 |
b_ptr->link_req = req; |
691a62075 tipc: Enhance sen... |
327 |
disc_send_msg(req); |
3a777ff8b tipc: Enhance han... |
328 329 330 331 332 333 334 |
return 0; } /** * tipc_disc_delete - destroy object sending periodic link setup requests * @req: ptr to link request structure */ |
a18c4bc3e tipc: rename stru... |
335 |
void tipc_disc_delete(struct tipc_link_req *req) |
3a777ff8b tipc: Enhance han... |
336 337 338 339 340 |
{ k_cancel_timer(&req->timer); k_term_timer(&req->timer); buf_discard(req->buf); kfree(req); |
c43072852 [NET] TIPC: Fix w... |
341 |
} |
b97bf3fd8 [TIPC] Initial merge |
342 |