diff options
Diffstat (limited to 'net/tipc')
| -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 |
14 files changed, 320 insertions, 309 deletions
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 | ||
