diff options
author | David S. Miller <davem@davemloft.net> | 2011-05-11 12:41:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-11 12:41:28 -0400 |
commit | 0074820978004cc484b132d7a9ce0df414660d9d (patch) | |
tree | 2b5e95d1fd9eba7707cc529ac0099a8bf847581f | |
parent | 1fc19aff84edf97753c58cf4b858c6c4fdb246fa (diff) | |
parent | 972a77fbf1bbea6f54b5986b05041a17b607695b (diff) |
Merge branch 'tipc-May10-2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/net-next-2.6
-rw-r--r-- | include/linux/tipc.h | 2 | ||||
-rw-r--r-- | net/tipc/addr.h | 7 | ||||
-rw-r--r-- | net/tipc/bcast.c | 22 | ||||
-rw-r--r-- | net/tipc/bearer.c | 45 | ||||
-rw-r--r-- | net/tipc/core.c | 3 | ||||
-rw-r--r-- | net/tipc/discover.c | 150 | ||||
-rw-r--r-- | net/tipc/discover.h | 11 | ||||
-rw-r--r-- | net/tipc/link.c | 104 | ||||
-rw-r--r-- | net/tipc/link.h | 1 | ||||
-rw-r--r-- | net/tipc/msg.c | 25 | ||||
-rw-r--r-- | net/tipc/msg.h | 161 | ||||
-rw-r--r-- | net/tipc/port.c | 55 | ||||
-rw-r--r-- | net/tipc/port.h | 14 | ||||
-rw-r--r-- | net/tipc/socket.c | 27 | ||||
-rw-r--r-- | net/tipc/subscr.c | 4 |
15 files changed, 321 insertions, 310 deletions
diff --git a/include/linux/tipc.h b/include/linux/tipc.h index a5b994a204d2..f2d90091cc20 100644 --- a/include/linux/tipc.h +++ b/include/linux/tipc.h | |||
@@ -101,7 +101,7 @@ static inline unsigned int tipc_node(__u32 addr) | |||
101 | * Limiting values for messages | 101 | * Limiting values for messages |
102 | */ | 102 | */ |
103 | 103 | ||
104 | #define TIPC_MAX_USER_MSG_SIZE 66000 | 104 | #define TIPC_MAX_USER_MSG_SIZE 66000U |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * Message importance levels | 107 | * Message importance levels |
diff --git a/net/tipc/addr.h b/net/tipc/addr.h index 8971aba99aea..e4f35afe3207 100644 --- a/net/tipc/addr.h +++ b/net/tipc/addr.h | |||
@@ -37,14 +37,17 @@ | |||
37 | #ifndef _TIPC_ADDR_H | 37 | #ifndef _TIPC_ADDR_H |
38 | #define _TIPC_ADDR_H | 38 | #define _TIPC_ADDR_H |
39 | 39 | ||
40 | #define TIPC_ZONE_MASK 0xff000000u | ||
41 | #define TIPC_CLUSTER_MASK 0xfffff000u | ||
42 | |||
40 | static inline u32 tipc_zone_mask(u32 addr) | 43 | static inline u32 tipc_zone_mask(u32 addr) |
41 | { | 44 | { |
42 | return addr & 0xff000000u; | 45 | return addr & TIPC_ZONE_MASK; |
43 | } | 46 | } |
44 | 47 | ||
45 | static inline u32 tipc_cluster_mask(u32 addr) | 48 | static inline u32 tipc_cluster_mask(u32 addr) |
46 | { | 49 | { |
47 | return addr & 0xfffff000u; | 50 | return addr & TIPC_CLUSTER_MASK; |
48 | } | 51 | } |
49 | 52 | ||
50 | static inline int in_own_cluster(u32 addr) | 53 | static inline int in_own_cluster(u32 addr) |
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 7dc1dc7151ea..fa68d1e9ff4b 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -44,13 +44,6 @@ | |||
44 | 44 | ||
45 | #define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ | 45 | #define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ |
46 | 46 | ||
47 | /* | ||
48 | * Loss rate for incoming broadcast frames; used to test retransmission code. | ||
49 | * Set to N to cause every N'th frame to be discarded; 0 => don't discard any. | ||
50 | */ | ||
51 | |||
52 | #define TIPC_BCAST_LOSS_RATE 0 | ||
53 | |||
54 | /** | 47 | /** |
55 | * struct bcbearer_pair - a pair of bearers used by broadcast link | 48 | * struct bcbearer_pair - a pair of bearers used by broadcast link |
56 | * @primary: pointer to primary bearer | 49 | * @primary: pointer to primary bearer |
@@ -414,9 +407,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf) | |||
414 | spin_lock_bh(&bc_lock); | 407 | spin_lock_bh(&bc_lock); |
415 | 408 | ||
416 | res = tipc_link_send_buf(bcl, buf); | 409 | res = tipc_link_send_buf(bcl, buf); |
417 | if (unlikely(res == -ELINKCONG)) | 410 | if (likely(res > 0)) |
418 | buf_discard(buf); | ||
419 | else | ||
420 | bclink_set_last_sent(); | 411 | bclink_set_last_sent(); |
421 | 412 | ||
422 | bcl->stats.queue_sz_counts++; | 413 | bcl->stats.queue_sz_counts++; |
@@ -434,9 +425,6 @@ int tipc_bclink_send_msg(struct sk_buff *buf) | |||
434 | 425 | ||
435 | void tipc_bclink_recv_pkt(struct sk_buff *buf) | 426 | void tipc_bclink_recv_pkt(struct sk_buff *buf) |
436 | { | 427 | { |
437 | #if (TIPC_BCAST_LOSS_RATE) | ||
438 | static int rx_count; | ||
439 | #endif | ||
440 | struct tipc_msg *msg = buf_msg(buf); | 428 | struct tipc_msg *msg = buf_msg(buf); |
441 | struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); | 429 | struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); |
442 | u32 next_in; | 430 | u32 next_in; |
@@ -470,14 +458,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) | |||
470 | return; | 458 | return; |
471 | } | 459 | } |
472 | 460 | ||
473 | #if (TIPC_BCAST_LOSS_RATE) | ||
474 | if (++rx_count == TIPC_BCAST_LOSS_RATE) { | ||
475 | rx_count = 0; | ||
476 | buf_discard(buf); | ||
477 | return; | ||
478 | } | ||
479 | #endif | ||
480 | |||
481 | tipc_node_lock(node); | 461 | tipc_node_lock(node); |
482 | receive: | 462 | receive: |
483 | deferred = node->bclink.deferred_head; | 463 | deferred = node->bclink.deferred_head; |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 411719feb803..85209eadfae6 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -46,6 +46,8 @@ static u32 media_count; | |||
46 | 46 | ||
47 | struct tipc_bearer tipc_bearers[MAX_BEARERS]; | 47 | struct tipc_bearer tipc_bearers[MAX_BEARERS]; |
48 | 48 | ||
49 | static void bearer_disable(struct tipc_bearer *b_ptr); | ||
50 | |||
49 | /** | 51 | /** |
50 | * media_name_valid - validate media name | 52 | * media_name_valid - validate media name |
51 | * | 53 | * |
@@ -342,15 +344,15 @@ struct sk_buff *tipc_bearer_get_names(void) | |||
342 | void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest) | 344 | void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest) |
343 | { | 345 | { |
344 | tipc_nmap_add(&b_ptr->nodes, dest); | 346 | tipc_nmap_add(&b_ptr->nodes, dest); |
345 | tipc_disc_update_link_req(b_ptr->link_req); | ||
346 | tipc_bcbearer_sort(); | 347 | tipc_bcbearer_sort(); |
348 | tipc_disc_add_dest(b_ptr->link_req); | ||
347 | } | 349 | } |
348 | 350 | ||
349 | void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest) | 351 | void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest) |
350 | { | 352 | { |
351 | tipc_nmap_remove(&b_ptr->nodes, dest); | 353 | tipc_nmap_remove(&b_ptr->nodes, dest); |
352 | tipc_disc_update_link_req(b_ptr->link_req); | ||
353 | tipc_bcbearer_sort(); | 354 | tipc_bcbearer_sort(); |
355 | tipc_disc_remove_dest(b_ptr->link_req); | ||
354 | } | 356 | } |
355 | 357 | ||
356 | /* | 358 | /* |
@@ -493,8 +495,15 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) | |||
493 | warn("Bearer <%s> rejected, illegal name\n", name); | 495 | warn("Bearer <%s> rejected, illegal name\n", name); |
494 | return -EINVAL; | 496 | return -EINVAL; |
495 | } | 497 | } |
496 | if (!tipc_addr_domain_valid(disc_domain) || | 498 | if (tipc_addr_domain_valid(disc_domain) && |
497 | !tipc_in_scope(disc_domain, tipc_own_addr)) { | 499 | (disc_domain != tipc_own_addr)) { |
500 | if (tipc_in_scope(disc_domain, tipc_own_addr)) { | ||
501 | disc_domain = tipc_own_addr & TIPC_CLUSTER_MASK; | ||
502 | res = 0; /* accept any node in own cluster */ | ||
503 | } else if (in_own_cluster(disc_domain)) | ||
504 | res = 0; /* accept specified node in own cluster */ | ||
505 | } | ||
506 | if (res) { | ||
498 | warn("Bearer <%s> rejected, illegal discovery domain\n", name); | 507 | warn("Bearer <%s> rejected, illegal discovery domain\n", name); |
499 | return -EINVAL; | 508 | return -EINVAL; |
500 | } | 509 | } |
@@ -511,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) | |||
511 | if (!m_ptr) { | 520 | if (!m_ptr) { |
512 | warn("Bearer <%s> rejected, media <%s> not registered\n", name, | 521 | warn("Bearer <%s> rejected, media <%s> not registered\n", name, |
513 | b_name.media_name); | 522 | b_name.media_name); |
514 | goto failed; | 523 | goto exit; |
515 | } | 524 | } |
516 | 525 | ||
517 | if (priority == TIPC_MEDIA_LINK_PRI) | 526 | if (priority == TIPC_MEDIA_LINK_PRI) |
@@ -527,14 +536,14 @@ restart: | |||
527 | } | 536 | } |
528 | if (!strcmp(name, tipc_bearers[i].name)) { | 537 | if (!strcmp(name, tipc_bearers[i].name)) { |
529 | warn("Bearer <%s> rejected, already enabled\n", name); | 538 | warn("Bearer <%s> rejected, already enabled\n", name); |
530 | goto failed; | 539 | goto exit; |
531 | } | 540 | } |
532 | if ((tipc_bearers[i].priority == priority) && | 541 | if ((tipc_bearers[i].priority == priority) && |
533 | (++with_this_prio > 2)) { | 542 | (++with_this_prio > 2)) { |
534 | if (priority-- == 0) { | 543 | if (priority-- == 0) { |
535 | warn("Bearer <%s> rejected, duplicate priority\n", | 544 | warn("Bearer <%s> rejected, duplicate priority\n", |
536 | name); | 545 | name); |
537 | goto failed; | 546 | goto exit; |
538 | } | 547 | } |
539 | warn("Bearer <%s> priority adjustment required %u->%u\n", | 548 | warn("Bearer <%s> priority adjustment required %u->%u\n", |
540 | name, priority + 1, priority); | 549 | name, priority + 1, priority); |
@@ -544,7 +553,7 @@ restart: | |||
544 | if (bearer_id >= MAX_BEARERS) { | 553 | if (bearer_id >= MAX_BEARERS) { |
545 | warn("Bearer <%s> rejected, bearer limit reached (%u)\n", | 554 | warn("Bearer <%s> rejected, bearer limit reached (%u)\n", |
546 | name, MAX_BEARERS); | 555 | name, MAX_BEARERS); |
547 | goto failed; | 556 | goto exit; |
548 | } | 557 | } |
549 | 558 | ||
550 | b_ptr = &tipc_bearers[bearer_id]; | 559 | b_ptr = &tipc_bearers[bearer_id]; |
@@ -552,7 +561,7 @@ restart: | |||
552 | res = m_ptr->enable_bearer(b_ptr); | 561 | res = m_ptr->enable_bearer(b_ptr); |
553 | if (res) { | 562 | if (res) { |
554 | warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); | 563 | warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); |
555 | goto failed; | 564 | goto exit; |
556 | } | 565 | } |
557 | 566 | ||
558 | b_ptr->identity = bearer_id; | 567 | b_ptr->identity = bearer_id; |
@@ -562,14 +571,18 @@ restart: | |||
562 | b_ptr->priority = priority; | 571 | b_ptr->priority = priority; |
563 | INIT_LIST_HEAD(&b_ptr->cong_links); | 572 | INIT_LIST_HEAD(&b_ptr->cong_links); |
564 | INIT_LIST_HEAD(&b_ptr->links); | 573 | INIT_LIST_HEAD(&b_ptr->links); |
565 | b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, | ||
566 | disc_domain); | ||
567 | spin_lock_init(&b_ptr->lock); | 574 | spin_lock_init(&b_ptr->lock); |
568 | write_unlock_bh(&tipc_net_lock); | 575 | |
576 | res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain); | ||
577 | if (res) { | ||
578 | bearer_disable(b_ptr); | ||
579 | warn("Bearer <%s> rejected, discovery object creation failed\n", | ||
580 | name); | ||
581 | goto exit; | ||
582 | } | ||
569 | info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 583 | info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
570 | name, tipc_addr_string_fill(addr_string, disc_domain), priority); | 584 | name, tipc_addr_string_fill(addr_string, disc_domain), priority); |
571 | return 0; | 585 | exit: |
572 | failed: | ||
573 | write_unlock_bh(&tipc_net_lock); | 586 | write_unlock_bh(&tipc_net_lock); |
574 | return res; | 587 | return res; |
575 | } | 588 | } |
@@ -620,14 +633,14 @@ static void bearer_disable(struct tipc_bearer *b_ptr) | |||
620 | struct link *temp_l_ptr; | 633 | struct link *temp_l_ptr; |
621 | 634 | ||
622 | info("Disabling bearer <%s>\n", b_ptr->name); | 635 | info("Disabling bearer <%s>\n", b_ptr->name); |
623 | tipc_disc_stop_link_req(b_ptr->link_req); | ||
624 | spin_lock_bh(&b_ptr->lock); | 636 | spin_lock_bh(&b_ptr->lock); |
625 | b_ptr->link_req = NULL; | ||
626 | b_ptr->blocked = 1; | 637 | b_ptr->blocked = 1; |
627 | b_ptr->media->disable_bearer(b_ptr); | 638 | b_ptr->media->disable_bearer(b_ptr); |
628 | list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { | 639 | list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { |
629 | tipc_link_delete(l_ptr); | 640 | tipc_link_delete(l_ptr); |
630 | } | 641 | } |
642 | if (b_ptr->link_req) | ||
643 | tipc_disc_delete(b_ptr->link_req); | ||
631 | spin_unlock_bh(&b_ptr->lock); | 644 | spin_unlock_bh(&b_ptr->lock); |
632 | memset(b_ptr, 0, sizeof(struct tipc_bearer)); | 645 | memset(b_ptr, 0, sizeof(struct tipc_bearer)); |
633 | } | 646 | } |
diff --git a/net/tipc/core.c b/net/tipc/core.c index c9a73e7763f6..943b6af84265 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -179,8 +179,7 @@ static int __init tipc_init(void) | |||
179 | if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) | 179 | if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) |
180 | warn("Unable to create log buffer\n"); | 180 | warn("Unable to create log buffer\n"); |
181 | 181 | ||
182 | info("Activated (version " TIPC_MOD_VER | 182 | info("Activated (version " TIPC_MOD_VER ")\n"); |
183 | " compiled " __DATE__ " " __TIME__ ")\n"); | ||
184 | 183 | ||
185 | tipc_own_addr = 0; | 184 | tipc_own_addr = 0; |
186 | tipc_remote_management = 1; | 185 | tipc_remote_management = 1; |
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 | ||
diff --git a/net/tipc/discover.h b/net/tipc/discover.h index e48a167e47b2..a3af595b86cb 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h | |||
@@ -39,12 +39,11 @@ | |||
39 | 39 | ||
40 | struct link_req; | 40 | struct link_req; |
41 | 41 | ||
42 | struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr, | 42 | int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest, |
43 | const struct tipc_media_addr *dest, | 43 | u32 dest_domain); |
44 | u32 dest_domain); | 44 | void tipc_disc_delete(struct link_req *req); |
45 | void tipc_disc_update_link_req(struct link_req *req); | 45 | void tipc_disc_add_dest(struct link_req *req); |
46 | void tipc_disc_stop_link_req(struct link_req *req); | 46 | void tipc_disc_remove_dest(struct link_req *req); |
47 | |||
48 | void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr); | 47 | void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr); |
49 | 48 | ||
50 | #endif | 49 | #endif |
diff --git a/net/tipc/link.c b/net/tipc/link.c index ebf338f7b14e..5ed4b4f7452d 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -92,7 +92,8 @@ static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); | |||
92 | static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); | 92 | static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); |
93 | static int link_send_sections_long(struct tipc_port *sender, | 93 | static int link_send_sections_long(struct tipc_port *sender, |
94 | struct iovec const *msg_sect, | 94 | struct iovec const *msg_sect, |
95 | u32 num_sect, u32 destnode); | 95 | u32 num_sect, unsigned int total_len, |
96 | u32 destnode); | ||
96 | static void link_check_defragm_bufs(struct link *l_ptr); | 97 | static void link_check_defragm_bufs(struct link *l_ptr); |
97 | static void link_state_event(struct link *l_ptr, u32 event); | 98 | static void link_state_event(struct link *l_ptr, u32 event); |
98 | static void link_reset_statistics(struct link *l_ptr); | 99 | static void link_reset_statistics(struct link *l_ptr); |
@@ -842,6 +843,25 @@ static void link_add_to_outqueue(struct link *l_ptr, | |||
842 | l_ptr->stats.max_queue_sz = l_ptr->out_queue_size; | 843 | l_ptr->stats.max_queue_sz = l_ptr->out_queue_size; |
843 | } | 844 | } |
844 | 845 | ||
846 | static void link_add_chain_to_outqueue(struct link *l_ptr, | ||
847 | struct sk_buff *buf_chain, | ||
848 | u32 long_msgno) | ||
849 | { | ||
850 | struct sk_buff *buf; | ||
851 | struct tipc_msg *msg; | ||
852 | |||
853 | if (!l_ptr->next_out) | ||
854 | l_ptr->next_out = buf_chain; | ||
855 | while (buf_chain) { | ||
856 | buf = buf_chain; | ||
857 | buf_chain = buf_chain->next; | ||
858 | |||
859 | msg = buf_msg(buf); | ||
860 | msg_set_long_msgno(msg, long_msgno); | ||
861 | link_add_to_outqueue(l_ptr, buf, msg); | ||
862 | } | ||
863 | } | ||
864 | |||
845 | /* | 865 | /* |
846 | * tipc_link_send_buf() is the 'full path' for messages, called from | 866 | * tipc_link_send_buf() is the 'full path' for messages, called from |
847 | * inside TIPC when the 'fast path' in tipc_send_buf | 867 | * inside TIPC when the 'fast path' in tipc_send_buf |
@@ -864,8 +884,9 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) | |||
864 | 884 | ||
865 | if (unlikely(queue_size >= queue_limit)) { | 885 | if (unlikely(queue_size >= queue_limit)) { |
866 | if (imp <= TIPC_CRITICAL_IMPORTANCE) { | 886 | if (imp <= TIPC_CRITICAL_IMPORTANCE) { |
867 | return link_schedule_port(l_ptr, msg_origport(msg), | 887 | link_schedule_port(l_ptr, msg_origport(msg), size); |
868 | size); | 888 | buf_discard(buf); |
889 | return -ELINKCONG; | ||
869 | } | 890 | } |
870 | buf_discard(buf); | 891 | buf_discard(buf); |
871 | if (imp > CONN_MANAGER) { | 892 | if (imp > CONN_MANAGER) { |
@@ -1042,6 +1063,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) | |||
1042 | int tipc_link_send_sections_fast(struct tipc_port *sender, | 1063 | int tipc_link_send_sections_fast(struct tipc_port *sender, |
1043 | struct iovec const *msg_sect, | 1064 | struct iovec const *msg_sect, |
1044 | const u32 num_sect, | 1065 | const u32 num_sect, |
1066 | unsigned int total_len, | ||
1045 | u32 destaddr) | 1067 | u32 destaddr) |
1046 | { | 1068 | { |
1047 | struct tipc_msg *hdr = &sender->phdr; | 1069 | struct tipc_msg *hdr = &sender->phdr; |
@@ -1057,8 +1079,8 @@ again: | |||
1057 | * (Must not hold any locks while building message.) | 1079 | * (Must not hold any locks while building message.) |
1058 | */ | 1080 | */ |
1059 | 1081 | ||
1060 | res = tipc_msg_build(hdr, msg_sect, num_sect, sender->max_pkt, | 1082 | res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, |
1061 | !sender->user_port, &buf); | 1083 | sender->max_pkt, !sender->user_port, &buf); |
1062 | 1084 | ||
1063 | read_lock_bh(&tipc_net_lock); | 1085 | read_lock_bh(&tipc_net_lock); |
1064 | node = tipc_node_find(destaddr); | 1086 | node = tipc_node_find(destaddr); |
@@ -1069,8 +1091,6 @@ again: | |||
1069 | if (likely(buf)) { | 1091 | if (likely(buf)) { |
1070 | res = link_send_buf_fast(l_ptr, buf, | 1092 | res = link_send_buf_fast(l_ptr, buf, |
1071 | &sender->max_pkt); | 1093 | &sender->max_pkt); |
1072 | if (unlikely(res < 0)) | ||
1073 | buf_discard(buf); | ||
1074 | exit: | 1094 | exit: |
1075 | tipc_node_unlock(node); | 1095 | tipc_node_unlock(node); |
1076 | read_unlock_bh(&tipc_net_lock); | 1096 | read_unlock_bh(&tipc_net_lock); |
@@ -1105,7 +1125,8 @@ exit: | |||
1105 | goto again; | 1125 | goto again; |
1106 | 1126 | ||
1107 | return link_send_sections_long(sender, msg_sect, | 1127 | return link_send_sections_long(sender, msg_sect, |
1108 | num_sect, destaddr); | 1128 | num_sect, total_len, |
1129 | destaddr); | ||
1109 | } | 1130 | } |
1110 | tipc_node_unlock(node); | 1131 | tipc_node_unlock(node); |
1111 | } | 1132 | } |
@@ -1117,7 +1138,7 @@ exit: | |||
1117 | return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); | 1138 | return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); |
1118 | if (res >= 0) | 1139 | if (res >= 0) |
1119 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, | 1140 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, |
1120 | TIPC_ERR_NO_NODE); | 1141 | total_len, TIPC_ERR_NO_NODE); |
1121 | return res; | 1142 | return res; |
1122 | } | 1143 | } |
1123 | 1144 | ||
@@ -1138,12 +1159,13 @@ exit: | |||
1138 | static int link_send_sections_long(struct tipc_port *sender, | 1159 | static int link_send_sections_long(struct tipc_port *sender, |
1139 | struct iovec const *msg_sect, | 1160 | struct iovec const *msg_sect, |
1140 | u32 num_sect, | 1161 | u32 num_sect, |
1162 | unsigned int total_len, | ||
1141 | u32 destaddr) | 1163 | u32 destaddr) |
1142 | { | 1164 | { |
1143 | struct link *l_ptr; | 1165 | struct link *l_ptr; |
1144 | struct tipc_node *node; | 1166 | struct tipc_node *node; |
1145 | struct tipc_msg *hdr = &sender->phdr; | 1167 | struct tipc_msg *hdr = &sender->phdr; |
1146 | u32 dsz = msg_data_sz(hdr); | 1168 | u32 dsz = total_len; |
1147 | u32 max_pkt, fragm_sz, rest; | 1169 | u32 max_pkt, fragm_sz, rest; |
1148 | struct tipc_msg fragm_hdr; | 1170 | struct tipc_msg fragm_hdr; |
1149 | struct sk_buff *buf, *buf_chain, *prev; | 1171 | struct sk_buff *buf, *buf_chain, *prev; |
@@ -1169,7 +1191,6 @@ again: | |||
1169 | 1191 | ||
1170 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 1192 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
1171 | INT_H_SIZE, msg_destnode(hdr)); | 1193 | INT_H_SIZE, msg_destnode(hdr)); |
1172 | msg_set_link_selector(&fragm_hdr, sender->ref); | ||
1173 | msg_set_size(&fragm_hdr, max_pkt); | 1194 | msg_set_size(&fragm_hdr, max_pkt); |
1174 | msg_set_fragm_no(&fragm_hdr, 1); | 1195 | msg_set_fragm_no(&fragm_hdr, 1); |
1175 | 1196 | ||
@@ -1271,28 +1292,15 @@ reject: | |||
1271 | buf_discard(buf_chain); | 1292 | buf_discard(buf_chain); |
1272 | } | 1293 | } |
1273 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, | 1294 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, |
1274 | TIPC_ERR_NO_NODE); | 1295 | total_len, TIPC_ERR_NO_NODE); |
1275 | } | 1296 | } |
1276 | 1297 | ||
1277 | /* Append whole chain to send queue: */ | 1298 | /* Append chain of fragments to send queue & send them */ |
1278 | 1299 | ||
1279 | buf = buf_chain; | 1300 | l_ptr->long_msg_seq_no++; |
1280 | l_ptr->long_msg_seq_no = mod(l_ptr->long_msg_seq_no + 1); | 1301 | link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); |
1281 | if (!l_ptr->next_out) | 1302 | l_ptr->stats.sent_fragments += fragm_no; |
1282 | l_ptr->next_out = buf_chain; | ||
1283 | l_ptr->stats.sent_fragmented++; | 1303 | l_ptr->stats.sent_fragmented++; |
1284 | while (buf) { | ||
1285 | struct sk_buff *next = buf->next; | ||
1286 | struct tipc_msg *msg = buf_msg(buf); | ||
1287 | |||
1288 | l_ptr->stats.sent_fragments++; | ||
1289 | msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); | ||
1290 | link_add_to_outqueue(l_ptr, buf, msg); | ||
1291 | buf = next; | ||
1292 | } | ||
1293 | |||
1294 | /* Send it, if possible: */ | ||
1295 | |||
1296 | tipc_link_push_queue(l_ptr); | 1304 | tipc_link_push_queue(l_ptr); |
1297 | tipc_node_unlock(node); | 1305 | tipc_node_unlock(node); |
1298 | return dsz; | 1306 | return dsz; |
@@ -2407,6 +2415,8 @@ void tipc_link_recv_bundle(struct sk_buff *buf) | |||
2407 | */ | 2415 | */ |
2408 | static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | 2416 | static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) |
2409 | { | 2417 | { |
2418 | struct sk_buff *buf_chain = NULL; | ||
2419 | struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain; | ||
2410 | struct tipc_msg *inmsg = buf_msg(buf); | 2420 | struct tipc_msg *inmsg = buf_msg(buf); |
2411 | struct tipc_msg fragm_hdr; | 2421 | struct tipc_msg fragm_hdr; |
2412 | u32 insize = msg_size(inmsg); | 2422 | u32 insize = msg_size(inmsg); |
@@ -2415,7 +2425,7 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2415 | u32 rest = insize; | 2425 | u32 rest = insize; |
2416 | u32 pack_sz = l_ptr->max_pkt; | 2426 | u32 pack_sz = l_ptr->max_pkt; |
2417 | u32 fragm_sz = pack_sz - INT_H_SIZE; | 2427 | u32 fragm_sz = pack_sz - INT_H_SIZE; |
2418 | u32 fragm_no = 1; | 2428 | u32 fragm_no = 0; |
2419 | u32 destaddr; | 2429 | u32 destaddr; |
2420 | 2430 | ||
2421 | if (msg_short(inmsg)) | 2431 | if (msg_short(inmsg)) |
@@ -2427,10 +2437,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2427 | 2437 | ||
2428 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 2438 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
2429 | INT_H_SIZE, destaddr); | 2439 | INT_H_SIZE, destaddr); |
2430 | msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); | ||
2431 | msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); | ||
2432 | msg_set_fragm_no(&fragm_hdr, fragm_no); | ||
2433 | l_ptr->stats.sent_fragmented++; | ||
2434 | 2440 | ||
2435 | /* Chop up message: */ | 2441 | /* Chop up message: */ |
2436 | 2442 | ||
@@ -2443,27 +2449,37 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2443 | } | 2449 | } |
2444 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); | 2450 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
2445 | if (fragm == NULL) { | 2451 | if (fragm == NULL) { |
2446 | warn("Link unable to fragment message\n"); | 2452 | buf_discard(buf); |
2447 | dsz = -ENOMEM; | 2453 | while (buf_chain) { |
2448 | goto exit; | 2454 | buf = buf_chain; |
2455 | buf_chain = buf_chain->next; | ||
2456 | buf_discard(buf); | ||
2457 | } | ||
2458 | return -ENOMEM; | ||
2449 | } | 2459 | } |
2450 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); | 2460 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); |
2461 | fragm_no++; | ||
2462 | msg_set_fragm_no(&fragm_hdr, fragm_no); | ||
2451 | skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); | 2463 | skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); |
2452 | skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, | 2464 | skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, |
2453 | fragm_sz); | 2465 | fragm_sz); |
2454 | /* Send queued messages first, if any: */ | 2466 | buf_chain_tail->next = fragm; |
2467 | buf_chain_tail = fragm; | ||
2455 | 2468 | ||
2456 | l_ptr->stats.sent_fragments++; | ||
2457 | tipc_link_send_buf(l_ptr, fragm); | ||
2458 | if (!tipc_link_is_up(l_ptr)) | ||
2459 | return dsz; | ||
2460 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); | ||
2461 | rest -= fragm_sz; | 2469 | rest -= fragm_sz; |
2462 | crs += fragm_sz; | 2470 | crs += fragm_sz; |
2463 | msg_set_type(&fragm_hdr, FRAGMENT); | 2471 | msg_set_type(&fragm_hdr, FRAGMENT); |
2464 | } | 2472 | } |
2465 | exit: | ||
2466 | buf_discard(buf); | 2473 | buf_discard(buf); |
2474 | |||
2475 | /* Append chain of fragments to send queue & send them */ | ||
2476 | |||
2477 | l_ptr->long_msg_seq_no++; | ||
2478 | link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); | ||
2479 | l_ptr->stats.sent_fragments += fragm_no; | ||
2480 | l_ptr->stats.sent_fragmented++; | ||
2481 | tipc_link_push_queue(l_ptr); | ||
2482 | |||
2467 | return dsz; | 2483 | return dsz; |
2468 | } | 2484 | } |
2469 | 2485 | ||
diff --git a/net/tipc/link.h b/net/tipc/link.h index e6a30dbe1aaa..74fbecab1ea0 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h | |||
@@ -228,6 +228,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector); | |||
228 | int tipc_link_send_sections_fast(struct tipc_port *sender, | 228 | int tipc_link_send_sections_fast(struct tipc_port *sender, |
229 | struct iovec const *msg_sect, | 229 | struct iovec const *msg_sect, |
230 | const u32 num_sect, | 230 | const u32 num_sect, |
231 | unsigned int total_len, | ||
231 | u32 destnode); | 232 | u32 destnode); |
232 | void tipc_link_recv_bundle(struct sk_buff *buf); | 233 | void tipc_link_recv_bundle(struct sk_buff *buf); |
233 | int tipc_link_recv_fragment(struct sk_buff **pending, | 234 | int tipc_link_recv_fragment(struct sk_buff **pending, |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 6d92d17e7fb5..03e57bf92c73 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -68,20 +68,6 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, | |||
68 | } | 68 | } |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * tipc_msg_calc_data_size - determine total data size for message | ||
72 | */ | ||
73 | |||
74 | int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) | ||
75 | { | ||
76 | int dsz = 0; | ||
77 | int i; | ||
78 | |||
79 | for (i = 0; i < num_sect; i++) | ||
80 | dsz += msg_sect[i].iov_len; | ||
81 | return dsz; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * tipc_msg_build - create message using specified header and data | 71 | * tipc_msg_build - create message using specified header and data |
86 | * | 72 | * |
87 | * Note: Caller must not hold any locks in case copy_from_user() is interrupted! | 73 | * Note: Caller must not hold any locks in case copy_from_user() is interrupted! |
@@ -89,18 +75,13 @@ int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) | |||
89 | * Returns message data size or errno | 75 | * Returns message data size or errno |
90 | */ | 76 | */ |
91 | 77 | ||
92 | int tipc_msg_build(struct tipc_msg *hdr, | 78 | int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, |
93 | struct iovec const *msg_sect, u32 num_sect, | 79 | u32 num_sect, unsigned int total_len, |
94 | int max_size, int usrmem, struct sk_buff **buf) | 80 | int max_size, int usrmem, struct sk_buff **buf) |
95 | { | 81 | { |
96 | int dsz, sz, hsz, pos, res, cnt; | 82 | int dsz, sz, hsz, pos, res, cnt; |
97 | 83 | ||
98 | dsz = tipc_msg_calc_data_size(msg_sect, num_sect); | 84 | dsz = total_len; |
99 | if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { | ||
100 | *buf = NULL; | ||
101 | return -EINVAL; | ||
102 | } | ||
103 | |||
104 | pos = hsz = msg_hdr_sz(hdr); | 85 | pos = hsz = msg_hdr_sz(hdr); |
105 | sz = hsz + dsz; | 86 | sz = hsz + dsz; |
106 | msg_set_size(hdr, sz); | 87 | msg_set_size(hdr, sz); |
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index de02339fc175..8452454731fa 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -39,41 +39,24 @@ | |||
39 | 39 | ||
40 | #include "bearer.h" | 40 | #include "bearer.h" |
41 | 41 | ||
42 | /* | ||
43 | * Constants and routines used to read and write TIPC payload message headers | ||
44 | * | ||
45 | * Note: Some items are also used with TIPC internal message headers | ||
46 | */ | ||
47 | |||
42 | #define TIPC_VERSION 2 | 48 | #define TIPC_VERSION 2 |
43 | 49 | ||
44 | /* | 50 | /* |
45 | * TIPC user data message header format, version 2: | 51 | * Payload message users are defined in TIPC's public API: |
46 | * | 52 | * - TIPC_LOW_IMPORTANCE |
47 | * | 53 | * - TIPC_MEDIUM_IMPORTANCE |
48 | * 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 | 54 | * - TIPC_HIGH_IMPORTANCE |
49 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 55 | * - TIPC_CRITICAL_IMPORTANCE |
50 | * w0:|vers | user |hdr sz |n|d|s|-| message size | | 56 | */ |
51 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 57 | |
52 | * w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no | | 58 | /* |
53 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 59 | * Payload message types |
54 | * w2:| link level ack no | broadcast/link level seq no | | ||
55 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
56 | * w3:| previous node | | ||
57 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
58 | * w4:| originating port | | ||
59 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
60 | * w5:| destination port | | ||
61 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
62 | * w6:| originating node | | ||
63 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
64 | * w7:| destination node | | ||
65 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
66 | * w8:| name type / transport sequence number | | ||
67 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
68 | * w9:| name instance/multicast lower bound | | ||
69 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
70 | * wA:| multicast upper bound | | ||
71 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
72 | * / / | ||
73 | * \ options \ | ||
74 | * / / | ||
75 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
76 | * | ||
77 | */ | 60 | */ |
78 | 61 | ||
79 | #define TIPC_CONN_MSG 0 | 62 | #define TIPC_CONN_MSG 0 |
@@ -81,6 +64,9 @@ | |||
81 | #define TIPC_NAMED_MSG 2 | 64 | #define TIPC_NAMED_MSG 2 |
82 | #define TIPC_DIRECT_MSG 3 | 65 | #define TIPC_DIRECT_MSG 3 |
83 | 66 | ||
67 | /* | ||
68 | * Message header sizes | ||
69 | */ | ||
84 | 70 | ||
85 | #define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ | 71 | #define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ |
86 | #define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ | 72 | #define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ |
@@ -473,40 +459,11 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
473 | 459 | ||
474 | 460 | ||
475 | /* | 461 | /* |
476 | TIPC internal message header format, version 2 | 462 | * Constants and routines used to read and write TIPC internal message headers |
477 | 463 | */ | |
478 | 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 | ||
479 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
480 | w0:|vers |msg usr|hdr sz |n|resrv| packet size | | ||
481 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
482 | w1:|m typ| sequence gap | broadcast ack no | | ||
483 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
484 | w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | | ||
485 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
486 | w3:| previous node | | ||
487 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
488 | w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no | | ||
489 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
490 | w5:| session no |rsv=0|r|berid|link prio|netpl|p| | ||
491 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
492 | w6:| originating node | | ||
493 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
494 | w7:| destination node | | ||
495 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
496 | w8:| transport sequence number | | ||
497 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
498 | w9:| msg count / bcast tag | link tolerance | | ||
499 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
500 | \ \ | ||
501 | / User Specific Data / | ||
502 | \ \ | ||
503 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
504 | |||
505 | NB: CONN_MANAGER use data message format. LINK_CONFIG has own format. | ||
506 | */ | ||
507 | 464 | ||
508 | /* | 465 | /* |
509 | * Internal users | 466 | * Internal message users |
510 | */ | 467 | */ |
511 | 468 | ||
512 | #define BCAST_PROTOCOL 5 | 469 | #define BCAST_PROTOCOL 5 |
@@ -520,7 +477,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
520 | #define LINK_CONFIG 13 | 477 | #define LINK_CONFIG 13 |
521 | 478 | ||
522 | /* | 479 | /* |
523 | * Connection management protocol messages | 480 | * Connection management protocol message types |
524 | */ | 481 | */ |
525 | 482 | ||
526 | #define CONN_PROBE 0 | 483 | #define CONN_PROBE 0 |
@@ -528,12 +485,41 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) | |||
528 | #define CONN_ACK 2 | 485 | #define CONN_ACK 2 |
529 | 486 | ||
530 | /* | 487 | /* |
531 | * Name distributor messages | 488 | * Name distributor message types |
532 | */ | 489 | */ |
533 | 490 | ||
534 | #define PUBLICATION 0 | 491 | #define PUBLICATION 0 |
535 | #define WITHDRAWAL 1 | 492 | #define WITHDRAWAL 1 |
536 | 493 | ||
494 | /* | ||
495 | * Segmentation message types | ||
496 | */ | ||
497 | |||
498 | #define FIRST_FRAGMENT 0 | ||
499 | #define FRAGMENT 1 | ||
500 | #define LAST_FRAGMENT 2 | ||
501 | |||
502 | /* | ||
503 | * Link management protocol message types | ||
504 | */ | ||
505 | |||
506 | #define STATE_MSG 0 | ||
507 | #define RESET_MSG 1 | ||
508 | #define ACTIVATE_MSG 2 | ||
509 | |||
510 | /* | ||
511 | * Changeover tunnel message types | ||
512 | */ | ||
513 | #define DUPLICATE_MSG 0 | ||
514 | #define ORIGINAL_MSG 1 | ||
515 | |||
516 | /* | ||
517 | * Config protocol message types | ||
518 | */ | ||
519 | |||
520 | #define DSC_REQ_MSG 0 | ||
521 | #define DSC_RESP_MSG 1 | ||
522 | |||
537 | 523 | ||
538 | /* | 524 | /* |
539 | * Word 1 | 525 | * Word 1 |
@@ -761,50 +747,11 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) | |||
761 | msg_set_bits(m, 9, 0, 0xffff, n); | 747 | msg_set_bits(m, 9, 0, 0xffff, n); |
762 | } | 748 | } |
763 | 749 | ||
764 | /* | ||
765 | * Segmentation message types | ||
766 | */ | ||
767 | |||
768 | #define FIRST_FRAGMENT 0 | ||
769 | #define FRAGMENT 1 | ||
770 | #define LAST_FRAGMENT 2 | ||
771 | |||
772 | /* | ||
773 | * Link management protocol message types | ||
774 | */ | ||
775 | |||
776 | #define STATE_MSG 0 | ||
777 | #define RESET_MSG 1 | ||
778 | #define ACTIVATE_MSG 2 | ||
779 | |||
780 | /* | ||
781 | * Changeover tunnel message types | ||
782 | */ | ||
783 | #define DUPLICATE_MSG 0 | ||
784 | #define ORIGINAL_MSG 1 | ||
785 | |||
786 | /* | ||
787 | * Routing table message types | ||
788 | */ | ||
789 | #define EXT_ROUTING_TABLE 0 | ||
790 | #define LOCAL_ROUTING_TABLE 1 /* obsoleted */ | ||
791 | #define SLAVE_ROUTING_TABLE 2 | ||
792 | #define ROUTE_ADDITION 3 | ||
793 | #define ROUTE_REMOVAL 4 | ||
794 | |||
795 | /* | ||
796 | * Config protocol message types | ||
797 | */ | ||
798 | |||
799 | #define DSC_REQ_MSG 0 | ||
800 | #define DSC_RESP_MSG 1 | ||
801 | |||
802 | u32 tipc_msg_tot_importance(struct tipc_msg *m); | 750 | u32 tipc_msg_tot_importance(struct tipc_msg *m); |
803 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, | 751 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, |
804 | u32 hsize, u32 destnode); | 752 | u32 hsize, u32 destnode); |
805 | int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect); | 753 | int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, |
806 | int tipc_msg_build(struct tipc_msg *hdr, | 754 | u32 num_sect, unsigned int total_len, |
807 | struct iovec const *msg_sect, u32 num_sect, | ||
808 | int max_size, int usrmem, struct sk_buff **buf); | 755 | int max_size, int usrmem, struct sk_buff **buf); |
809 | 756 | ||
810 | static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) | 757 | static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) |
diff --git a/net/tipc/port.c b/net/tipc/port.c index 6ff78f9c7d65..c68dc956a423 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -74,7 +74,8 @@ static u32 port_peerport(struct tipc_port *p_ptr) | |||
74 | */ | 74 | */ |
75 | 75 | ||
76 | int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, | 76 | int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, |
77 | u32 num_sect, struct iovec const *msg_sect) | 77 | u32 num_sect, struct iovec const *msg_sect, |
78 | unsigned int total_len) | ||
78 | { | 79 | { |
79 | struct tipc_msg *hdr; | 80 | struct tipc_msg *hdr; |
80 | struct sk_buff *buf; | 81 | struct sk_buff *buf; |
@@ -91,11 +92,14 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, | |||
91 | 92 | ||
92 | hdr = &oport->phdr; | 93 | hdr = &oport->phdr; |
93 | msg_set_type(hdr, TIPC_MCAST_MSG); | 94 | msg_set_type(hdr, TIPC_MCAST_MSG); |
95 | msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE); | ||
96 | msg_set_destport(hdr, 0); | ||
97 | msg_set_destnode(hdr, 0); | ||
94 | msg_set_nametype(hdr, seq->type); | 98 | msg_set_nametype(hdr, seq->type); |
95 | msg_set_namelower(hdr, seq->lower); | 99 | msg_set_namelower(hdr, seq->lower); |
96 | msg_set_nameupper(hdr, seq->upper); | 100 | msg_set_nameupper(hdr, seq->upper); |
97 | msg_set_hdr_sz(hdr, MCAST_H_SIZE); | 101 | msg_set_hdr_sz(hdr, MCAST_H_SIZE); |
98 | res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, | 102 | res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, |
99 | !oport->user_port, &buf); | 103 | !oport->user_port, &buf); |
100 | if (unlikely(!buf)) | 104 | if (unlikely(!buf)) |
101 | return res; | 105 | return res; |
@@ -161,6 +165,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) | |||
161 | /* Deliver a copy of message to each destination port */ | 165 | /* Deliver a copy of message to each destination port */ |
162 | 166 | ||
163 | if (dp->count != 0) { | 167 | if (dp->count != 0) { |
168 | msg_set_destnode(msg, tipc_own_addr); | ||
164 | if (dp->count == 1) { | 169 | if (dp->count == 1) { |
165 | msg_set_destport(msg, dp->ports[0]); | 170 | msg_set_destport(msg, dp->ports[0]); |
166 | tipc_port_recv_msg(buf); | 171 | tipc_port_recv_msg(buf); |
@@ -414,12 +419,12 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
414 | 419 | ||
415 | int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, | 420 | int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, |
416 | struct iovec const *msg_sect, u32 num_sect, | 421 | struct iovec const *msg_sect, u32 num_sect, |
417 | int err) | 422 | unsigned int total_len, int err) |
418 | { | 423 | { |
419 | struct sk_buff *buf; | 424 | struct sk_buff *buf; |
420 | int res; | 425 | int res; |
421 | 426 | ||
422 | res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, | 427 | res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, |
423 | !p_ptr->user_port, &buf); | 428 | !p_ptr->user_port, &buf); |
424 | if (!buf) | 429 | if (!buf) |
425 | return res; | 430 | return res; |
@@ -1065,6 +1070,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer) | |||
1065 | msg_set_orignode(msg, tipc_own_addr); | 1070 | msg_set_orignode(msg, tipc_own_addr); |
1066 | msg_set_origport(msg, p_ptr->ref); | 1071 | msg_set_origport(msg, p_ptr->ref); |
1067 | msg_set_type(msg, TIPC_CONN_MSG); | 1072 | msg_set_type(msg, TIPC_CONN_MSG); |
1073 | msg_set_lookup_scope(msg, 0); | ||
1068 | msg_set_hdr_sz(msg, SHORT_H_SIZE); | 1074 | msg_set_hdr_sz(msg, SHORT_H_SIZE); |
1069 | 1075 | ||
1070 | p_ptr->probing_interval = PROBING_INTERVAL; | 1076 | p_ptr->probing_interval = PROBING_INTERVAL; |
@@ -1158,12 +1164,13 @@ int tipc_shutdown(u32 ref) | |||
1158 | */ | 1164 | */ |
1159 | 1165 | ||
1160 | static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect, | 1166 | static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect, |
1161 | struct iovec const *msg_sect) | 1167 | struct iovec const *msg_sect, |
1168 | unsigned int total_len) | ||
1162 | { | 1169 | { |
1163 | struct sk_buff *buf; | 1170 | struct sk_buff *buf; |
1164 | int res; | 1171 | int res; |
1165 | 1172 | ||
1166 | res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, | 1173 | res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len, |
1167 | MAX_MSG_SIZE, !sender->user_port, &buf); | 1174 | MAX_MSG_SIZE, !sender->user_port, &buf); |
1168 | if (likely(buf)) | 1175 | if (likely(buf)) |
1169 | tipc_port_recv_msg(buf); | 1176 | tipc_port_recv_msg(buf); |
@@ -1174,7 +1181,8 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se | |||
1174 | * tipc_send - send message sections on connection | 1181 | * tipc_send - send message sections on connection |
1175 | */ | 1182 | */ |
1176 | 1183 | ||
1177 | int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) | 1184 | int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect, |
1185 | unsigned int total_len) | ||
1178 | { | 1186 | { |
1179 | struct tipc_port *p_ptr; | 1187 | struct tipc_port *p_ptr; |
1180 | u32 destnode; | 1188 | u32 destnode; |
@@ -1189,9 +1197,10 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) | |||
1189 | destnode = port_peernode(p_ptr); | 1197 | destnode = port_peernode(p_ptr); |
1190 | if (likely(destnode != tipc_own_addr)) | 1198 | if (likely(destnode != tipc_own_addr)) |
1191 | res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, | 1199 | res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, |
1192 | destnode); | 1200 | total_len, destnode); |
1193 | else | 1201 | else |
1194 | res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); | 1202 | res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, |
1203 | total_len); | ||
1195 | 1204 | ||
1196 | if (likely(res != -ELINKCONG)) { | 1205 | if (likely(res != -ELINKCONG)) { |
1197 | p_ptr->congested = 0; | 1206 | p_ptr->congested = 0; |
@@ -1202,8 +1211,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) | |||
1202 | } | 1211 | } |
1203 | if (port_unreliable(p_ptr)) { | 1212 | if (port_unreliable(p_ptr)) { |
1204 | p_ptr->congested = 0; | 1213 | p_ptr->congested = 0; |
1205 | /* Just calculate msg length and return */ | 1214 | return total_len; |
1206 | return tipc_msg_calc_data_size(msg_sect, num_sect); | ||
1207 | } | 1215 | } |
1208 | return -ELINKCONG; | 1216 | return -ELINKCONG; |
1209 | } | 1217 | } |
@@ -1213,7 +1221,8 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) | |||
1213 | */ | 1221 | */ |
1214 | 1222 | ||
1215 | int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, | 1223 | int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, |
1216 | unsigned int num_sect, struct iovec const *msg_sect) | 1224 | unsigned int num_sect, struct iovec const *msg_sect, |
1225 | unsigned int total_len) | ||
1217 | { | 1226 | { |
1218 | struct tipc_port *p_ptr; | 1227 | struct tipc_port *p_ptr; |
1219 | struct tipc_msg *msg; | 1228 | struct tipc_msg *msg; |
@@ -1240,23 +1249,23 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, | |||
1240 | if (likely(destport)) { | 1249 | if (likely(destport)) { |
1241 | if (likely(destnode == tipc_own_addr)) | 1250 | if (likely(destnode == tipc_own_addr)) |
1242 | res = tipc_port_recv_sections(p_ptr, num_sect, | 1251 | res = tipc_port_recv_sections(p_ptr, num_sect, |
1243 | msg_sect); | 1252 | msg_sect, total_len); |
1244 | else | 1253 | else |
1245 | res = tipc_link_send_sections_fast(p_ptr, msg_sect, | 1254 | res = tipc_link_send_sections_fast(p_ptr, msg_sect, |
1246 | num_sect, destnode); | 1255 | num_sect, total_len, |
1256 | destnode); | ||
1247 | if (likely(res != -ELINKCONG)) { | 1257 | if (likely(res != -ELINKCONG)) { |
1248 | if (res > 0) | 1258 | if (res > 0) |
1249 | p_ptr->sent++; | 1259 | p_ptr->sent++; |
1250 | return res; | 1260 | return res; |
1251 | } | 1261 | } |
1252 | if (port_unreliable(p_ptr)) { | 1262 | if (port_unreliable(p_ptr)) { |
1253 | /* Just calculate msg length and return */ | 1263 | return total_len; |
1254 | return tipc_msg_calc_data_size(msg_sect, num_sect); | ||
1255 | } | 1264 | } |
1256 | return -ELINKCONG; | 1265 | return -ELINKCONG; |
1257 | } | 1266 | } |
1258 | return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, | 1267 | return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, |
1259 | TIPC_ERR_NO_NAME); | 1268 | total_len, TIPC_ERR_NO_NAME); |
1260 | } | 1269 | } |
1261 | 1270 | ||
1262 | /** | 1271 | /** |
@@ -1264,7 +1273,8 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, | |||
1264 | */ | 1273 | */ |
1265 | 1274 | ||
1266 | int tipc_send2port(u32 ref, struct tipc_portid const *dest, | 1275 | int tipc_send2port(u32 ref, struct tipc_portid const *dest, |
1267 | unsigned int num_sect, struct iovec const *msg_sect) | 1276 | unsigned int num_sect, struct iovec const *msg_sect, |
1277 | unsigned int total_len) | ||
1268 | { | 1278 | { |
1269 | struct tipc_port *p_ptr; | 1279 | struct tipc_port *p_ptr; |
1270 | struct tipc_msg *msg; | 1280 | struct tipc_msg *msg; |
@@ -1276,6 +1286,7 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest, | |||
1276 | 1286 | ||
1277 | msg = &p_ptr->phdr; | 1287 | msg = &p_ptr->phdr; |
1278 | msg_set_type(msg, TIPC_DIRECT_MSG); | 1288 | msg_set_type(msg, TIPC_DIRECT_MSG); |
1289 | msg_set_lookup_scope(msg, 0); | ||
1279 | msg_set_orignode(msg, tipc_own_addr); | 1290 | msg_set_orignode(msg, tipc_own_addr); |
1280 | msg_set_origport(msg, ref); | 1291 | msg_set_origport(msg, ref); |
1281 | msg_set_destnode(msg, dest->node); | 1292 | msg_set_destnode(msg, dest->node); |
@@ -1283,18 +1294,18 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest, | |||
1283 | msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); | 1294 | msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); |
1284 | 1295 | ||
1285 | if (dest->node == tipc_own_addr) | 1296 | if (dest->node == tipc_own_addr) |
1286 | res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); | 1297 | res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, |
1298 | total_len); | ||
1287 | else | 1299 | else |
1288 | res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, | 1300 | res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, |
1289 | dest->node); | 1301 | total_len, dest->node); |
1290 | if (likely(res != -ELINKCONG)) { | 1302 | if (likely(res != -ELINKCONG)) { |
1291 | if (res > 0) | 1303 | if (res > 0) |
1292 | p_ptr->sent++; | 1304 | p_ptr->sent++; |
1293 | return res; | 1305 | return res; |
1294 | } | 1306 | } |
1295 | if (port_unreliable(p_ptr)) { | 1307 | if (port_unreliable(p_ptr)) { |
1296 | /* Just calculate msg length and return */ | 1308 | return total_len; |
1297 | return tipc_msg_calc_data_size(msg_sect, num_sect); | ||
1298 | } | 1309 | } |
1299 | return -ELINKCONG; | 1310 | return -ELINKCONG; |
1300 | } | 1311 | } |
diff --git a/net/tipc/port.h b/net/tipc/port.h index 87b9424ae0ec..b9aa34195aec 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
@@ -205,23 +205,27 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr); | |||
205 | /* | 205 | /* |
206 | * TIPC messaging routines | 206 | * TIPC messaging routines |
207 | */ | 207 | */ |
208 | int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); | 208 | int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect, |
209 | unsigned int total_len); | ||
209 | 210 | ||
210 | int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, | 211 | int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, |
211 | unsigned int num_sect, struct iovec const *msg_sect); | 212 | unsigned int num_sect, struct iovec const *msg_sect, |
213 | unsigned int total_len); | ||
212 | 214 | ||
213 | int tipc_send2port(u32 portref, struct tipc_portid const *dest, | 215 | int tipc_send2port(u32 portref, struct tipc_portid const *dest, |
214 | unsigned int num_sect, struct iovec const *msg_sect); | 216 | unsigned int num_sect, struct iovec const *msg_sect, |
217 | unsigned int total_len); | ||
215 | 218 | ||
216 | int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, | 219 | int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, |
217 | struct sk_buff *buf, unsigned int dsz); | 220 | struct sk_buff *buf, unsigned int dsz); |
218 | 221 | ||
219 | int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, | 222 | int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, |
220 | unsigned int section_count, struct iovec const *msg); | 223 | unsigned int section_count, struct iovec const *msg, |
224 | unsigned int total_len); | ||
221 | 225 | ||
222 | int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, | 226 | int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, |
223 | struct iovec const *msg_sect, u32 num_sect, | 227 | struct iovec const *msg_sect, u32 num_sect, |
224 | int err); | 228 | unsigned int total_len, int err); |
225 | struct sk_buff *tipc_port_get_ports(void); | 229 | struct sk_buff *tipc_port_get_ports(void); |
226 | void tipc_port_recv_proto_msg(struct sk_buff *buf); | 230 | void tipc_port_recv_proto_msg(struct sk_buff *buf); |
227 | void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); | 231 | void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 29d94d53198d..338837396642 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -535,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
535 | if (unlikely((m->msg_namelen < sizeof(*dest)) || | 535 | if (unlikely((m->msg_namelen < sizeof(*dest)) || |
536 | (dest->family != AF_TIPC))) | 536 | (dest->family != AF_TIPC))) |
537 | return -EINVAL; | 537 | return -EINVAL; |
538 | if ((total_len > TIPC_MAX_USER_MSG_SIZE) || | ||
539 | (m->msg_iovlen > (unsigned)INT_MAX)) | ||
540 | return -EMSGSIZE; | ||
538 | 541 | ||
539 | if (iocb) | 542 | if (iocb) |
540 | lock_sock(sk); | 543 | lock_sock(sk); |
@@ -573,12 +576,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
573 | &dest->addr.name.name, | 576 | &dest->addr.name.name, |
574 | dest->addr.name.domain, | 577 | dest->addr.name.domain, |
575 | m->msg_iovlen, | 578 | m->msg_iovlen, |
576 | m->msg_iov); | 579 | m->msg_iov, |
580 | total_len); | ||
577 | } else if (dest->addrtype == TIPC_ADDR_ID) { | 581 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
578 | res = tipc_send2port(tport->ref, | 582 | res = tipc_send2port(tport->ref, |
579 | &dest->addr.id, | 583 | &dest->addr.id, |
580 | m->msg_iovlen, | 584 | m->msg_iovlen, |
581 | m->msg_iov); | 585 | m->msg_iov, |
586 | total_len); | ||
582 | } else if (dest->addrtype == TIPC_ADDR_MCAST) { | 587 | } else if (dest->addrtype == TIPC_ADDR_MCAST) { |
583 | if (needs_conn) { | 588 | if (needs_conn) { |
584 | res = -EOPNOTSUPP; | 589 | res = -EOPNOTSUPP; |
@@ -590,7 +595,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
590 | res = tipc_multicast(tport->ref, | 595 | res = tipc_multicast(tport->ref, |
591 | &dest->addr.nameseq, | 596 | &dest->addr.nameseq, |
592 | m->msg_iovlen, | 597 | m->msg_iovlen, |
593 | m->msg_iov); | 598 | m->msg_iov, |
599 | total_len); | ||
594 | } | 600 | } |
595 | if (likely(res != -ELINKCONG)) { | 601 | if (likely(res != -ELINKCONG)) { |
596 | if (needs_conn && (res >= 0)) | 602 | if (needs_conn && (res >= 0)) |
@@ -640,6 +646,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
640 | if (unlikely(dest)) | 646 | if (unlikely(dest)) |
641 | return send_msg(iocb, sock, m, total_len); | 647 | return send_msg(iocb, sock, m, total_len); |
642 | 648 | ||
649 | if ((total_len > TIPC_MAX_USER_MSG_SIZE) || | ||
650 | (m->msg_iovlen > (unsigned)INT_MAX)) | ||
651 | return -EMSGSIZE; | ||
652 | |||
643 | if (iocb) | 653 | if (iocb) |
644 | lock_sock(sk); | 654 | lock_sock(sk); |
645 | 655 | ||
@@ -652,7 +662,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
652 | break; | 662 | break; |
653 | } | 663 | } |
654 | 664 | ||
655 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); | 665 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov, |
666 | total_len); | ||
656 | if (likely(res != -ELINKCONG)) | 667 | if (likely(res != -ELINKCONG)) |
657 | break; | 668 | break; |
658 | if (m->msg_flags & MSG_DONTWAIT) { | 669 | if (m->msg_flags & MSG_DONTWAIT) { |
@@ -723,6 +734,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
723 | goto exit; | 734 | goto exit; |
724 | } | 735 | } |
725 | 736 | ||
737 | if ((total_len > (unsigned)INT_MAX) || | ||
738 | (m->msg_iovlen > (unsigned)INT_MAX)) { | ||
739 | res = -EMSGSIZE; | ||
740 | goto exit; | ||
741 | } | ||
742 | |||
726 | /* | 743 | /* |
727 | * Send each iovec entry using one or more messages | 744 | * Send each iovec entry using one or more messages |
728 | * | 745 | * |
@@ -753,7 +770,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
753 | bytes_to_send = curr_left; | 770 | bytes_to_send = curr_left; |
754 | my_iov.iov_base = curr_start; | 771 | my_iov.iov_base = curr_start; |
755 | my_iov.iov_len = bytes_to_send; | 772 | my_iov.iov_len = bytes_to_send; |
756 | res = send_packet(NULL, sock, &my_msg, 0); | 773 | res = send_packet(NULL, sock, &my_msg, bytes_to_send); |
757 | if (res < 0) { | 774 | if (res < 0) { |
758 | if (bytes_sent) | 775 | if (bytes_sent) |
759 | res = bytes_sent; | 776 | res = bytes_sent; |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index aae9eae13404..6cf726863485 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -109,7 +109,7 @@ static void subscr_send_event(struct subscription *sub, | |||
109 | sub->evt.found_upper = htohl(found_upper, sub->swap); | 109 | sub->evt.found_upper = htohl(found_upper, sub->swap); |
110 | sub->evt.port.ref = htohl(port_ref, sub->swap); | 110 | sub->evt.port.ref = htohl(port_ref, sub->swap); |
111 | sub->evt.port.node = htohl(node, sub->swap); | 111 | sub->evt.port.node = htohl(node, sub->swap); |
112 | tipc_send(sub->server_ref, 1, &msg_sect); | 112 | tipc_send(sub->server_ref, 1, &msg_sect, msg_sect.iov_len); |
113 | } | 113 | } |
114 | 114 | ||
115 | /** | 115 | /** |
@@ -521,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle, | |||
521 | 521 | ||
522 | /* Send an ACK- to complete connection handshaking */ | 522 | /* Send an ACK- to complete connection handshaking */ |
523 | 523 | ||
524 | tipc_send(server_port_ref, 0, NULL); | 524 | tipc_send(server_port_ref, 0, NULL, 0); |
525 | 525 | ||
526 | /* Handle optional subscription request */ | 526 | /* Handle optional subscription request */ |
527 | 527 | ||