aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-05-11 12:41:28 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-11 12:41:28 -0400
commit0074820978004cc484b132d7a9ce0df414660d9d (patch)
tree2b5e95d1fd9eba7707cc529ac0099a8bf847581f
parent1fc19aff84edf97753c58cf4b858c6c4fdb246fa (diff)
parent972a77fbf1bbea6f54b5986b05041a17b607695b (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.h2
-rw-r--r--net/tipc/addr.h7
-rw-r--r--net/tipc/bcast.c22
-rw-r--r--net/tipc/bearer.c45
-rw-r--r--net/tipc/core.c3
-rw-r--r--net/tipc/discover.c150
-rw-r--r--net/tipc/discover.h11
-rw-r--r--net/tipc/link.c104
-rw-r--r--net/tipc/link.h1
-rw-r--r--net/tipc/msg.c25
-rw-r--r--net/tipc/msg.h161
-rw-r--r--net/tipc/port.c55
-rw-r--r--net/tipc/port.h14
-rw-r--r--net/tipc/socket.c27
-rw-r--r--net/tipc/subscr.c4
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
40static inline u32 tipc_zone_mask(u32 addr) 43static inline u32 tipc_zone_mask(u32 addr)
41{ 44{
42 return addr & 0xff000000u; 45 return addr & TIPC_ZONE_MASK;
43} 46}
44 47
45static inline u32 tipc_cluster_mask(u32 addr) 48static inline u32 tipc_cluster_mask(u32 addr)
46{ 49{
47 return addr & 0xfffff000u; 50 return addr & TIPC_CLUSTER_MASK;
48} 51}
49 52
50static inline int in_own_cluster(u32 addr) 53static 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
435void tipc_bclink_recv_pkt(struct sk_buff *buf) 426void 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);
482receive: 462receive:
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
47struct tipc_bearer tipc_bearers[MAX_BEARERS]; 47struct tipc_bearer tipc_bearers[MAX_BEARERS];
48 48
49static 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)
342void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest) 344void 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
349void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest) 351void 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; 585exit:
572failed:
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 @@
59struct link_req { 57struct 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
221void tipc_disc_stop_link_req(struct link_req *req) 224static 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
240void 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
237void tipc_disc_update_link_req(struct link_req *req) 250void 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) { 261static 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
264static void disc_timeout(struct link_req *req) 274static 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);
306exit:
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
295struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr, 319int 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
351void 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
40struct link_req; 40struct link_req;
41 41
42struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr, 42int 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); 44void tipc_disc_delete(struct link_req *req);
45void tipc_disc_update_link_req(struct link_req *req); 45void tipc_disc_add_dest(struct link_req *req);
46void tipc_disc_stop_link_req(struct link_req *req); 46void tipc_disc_remove_dest(struct link_req *req);
47
48void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr); 47void 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);
92static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); 92static void link_set_supervision_props(struct link *l_ptr, u32 tolerance);
93static int link_send_sections_long(struct tipc_port *sender, 93static 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);
96static void link_check_defragm_bufs(struct link *l_ptr); 97static void link_check_defragm_bufs(struct link *l_ptr);
97static void link_state_event(struct link *l_ptr, u32 event); 98static void link_state_event(struct link *l_ptr, u32 event);
98static void link_reset_statistics(struct link *l_ptr); 99static 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
846static 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)
1042int tipc_link_send_sections_fast(struct tipc_port *sender, 1063int 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);
1074exit: 1094exit:
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:
1138static int link_send_sections_long(struct tipc_port *sender, 1159static 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 */
2408static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) 2416static 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 }
2465exit:
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);
228int tipc_link_send_sections_fast(struct tipc_port *sender, 228int 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);
232void tipc_link_recv_bundle(struct sk_buff *buf); 233void tipc_link_recv_bundle(struct sk_buff *buf);
233int tipc_link_recv_fragment(struct sk_buff **pending, 234int 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
74int 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
92int tipc_msg_build(struct tipc_msg *hdr, 78int 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
802u32 tipc_msg_tot_importance(struct tipc_msg *m); 750u32 tipc_msg_tot_importance(struct tipc_msg *m);
803void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, 751void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
804 u32 hsize, u32 destnode); 752 u32 hsize, u32 destnode);
805int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect); 753int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
806int 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
810static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 757static 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
76int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, 76int 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
415int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, 420int 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
1160static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect, 1166static 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
1177int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) 1184int 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
1215int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, 1223int 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
1266int tipc_send2port(u32 ref, struct tipc_portid const *dest, 1275int 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 */
208int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); 208int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect,
209 unsigned int total_len);
209 210
210int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, 211int 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
213int tipc_send2port(u32 portref, struct tipc_portid const *dest, 215int 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
216int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, 219int 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
219int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, 222int 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
222int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, 226int 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);
225struct sk_buff *tipc_port_get_ports(void); 229struct sk_buff *tipc_port_get_ports(void);
226void tipc_port_recv_proto_msg(struct sk_buff *buf); 230void tipc_port_recv_proto_msg(struct sk_buff *buf);
227void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); 231void 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