diff options
Diffstat (limited to 'net/tipc/discover.c')
| -rw-r--r-- | net/tipc/discover.c | 150 |
1 files changed, 95 insertions, 55 deletions
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 491eff56b9da..0987933155b9 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
| @@ -39,19 +39,17 @@ | |||
| 39 | #include "discover.h" | 39 | #include "discover.h" |
| 40 | 40 | ||
| 41 | #define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */ | 41 | #define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */ |
| 42 | #define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */ | 42 | #define TIPC_LINK_REQ_FAST 1000 /* max delay if bearer has no links */ |
| 43 | #define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */ | 43 | #define TIPC_LINK_REQ_SLOW 60000 /* max delay if bearer has links */ |
| 44 | 44 | #define TIPC_LINK_REQ_INACTIVE 0xffffffff /* indicates no timer in use */ | |
| 45 | /* | ||
| 46 | * TODO: Most of the inter-cluster setup stuff should be | ||
| 47 | * rewritten, and be made conformant with specification. | ||
| 48 | */ | ||
| 49 | 45 | ||
| 50 | 46 | ||
| 51 | /** | 47 | /** |
| 52 | * struct link_req - information about an ongoing link setup request | 48 | * struct link_req - information about an ongoing link setup request |
| 53 | * @bearer: bearer issuing requests | 49 | * @bearer: bearer issuing requests |
| 54 | * @dest: destination address for request messages | 50 | * @dest: destination address for request messages |
| 51 | * @domain: network domain to which links can be established | ||
| 52 | * @num_nodes: number of nodes currently discovered (i.e. with an active link) | ||
| 55 | * @buf: request message to be (repeatedly) sent | 53 | * @buf: request message to be (repeatedly) sent |
| 56 | * @timer: timer governing period between requests | 54 | * @timer: timer governing period between requests |
| 57 | * @timer_intv: current interval between requests (in ms) | 55 | * @timer_intv: current interval between requests (in ms) |
| @@ -59,6 +57,8 @@ | |||
| 59 | struct link_req { | 57 | struct link_req { |
| 60 | struct tipc_bearer *bearer; | 58 | struct tipc_bearer *bearer; |
| 61 | struct tipc_media_addr dest; | 59 | struct tipc_media_addr dest; |
| 60 | u32 domain; | ||
| 61 | int num_nodes; | ||
| 62 | struct sk_buff *buf; | 62 | struct sk_buff *buf; |
| 63 | struct timer_list timer; | 63 | struct timer_list timer; |
| 64 | unsigned int timer_intv; | 64 | unsigned int timer_intv; |
| @@ -147,7 +147,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr) | |||
| 147 | } | 147 | } |
| 148 | if (!tipc_in_scope(dest, tipc_own_addr)) | 148 | if (!tipc_in_scope(dest, tipc_own_addr)) |
| 149 | return; | 149 | return; |
| 150 | if (!in_own_cluster(orig)) | 150 | if (!tipc_in_scope(b_ptr->link_req->domain, orig)) |
| 151 | return; | 151 | return; |
| 152 | 152 | ||
| 153 | /* Locate structure corresponding to requesting node */ | 153 | /* Locate structure corresponding to requesting node */ |
| @@ -214,44 +214,54 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr) | |||
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | /** | 216 | /** |
| 217 | * tipc_disc_stop_link_req - stop sending periodic link setup requests | 217 | * disc_update - update frequency of periodic link setup requests |
| 218 | * @req: ptr to link request structure | 218 | * @req: ptr to link request structure |
| 219 | * | ||
| 220 | * Reinitiates discovery process if discovery object has no associated nodes | ||
| 221 | * and is either not currently searching or is searching at a slow rate | ||
| 219 | */ | 222 | */ |
| 220 | 223 | ||
| 221 | void tipc_disc_stop_link_req(struct link_req *req) | 224 | static void disc_update(struct link_req *req) |
| 222 | { | 225 | { |
| 223 | if (!req) | 226 | if (!req->num_nodes) { |
| 224 | return; | 227 | if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) || |
| 228 | (req->timer_intv > TIPC_LINK_REQ_FAST)) { | ||
| 229 | req->timer_intv = TIPC_LINK_REQ_INIT; | ||
| 230 | k_start_timer(&req->timer, req->timer_intv); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | } | ||
| 225 | 234 | ||
| 226 | k_cancel_timer(&req->timer); | 235 | /** |
| 227 | k_term_timer(&req->timer); | 236 | * tipc_disc_add_dest - increment set of discovered nodes |
| 228 | buf_discard(req->buf); | 237 | * @req: ptr to link request structure |
| 229 | kfree(req); | 238 | */ |
| 239 | |||
| 240 | void tipc_disc_add_dest(struct link_req *req) | ||
| 241 | { | ||
| 242 | req->num_nodes++; | ||
| 230 | } | 243 | } |
| 231 | 244 | ||
| 232 | /** | 245 | /** |
| 233 | * tipc_disc_update_link_req - update frequency of periodic link setup requests | 246 | * tipc_disc_remove_dest - decrement set of discovered nodes |
| 234 | * @req: ptr to link request structure | 247 | * @req: ptr to link request structure |
| 235 | */ | 248 | */ |
| 236 | 249 | ||
| 237 | void tipc_disc_update_link_req(struct link_req *req) | 250 | void tipc_disc_remove_dest(struct link_req *req) |
| 238 | { | 251 | { |
| 239 | if (!req) | 252 | req->num_nodes--; |
| 240 | return; | 253 | disc_update(req); |
| 254 | } | ||
| 241 | 255 | ||
| 242 | if (req->timer_intv == TIPC_LINK_REQ_SLOW) { | 256 | /** |
| 243 | if (!req->bearer->nodes.count) { | 257 | * disc_send_msg - send link setup request message |
| 244 | req->timer_intv = TIPC_LINK_REQ_FAST; | 258 | * @req: ptr to link request structure |
| 245 | k_start_timer(&req->timer, req->timer_intv); | 259 | */ |
| 246 | } | 260 | |
| 247 | } else if (req->timer_intv == TIPC_LINK_REQ_FAST) { | 261 | static void disc_send_msg(struct link_req *req) |
| 248 | if (req->bearer->nodes.count) { | 262 | { |
| 249 | req->timer_intv = TIPC_LINK_REQ_SLOW; | 263 | if (!req->bearer->blocked) |
| 250 | k_start_timer(&req->timer, req->timer_intv); | 264 | tipc_bearer_send(req->bearer, req->buf, &req->dest); |
| 251 | } | ||
| 252 | } else { | ||
| 253 | /* leave timer "as is" if haven't yet reached a "normal" rate */ | ||
| 254 | } | ||
| 255 | } | 265 | } |
| 256 | 266 | ||
| 257 | /** | 267 | /** |
| @@ -263,56 +273,86 @@ void tipc_disc_update_link_req(struct link_req *req) | |||
| 263 | 273 | ||
| 264 | static void disc_timeout(struct link_req *req) | 274 | static void disc_timeout(struct link_req *req) |
| 265 | { | 275 | { |
| 276 | int max_delay; | ||
| 277 | |||
| 266 | spin_lock_bh(&req->bearer->lock); | 278 | spin_lock_bh(&req->bearer->lock); |
| 267 | 279 | ||
| 268 | req->bearer->media->send_msg(req->buf, req->bearer, &req->dest); | 280 | /* Stop searching if only desired node has been found */ |
| 269 | 281 | ||
| 270 | if ((req->timer_intv == TIPC_LINK_REQ_SLOW) || | 282 | if (tipc_node(req->domain) && req->num_nodes) { |
| 271 | (req->timer_intv == TIPC_LINK_REQ_FAST)) { | 283 | req->timer_intv = TIPC_LINK_REQ_INACTIVE; |
| 272 | /* leave timer interval "as is" if already at a "normal" rate */ | 284 | goto exit; |
| 273 | } else { | ||
| 274 | req->timer_intv *= 2; | ||
| 275 | if (req->timer_intv > TIPC_LINK_REQ_FAST) | ||
| 276 | req->timer_intv = TIPC_LINK_REQ_FAST; | ||
| 277 | if ((req->timer_intv == TIPC_LINK_REQ_FAST) && | ||
| 278 | (req->bearer->nodes.count)) | ||
| 279 | req->timer_intv = TIPC_LINK_REQ_SLOW; | ||
| 280 | } | 285 | } |
| 281 | k_start_timer(&req->timer, req->timer_intv); | ||
| 282 | 286 | ||
| 287 | /* | ||
| 288 | * Send discovery message, then update discovery timer | ||
| 289 | * | ||
| 290 | * Keep doubling time between requests until limit is reached; | ||
| 291 | * hold at fast polling rate if don't have any associated nodes, | ||
| 292 | * otherwise hold at slow polling rate | ||
| 293 | */ | ||
| 294 | |||
| 295 | disc_send_msg(req); | ||
| 296 | |||
| 297 | req->timer_intv *= 2; | ||
| 298 | if (req->num_nodes) | ||
| 299 | max_delay = TIPC_LINK_REQ_SLOW; | ||
| 300 | else | ||
| 301 | max_delay = TIPC_LINK_REQ_FAST; | ||
| 302 | if (req->timer_intv > max_delay) | ||
| 303 | req->timer_intv = max_delay; | ||
| 304 | |||
| 305 | k_start_timer(&req->timer, req->timer_intv); | ||
| 306 | exit: | ||
| 283 | spin_unlock_bh(&req->bearer->lock); | 307 | spin_unlock_bh(&req->bearer->lock); |
| 284 | } | 308 | } |
| 285 | 309 | ||
| 286 | /** | 310 | /** |
| 287 | * tipc_disc_init_link_req - start sending periodic link setup requests | 311 | * tipc_disc_create - create object to send periodic link setup requests |
| 288 | * @b_ptr: ptr to bearer issuing requests | 312 | * @b_ptr: ptr to bearer issuing requests |
| 289 | * @dest: destination address for request messages | 313 | * @dest: destination address for request messages |
| 290 | * @dest_domain: network domain of node(s) which should respond to message | 314 | * @dest_domain: network domain to which links can be established |
| 291 | * | 315 | * |
| 292 | * Returns pointer to link request structure, or NULL if unable to create. | 316 | * Returns 0 if successful, otherwise -errno. |
| 293 | */ | 317 | */ |
| 294 | 318 | ||
| 295 | struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr, | 319 | int tipc_disc_create(struct tipc_bearer *b_ptr, |
| 296 | const struct tipc_media_addr *dest, | 320 | struct tipc_media_addr *dest, u32 dest_domain) |
| 297 | u32 dest_domain) | ||
| 298 | { | 321 | { |
| 299 | struct link_req *req; | 322 | struct link_req *req; |
| 300 | 323 | ||
| 301 | req = kmalloc(sizeof(*req), GFP_ATOMIC); | 324 | req = kmalloc(sizeof(*req), GFP_ATOMIC); |
| 302 | if (!req) | 325 | if (!req) |
| 303 | return NULL; | 326 | return -ENOMEM; |
| 304 | 327 | ||
| 305 | req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr); | 328 | req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr); |
| 306 | if (!req->buf) { | 329 | if (!req->buf) { |
| 307 | kfree(req); | 330 | kfree(req); |
| 308 | return NULL; | 331 | return -ENOMSG; |
| 309 | } | 332 | } |
| 310 | 333 | ||
| 311 | memcpy(&req->dest, dest, sizeof(*dest)); | 334 | memcpy(&req->dest, dest, sizeof(*dest)); |
| 312 | req->bearer = b_ptr; | 335 | req->bearer = b_ptr; |
| 336 | req->domain = dest_domain; | ||
| 337 | req->num_nodes = 0; | ||
| 313 | req->timer_intv = TIPC_LINK_REQ_INIT; | 338 | req->timer_intv = TIPC_LINK_REQ_INIT; |
| 314 | k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); | 339 | k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); |
| 315 | k_start_timer(&req->timer, req->timer_intv); | 340 | k_start_timer(&req->timer, req->timer_intv); |
| 316 | return req; | 341 | b_ptr->link_req = req; |
| 342 | disc_send_msg(req); | ||
| 343 | return 0; | ||
| 344 | } | ||
| 345 | |||
| 346 | /** | ||
| 347 | * tipc_disc_delete - destroy object sending periodic link setup requests | ||
| 348 | * @req: ptr to link request structure | ||
| 349 | */ | ||
| 350 | |||
| 351 | void tipc_disc_delete(struct link_req *req) | ||
| 352 | { | ||
| 353 | k_cancel_timer(&req->timer); | ||
| 354 | k_term_timer(&req->timer); | ||
| 355 | buf_discard(req->buf); | ||
| 356 | kfree(req); | ||
| 317 | } | 357 | } |
| 318 | 358 | ||
