aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Kconfig12
-rw-r--r--net/tipc/addr.c15
-rw-r--r--net/tipc/addr.h20
-rw-r--r--net/tipc/bcast.c69
-rw-r--r--net/tipc/bcast.h3
-rw-r--r--net/tipc/bearer.c151
-rw-r--r--net/tipc/bearer.h73
-rw-r--r--net/tipc/config.c31
-rw-r--r--net/tipc/core.c12
-rw-r--r--net/tipc/core.h4
-rw-r--r--net/tipc/discover.c284
-rw-r--r--net/tipc/discover.h16
-rw-r--r--net/tipc/link.c232
-rw-r--r--net/tipc/link.h30
-rw-r--r--net/tipc/msg.c66
-rw-r--r--net/tipc/msg.h225
-rw-r--r--net/tipc/name_distr.c20
-rw-r--r--net/tipc/net.c32
-rw-r--r--net/tipc/net.h19
-rw-r--r--net/tipc/node.c125
-rw-r--r--net/tipc/node.h36
-rw-r--r--net/tipc/node_subscr.c21
-rw-r--r--net/tipc/node_subscr.h3
-rw-r--r--net/tipc/port.c351
-rw-r--r--net/tipc/port.h87
-rw-r--r--net/tipc/socket.c103
-rw-r--r--net/tipc/subscr.c15
27 files changed, 946 insertions, 1109 deletions
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index 0436927369f3..2c5954b85933 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -29,18 +29,6 @@ config TIPC_ADVANCED
29 Saying Y here will open some advanced configuration for TIPC. 29 Saying Y here will open some advanced configuration for TIPC.
30 Most users do not need to bother; if unsure, just say N. 30 Most users do not need to bother; if unsure, just say N.
31 31
32config TIPC_NODES
33 int "Maximum number of nodes in a cluster"
34 depends on TIPC_ADVANCED
35 range 8 2047
36 default "255"
37 help
38 Specifies how many nodes can be supported in a TIPC cluster.
39 Can range from 8 to 2047 nodes; default is 255.
40
41 Setting this to a smaller value saves some memory;
42 setting it to higher allows for more nodes.
43
44config TIPC_PORTS 32config TIPC_PORTS
45 int "Maximum number of ports in a node" 33 int "Maximum number of ports in a node"
46 depends on TIPC_ADVANCED 34 depends on TIPC_ADVANCED
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 88463d9a6f12..a6fdab33877e 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -2,7 +2,7 @@
2 * net/tipc/addr.c: TIPC address utility routines 2 * net/tipc/addr.c: TIPC address utility routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@
41 * tipc_addr_domain_valid - validates a network domain address 41 * tipc_addr_domain_valid - validates a network domain address
42 * 42 *
43 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>, 43 * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>,
44 * where Z, C, and N are non-zero and do not exceed the configured limits. 44 * where Z, C, and N are non-zero.
45 * 45 *
46 * Returns 1 if domain address is valid, otherwise 0 46 * Returns 1 if domain address is valid, otherwise 0
47 */ 47 */
@@ -51,10 +51,6 @@ int tipc_addr_domain_valid(u32 addr)
51 u32 n = tipc_node(addr); 51 u32 n = tipc_node(addr);
52 u32 c = tipc_cluster(addr); 52 u32 c = tipc_cluster(addr);
53 u32 z = tipc_zone(addr); 53 u32 z = tipc_zone(addr);
54 u32 max_nodes = tipc_max_nodes;
55
56 if (n > max_nodes)
57 return 0;
58 54
59 if (n && (!z || !c)) 55 if (n && (!z || !c))
60 return 0; 56 return 0;
@@ -66,8 +62,7 @@ int tipc_addr_domain_valid(u32 addr)
66/** 62/**
67 * tipc_addr_node_valid - validates a proposed network address for this node 63 * tipc_addr_node_valid - validates a proposed network address for this node
68 * 64 *
69 * Accepts <Z.C.N>, where Z, C, and N are non-zero and do not exceed 65 * Accepts <Z.C.N>, where Z, C, and N are non-zero.
70 * the configured limits.
71 * 66 *
72 * Returns 1 if address can be used, otherwise 0 67 * Returns 1 if address can be used, otherwise 0
73 */ 68 */
@@ -81,9 +76,9 @@ int tipc_in_scope(u32 domain, u32 addr)
81{ 76{
82 if (!domain || (domain == addr)) 77 if (!domain || (domain == addr))
83 return 1; 78 return 1;
84 if (domain == (addr & 0xfffff000u)) /* domain <Z.C.0> */ 79 if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
85 return 1; 80 return 1;
86 if (domain == (addr & 0xff000000u)) /* domain <Z.0.0> */ 81 if (domain == tipc_zone_mask(addr)) /* domain <Z.0.0> */
87 return 1; 82 return 1;
88 return 0; 83 return 0;
89} 84}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 2490fadd0caf..e4f35afe3207 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,6 +37,19 @@
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
43static inline u32 tipc_zone_mask(u32 addr)
44{
45 return addr & TIPC_ZONE_MASK;
46}
47
48static inline u32 tipc_cluster_mask(u32 addr)
49{
50 return addr & TIPC_CLUSTER_MASK;
51}
52
40static inline int in_own_cluster(u32 addr) 53static inline int in_own_cluster(u32 addr)
41{ 54{
42 return !((addr ^ tipc_own_addr) >> 12); 55 return !((addr ^ tipc_own_addr) >> 12);
@@ -49,14 +62,13 @@ static inline int in_own_cluster(u32 addr)
49 * after a network hop. 62 * after a network hop.
50 */ 63 */
51 64
52static inline int addr_domain(int sc) 65static inline u32 addr_domain(u32 sc)
53{ 66{
54 if (likely(sc == TIPC_NODE_SCOPE)) 67 if (likely(sc == TIPC_NODE_SCOPE))
55 return tipc_own_addr; 68 return tipc_own_addr;
56 if (sc == TIPC_CLUSTER_SCOPE) 69 if (sc == TIPC_CLUSTER_SCOPE)
57 return tipc_addr(tipc_zone(tipc_own_addr), 70 return tipc_cluster_mask(tipc_own_addr);
58 tipc_cluster(tipc_own_addr), 0); 71 return tipc_zone_mask(tipc_own_addr);
59 return tipc_addr(tipc_zone(tipc_own_addr), 0, 0);
60} 72}
61 73
62int tipc_addr_domain_valid(u32); 74int tipc_addr_domain_valid(u32);
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 70ab5ef48766..fa68d1e9ff4b 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004-2006, Ericsson AB 4 * Copyright (c) 2004-2006, Ericsson AB
5 * Copyright (c) 2004, Intel Corporation. 5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) 2005, Wind River Systems 6 * Copyright (c) 2005, 2010-2011, Wind River Systems
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
@@ -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
@@ -61,8 +54,8 @@
61 */ 54 */
62 55
63struct bcbearer_pair { 56struct bcbearer_pair {
64 struct bearer *primary; 57 struct tipc_bearer *primary;
65 struct bearer *secondary; 58 struct tipc_bearer *secondary;
66}; 59};
67 60
68/** 61/**
@@ -81,7 +74,7 @@ struct bcbearer_pair {
81 */ 74 */
82 75
83struct bcbearer { 76struct bcbearer {
84 struct bearer bearer; 77 struct tipc_bearer bearer;
85 struct media media; 78 struct media media;
86 struct bcbearer_pair bpairs[MAX_BEARERS]; 79 struct bcbearer_pair bpairs[MAX_BEARERS];
87 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 80 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
@@ -93,6 +86,7 @@ struct bcbearer {
93 * struct bclink - link used for broadcast messages 86 * struct bclink - link used for broadcast messages
94 * @link: (non-standard) broadcast link structure 87 * @link: (non-standard) broadcast link structure
95 * @node: (non-standard) node structure representing b'cast link's peer node 88 * @node: (non-standard) node structure representing b'cast link's peer node
89 * @retransmit_to: node that most recently requested a retransmit
96 * 90 *
97 * Handles sequence numbering, fragmentation, bundling, etc. 91 * Handles sequence numbering, fragmentation, bundling, etc.
98 */ 92 */
@@ -100,6 +94,7 @@ struct bcbearer {
100struct bclink { 94struct bclink {
101 struct link link; 95 struct link link;
102 struct tipc_node node; 96 struct tipc_node node;
97 struct tipc_node *retransmit_to;
103}; 98};
104 99
105 100
@@ -184,6 +179,17 @@ static int bclink_ack_allowed(u32 n)
184 179
185 180
186/** 181/**
182 * tipc_bclink_retransmit_to - get most recent node to request retransmission
183 *
184 * Called with bc_lock locked
185 */
186
187struct tipc_node *tipc_bclink_retransmit_to(void)
188{
189 return bclink->retransmit_to;
190}
191
192/**
187 * bclink_retransmit_pkt - retransmit broadcast packets 193 * bclink_retransmit_pkt - retransmit broadcast packets
188 * @after: sequence number of last packet to *not* retransmit 194 * @after: sequence number of last packet to *not* retransmit
189 * @to: sequence number of last packet to retransmit 195 * @to: sequence number of last packet to retransmit
@@ -285,6 +291,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
285 msg = buf_msg(buf); 291 msg = buf_msg(buf);
286 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 292 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
287 INT_H_SIZE, n_ptr->addr); 293 INT_H_SIZE, n_ptr->addr);
294 msg_set_non_seq(msg, 1);
288 msg_set_mc_netid(msg, tipc_net_id); 295 msg_set_mc_netid(msg, tipc_net_id);
289 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 296 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
290 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 297 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -400,13 +407,9 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
400 spin_lock_bh(&bc_lock); 407 spin_lock_bh(&bc_lock);
401 408
402 res = tipc_link_send_buf(bcl, buf); 409 res = tipc_link_send_buf(bcl, buf);
403 if (unlikely(res == -ELINKCONG)) 410 if (likely(res > 0))
404 buf_discard(buf);
405 else
406 bclink_set_last_sent(); 411 bclink_set_last_sent();
407 412
408 if (bcl->out_queue_size > bcl->stats.max_queue_sz)
409 bcl->stats.max_queue_sz = bcl->out_queue_size;
410 bcl->stats.queue_sz_counts++; 413 bcl->stats.queue_sz_counts++;
411 bcl->stats.accu_queue_sz += bcl->out_queue_size; 414 bcl->stats.accu_queue_sz += bcl->out_queue_size;
412 415
@@ -422,9 +425,6 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
422 425
423void tipc_bclink_recv_pkt(struct sk_buff *buf) 426void tipc_bclink_recv_pkt(struct sk_buff *buf)
424{ 427{
425#if (TIPC_BCAST_LOSS_RATE)
426 static int rx_count;
427#endif
428 struct tipc_msg *msg = buf_msg(buf); 428 struct tipc_msg *msg = buf_msg(buf);
429 struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); 429 struct tipc_node *node = tipc_node_find(msg_prevnode(msg));
430 u32 next_in; 430 u32 next_in;
@@ -444,10 +444,9 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
444 tipc_node_unlock(node); 444 tipc_node_unlock(node);
445 spin_lock_bh(&bc_lock); 445 spin_lock_bh(&bc_lock);
446 bcl->stats.recv_nacks++; 446 bcl->stats.recv_nacks++;
447 bcl->owner->next = node; /* remember requestor */ 447 bclink->retransmit_to = node;
448 bclink_retransmit_pkt(msg_bcgap_after(msg), 448 bclink_retransmit_pkt(msg_bcgap_after(msg),
449 msg_bcgap_to(msg)); 449 msg_bcgap_to(msg));
450 bcl->owner->next = NULL;
451 spin_unlock_bh(&bc_lock); 450 spin_unlock_bh(&bc_lock);
452 } else { 451 } else {
453 tipc_bclink_peek_nack(msg_destnode(msg), 452 tipc_bclink_peek_nack(msg_destnode(msg),
@@ -459,14 +458,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
459 return; 458 return;
460 } 459 }
461 460
462#if (TIPC_BCAST_LOSS_RATE)
463 if (++rx_count == TIPC_BCAST_LOSS_RATE) {
464 rx_count = 0;
465 buf_discard(buf);
466 return;
467 }
468#endif
469
470 tipc_node_lock(node); 461 tipc_node_lock(node);
471receive: 462receive:
472 deferred = node->bclink.deferred_head; 463 deferred = node->bclink.deferred_head;
@@ -574,8 +565,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
574 bcbearer->remains = tipc_bcast_nmap; 565 bcbearer->remains = tipc_bcast_nmap;
575 566
576 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 567 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
577 struct bearer *p = bcbearer->bpairs[bp_index].primary; 568 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
578 struct bearer *s = bcbearer->bpairs[bp_index].secondary; 569 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary;
579 570
580 if (!p) 571 if (!p)
581 break; /* no more bearers to try */ 572 break; /* no more bearers to try */
@@ -584,11 +575,11 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
584 if (bcbearer->remains_new.count == bcbearer->remains.count) 575 if (bcbearer->remains_new.count == bcbearer->remains.count)
585 continue; /* bearer pair doesn't add anything */ 576 continue; /* bearer pair doesn't add anything */
586 577
587 if (p->publ.blocked || 578 if (p->blocked ||
588 p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { 579 p->media->send_msg(buf, p, &p->media->bcast_addr)) {
589 /* unable to send on primary bearer */ 580 /* unable to send on primary bearer */
590 if (!s || s->publ.blocked || 581 if (!s || s->blocked ||
591 s->media->send_msg(buf, &s->publ, 582 s->media->send_msg(buf, s,
592 &s->media->bcast_addr)) { 583 &s->media->bcast_addr)) {
593 /* unable to send on either bearer */ 584 /* unable to send on either bearer */
594 continue; 585 continue;
@@ -633,7 +624,7 @@ void tipc_bcbearer_sort(void)
633 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); 624 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
634 625
635 for (b_index = 0; b_index < MAX_BEARERS; b_index++) { 626 for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
636 struct bearer *b = &tipc_bearers[b_index]; 627 struct tipc_bearer *b = &tipc_bearers[b_index];
637 628
638 if (!b->active || !b->nodes.count) 629 if (!b->active || !b->nodes.count)
639 continue; 630 continue;
@@ -682,12 +673,12 @@ void tipc_bcbearer_sort(void)
682 673
683void tipc_bcbearer_push(void) 674void tipc_bcbearer_push(void)
684{ 675{
685 struct bearer *b_ptr; 676 struct tipc_bearer *b_ptr;
686 677
687 spin_lock_bh(&bc_lock); 678 spin_lock_bh(&bc_lock);
688 b_ptr = &bcbearer->bearer; 679 b_ptr = &bcbearer->bearer;
689 if (b_ptr->publ.blocked) { 680 if (b_ptr->blocked) {
690 b_ptr->publ.blocked = 0; 681 b_ptr->blocked = 0;
691 tipc_bearer_lock_push(b_ptr); 682 tipc_bearer_lock_push(b_ptr);
692 } 683 }
693 spin_unlock_bh(&bc_lock); 684 spin_unlock_bh(&bc_lock);
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 51f8c5326ce6..500c97f1c859 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -2,7 +2,7 @@
2 * net/tipc/bcast.h: Include file for TIPC broadcast code 2 * net/tipc/bcast.h: Include file for TIPC broadcast code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -90,6 +90,7 @@ void tipc_port_list_free(struct port_list *pl_ptr);
90 90
91int tipc_bclink_init(void); 91int tipc_bclink_init(void);
92void tipc_bclink_stop(void); 92void tipc_bclink_stop(void);
93struct tipc_node *tipc_bclink_retransmit_to(void);
93void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked); 94void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
94int tipc_bclink_send_msg(struct sk_buff *buf); 95int tipc_bclink_send_msg(struct sk_buff *buf);
95void tipc_bclink_recv_pkt(struct sk_buff *buf); 96void tipc_bclink_recv_pkt(struct sk_buff *buf);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 837b7a467885..85209eadfae6 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.c: TIPC bearer code 2 * net/tipc/bearer.c: TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2004-2006, Wind River Systems 5 * Copyright (c) 2004-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,9 @@
44static struct media media_list[MAX_MEDIA]; 44static struct media media_list[MAX_MEDIA];
45static u32 media_count; 45static u32 media_count;
46 46
47struct bearer tipc_bearers[MAX_BEARERS]; 47struct tipc_bearer tipc_bearers[MAX_BEARERS];
48
49static void bearer_disable(struct tipc_bearer *b_ptr);
48 50
49/** 51/**
50 * media_name_valid - validate media name 52 * media_name_valid - validate media name
@@ -158,7 +160,6 @@ int tipc_register_media(u32 media_type,
158 m_ptr->disable_bearer = disable; 160 m_ptr->disable_bearer = disable;
159 m_ptr->addr2str = addr2str; 161 m_ptr->addr2str = addr2str;
160 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); 162 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr));
161 m_ptr->bcast = 1;
162 strcpy(m_ptr->name, name); 163 strcpy(m_ptr->name, name);
163 m_ptr->priority = bearer_priority; 164 m_ptr->priority = bearer_priority;
164 m_ptr->tolerance = link_tolerance; 165 m_ptr->tolerance = link_tolerance;
@@ -278,13 +279,13 @@ static int bearer_name_validate(const char *name,
278 * bearer_find - locates bearer object with matching bearer name 279 * bearer_find - locates bearer object with matching bearer name
279 */ 280 */
280 281
281static struct bearer *bearer_find(const char *name) 282static struct tipc_bearer *bearer_find(const char *name)
282{ 283{
283 struct bearer *b_ptr; 284 struct tipc_bearer *b_ptr;
284 u32 i; 285 u32 i;
285 286
286 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 287 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
287 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) 288 if (b_ptr->active && (!strcmp(b_ptr->name, name)))
288 return b_ptr; 289 return b_ptr;
289 } 290 }
290 return NULL; 291 return NULL;
@@ -294,16 +295,16 @@ static struct bearer *bearer_find(const char *name)
294 * tipc_bearer_find_interface - locates bearer object with matching interface name 295 * tipc_bearer_find_interface - locates bearer object with matching interface name
295 */ 296 */
296 297
297struct bearer *tipc_bearer_find_interface(const char *if_name) 298struct tipc_bearer *tipc_bearer_find_interface(const char *if_name)
298{ 299{
299 struct bearer *b_ptr; 300 struct tipc_bearer *b_ptr;
300 char *b_if_name; 301 char *b_if_name;
301 u32 i; 302 u32 i;
302 303
303 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 304 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
304 if (!b_ptr->active) 305 if (!b_ptr->active)
305 continue; 306 continue;
306 b_if_name = strchr(b_ptr->publ.name, ':') + 1; 307 b_if_name = strchr(b_ptr->name, ':') + 1;
307 if (!strcmp(b_if_name, if_name)) 308 if (!strcmp(b_if_name, if_name))
308 return b_ptr; 309 return b_ptr;
309 } 310 }
@@ -318,7 +319,7 @@ struct sk_buff *tipc_bearer_get_names(void)
318{ 319{
319 struct sk_buff *buf; 320 struct sk_buff *buf;
320 struct media *m_ptr; 321 struct media *m_ptr;
321 struct bearer *b_ptr; 322 struct tipc_bearer *b_ptr;
322 int i, j; 323 int i, j;
323 324
324 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); 325 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
@@ -331,8 +332,8 @@ struct sk_buff *tipc_bearer_get_names(void)
331 b_ptr = &tipc_bearers[j]; 332 b_ptr = &tipc_bearers[j];
332 if (b_ptr->active && (b_ptr->media == m_ptr)) { 333 if (b_ptr->active && (b_ptr->media == m_ptr)) {
333 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 334 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME,
334 b_ptr->publ.name, 335 b_ptr->name,
335 strlen(b_ptr->publ.name) + 1); 336 strlen(b_ptr->name) + 1);
336 } 337 }
337 } 338 }
338 } 339 }
@@ -340,18 +341,18 @@ struct sk_buff *tipc_bearer_get_names(void)
340 return buf; 341 return buf;
341} 342}
342 343
343void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest) 344void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
344{ 345{
345 tipc_nmap_add(&b_ptr->nodes, dest); 346 tipc_nmap_add(&b_ptr->nodes, dest);
346 tipc_disc_update_link_req(b_ptr->link_req);
347 tipc_bcbearer_sort(); 347 tipc_bcbearer_sort();
348 tipc_disc_add_dest(b_ptr->link_req);
348} 349}
349 350
350void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest) 351void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
351{ 352{
352 tipc_nmap_remove(&b_ptr->nodes, dest); 353 tipc_nmap_remove(&b_ptr->nodes, dest);
353 tipc_disc_update_link_req(b_ptr->link_req);
354 tipc_bcbearer_sort(); 354 tipc_bcbearer_sort();
355 tipc_disc_remove_dest(b_ptr->link_req);
355} 356}
356 357
357/* 358/*
@@ -362,12 +363,12 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest)
362 * bearer.lock must be taken before calling 363 * bearer.lock must be taken before calling
363 * Returns binary true(1) ore false(0) 364 * Returns binary true(1) ore false(0)
364 */ 365 */
365static int bearer_push(struct bearer *b_ptr) 366static int bearer_push(struct tipc_bearer *b_ptr)
366{ 367{
367 u32 res = 0; 368 u32 res = 0;
368 struct link *ln, *tln; 369 struct link *ln, *tln;
369 370
370 if (b_ptr->publ.blocked) 371 if (b_ptr->blocked)
371 return 0; 372 return 0;
372 373
373 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) { 374 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {
@@ -382,13 +383,13 @@ static int bearer_push(struct bearer *b_ptr)
382 return list_empty(&b_ptr->cong_links); 383 return list_empty(&b_ptr->cong_links);
383} 384}
384 385
385void tipc_bearer_lock_push(struct bearer *b_ptr) 386void tipc_bearer_lock_push(struct tipc_bearer *b_ptr)
386{ 387{
387 int res; 388 int res;
388 389
389 spin_lock_bh(&b_ptr->publ.lock); 390 spin_lock_bh(&b_ptr->lock);
390 res = bearer_push(b_ptr); 391 res = bearer_push(b_ptr);
391 spin_unlock_bh(&b_ptr->publ.lock); 392 spin_unlock_bh(&b_ptr->lock);
392 if (res) 393 if (res)
393 tipc_bcbearer_push(); 394 tipc_bcbearer_push();
394} 395}
@@ -398,16 +399,14 @@ void tipc_bearer_lock_push(struct bearer *b_ptr)
398 * Interrupt enabling new requests after bearer congestion or blocking: 399 * Interrupt enabling new requests after bearer congestion or blocking:
399 * See bearer_send(). 400 * See bearer_send().
400 */ 401 */
401void tipc_continue(struct tipc_bearer *tb_ptr) 402void tipc_continue(struct tipc_bearer *b_ptr)
402{ 403{
403 struct bearer *b_ptr = (struct bearer *)tb_ptr; 404 spin_lock_bh(&b_ptr->lock);
404
405 spin_lock_bh(&b_ptr->publ.lock);
406 b_ptr->continue_count++; 405 b_ptr->continue_count++;
407 if (!list_empty(&b_ptr->cong_links)) 406 if (!list_empty(&b_ptr->cong_links))
408 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr); 407 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);
409 b_ptr->publ.blocked = 0; 408 b_ptr->blocked = 0;
410 spin_unlock_bh(&b_ptr->publ.lock); 409 spin_unlock_bh(&b_ptr->lock);
411} 410}
412 411
413/* 412/*
@@ -418,7 +417,7 @@ void tipc_continue(struct tipc_bearer *tb_ptr)
418 * bearer.lock is busy 417 * bearer.lock is busy
419 */ 418 */
420 419
421static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr) 420static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link *l_ptr)
422{ 421{
423 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); 422 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
424} 423}
@@ -431,11 +430,11 @@ static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_p
431 * bearer.lock is free 430 * bearer.lock is free
432 */ 431 */
433 432
434void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr) 433void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr)
435{ 434{
436 spin_lock_bh(&b_ptr->publ.lock); 435 spin_lock_bh(&b_ptr->lock);
437 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 436 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
438 spin_unlock_bh(&b_ptr->publ.lock); 437 spin_unlock_bh(&b_ptr->lock);
439} 438}
440 439
441 440
@@ -444,18 +443,18 @@ void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
444 * and if there is, try to resolve it before returning. 443 * and if there is, try to resolve it before returning.
445 * 'tipc_net_lock' is read_locked when this function is called 444 * 'tipc_net_lock' is read_locked when this function is called
446 */ 445 */
447int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr) 446int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr)
448{ 447{
449 int res = 1; 448 int res = 1;
450 449
451 if (list_empty(&b_ptr->cong_links)) 450 if (list_empty(&b_ptr->cong_links))
452 return 1; 451 return 1;
453 spin_lock_bh(&b_ptr->publ.lock); 452 spin_lock_bh(&b_ptr->lock);
454 if (!bearer_push(b_ptr)) { 453 if (!bearer_push(b_ptr)) {
455 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 454 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
456 res = 0; 455 res = 0;
457 } 456 }
458 spin_unlock_bh(&b_ptr->publ.lock); 457 spin_unlock_bh(&b_ptr->lock);
459 return res; 458 return res;
460} 459}
461 460
@@ -463,9 +462,9 @@ int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
463 * tipc_bearer_congested - determines if bearer is currently congested 462 * tipc_bearer_congested - determines if bearer is currently congested
464 */ 463 */
465 464
466int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr) 465int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr)
467{ 466{
468 if (unlikely(b_ptr->publ.blocked)) 467 if (unlikely(b_ptr->blocked))
469 return 1; 468 return 1;
470 if (likely(list_empty(&b_ptr->cong_links))) 469 if (likely(list_empty(&b_ptr->cong_links)))
471 return 0; 470 return 0;
@@ -476,9 +475,9 @@ int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
476 * tipc_enable_bearer - enable bearer with the given name 475 * tipc_enable_bearer - enable bearer with the given name
477 */ 476 */
478 477
479int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) 478int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
480{ 479{
481 struct bearer *b_ptr; 480 struct tipc_bearer *b_ptr;
482 struct media *m_ptr; 481 struct media *m_ptr;
483 struct bearer_name b_name; 482 struct bearer_name b_name;
484 char addr_string[16]; 483 char addr_string[16];
@@ -496,9 +495,16 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
496 warn("Bearer <%s> rejected, illegal name\n", name); 495 warn("Bearer <%s> rejected, illegal name\n", name);
497 return -EINVAL; 496 return -EINVAL;
498 } 497 }
499 if (!tipc_addr_domain_valid(bcast_scope) || 498 if (tipc_addr_domain_valid(disc_domain) &&
500 !tipc_in_scope(bcast_scope, tipc_own_addr)) { 499 (disc_domain != tipc_own_addr)) {
501 warn("Bearer <%s> rejected, illegal broadcast scope\n", name); 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) {
507 warn("Bearer <%s> rejected, illegal discovery domain\n", name);
502 return -EINVAL; 508 return -EINVAL;
503 } 509 }
504 if ((priority < TIPC_MIN_LINK_PRI || 510 if ((priority < TIPC_MIN_LINK_PRI ||
@@ -514,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
514 if (!m_ptr) { 520 if (!m_ptr) {
515 warn("Bearer <%s> rejected, media <%s> not registered\n", name, 521 warn("Bearer <%s> rejected, media <%s> not registered\n", name,
516 b_name.media_name); 522 b_name.media_name);
517 goto failed; 523 goto exit;
518 } 524 }
519 525
520 if (priority == TIPC_MEDIA_LINK_PRI) 526 if (priority == TIPC_MEDIA_LINK_PRI)
@@ -528,16 +534,16 @@ restart:
528 bearer_id = i; 534 bearer_id = i;
529 continue; 535 continue;
530 } 536 }
531 if (!strcmp(name, tipc_bearers[i].publ.name)) { 537 if (!strcmp(name, tipc_bearers[i].name)) {
532 warn("Bearer <%s> rejected, already enabled\n", name); 538 warn("Bearer <%s> rejected, already enabled\n", name);
533 goto failed; 539 goto exit;
534 } 540 }
535 if ((tipc_bearers[i].priority == priority) && 541 if ((tipc_bearers[i].priority == priority) &&
536 (++with_this_prio > 2)) { 542 (++with_this_prio > 2)) {
537 if (priority-- == 0) { 543 if (priority-- == 0) {
538 warn("Bearer <%s> rejected, duplicate priority\n", 544 warn("Bearer <%s> rejected, duplicate priority\n",
539 name); 545 name);
540 goto failed; 546 goto exit;
541 } 547 }
542 warn("Bearer <%s> priority adjustment required %u->%u\n", 548 warn("Bearer <%s> priority adjustment required %u->%u\n",
543 name, priority + 1, priority); 549 name, priority + 1, priority);
@@ -547,35 +553,36 @@ restart:
547 if (bearer_id >= MAX_BEARERS) { 553 if (bearer_id >= MAX_BEARERS) {
548 warn("Bearer <%s> rejected, bearer limit reached (%u)\n", 554 warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
549 name, MAX_BEARERS); 555 name, MAX_BEARERS);
550 goto failed; 556 goto exit;
551 } 557 }
552 558
553 b_ptr = &tipc_bearers[bearer_id]; 559 b_ptr = &tipc_bearers[bearer_id];
554 strcpy(b_ptr->publ.name, name); 560 strcpy(b_ptr->name, name);
555 res = m_ptr->enable_bearer(&b_ptr->publ); 561 res = m_ptr->enable_bearer(b_ptr);
556 if (res) { 562 if (res) {
557 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); 563 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
558 goto failed; 564 goto exit;
559 } 565 }
560 566
561 b_ptr->identity = bearer_id; 567 b_ptr->identity = bearer_id;
562 b_ptr->media = m_ptr; 568 b_ptr->media = m_ptr;
563 b_ptr->net_plane = bearer_id + 'A'; 569 b_ptr->net_plane = bearer_id + 'A';
564 b_ptr->active = 1; 570 b_ptr->active = 1;
565 b_ptr->detect_scope = bcast_scope;
566 b_ptr->priority = priority; 571 b_ptr->priority = priority;
567 INIT_LIST_HEAD(&b_ptr->cong_links); 572 INIT_LIST_HEAD(&b_ptr->cong_links);
568 INIT_LIST_HEAD(&b_ptr->links); 573 INIT_LIST_HEAD(&b_ptr->links);
569 if (m_ptr->bcast) { 574 spin_lock_init(&b_ptr->lock);
570 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 575
571 bcast_scope, 2); 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;
572 } 582 }
573 spin_lock_init(&b_ptr->publ.lock);
574 write_unlock_bh(&tipc_net_lock);
575 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 583 info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
576 name, tipc_addr_string_fill(addr_string, bcast_scope), priority); 584 name, tipc_addr_string_fill(addr_string, disc_domain), priority);
577 return 0; 585exit:
578failed:
579 write_unlock_bh(&tipc_net_lock); 586 write_unlock_bh(&tipc_net_lock);
580 return res; 587 return res;
581} 588}
@@ -587,7 +594,7 @@ failed:
587 594
588int tipc_block_bearer(const char *name) 595int tipc_block_bearer(const char *name)
589{ 596{
590 struct bearer *b_ptr = NULL; 597 struct tipc_bearer *b_ptr = NULL;
591 struct link *l_ptr; 598 struct link *l_ptr;
592 struct link *temp_l_ptr; 599 struct link *temp_l_ptr;
593 600
@@ -600,8 +607,8 @@ int tipc_block_bearer(const char *name)
600 } 607 }
601 608
602 info("Blocking bearer <%s>\n", name); 609 info("Blocking bearer <%s>\n", name);
603 spin_lock_bh(&b_ptr->publ.lock); 610 spin_lock_bh(&b_ptr->lock);
604 b_ptr->publ.blocked = 1; 611 b_ptr->blocked = 1;
605 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 612 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
606 struct tipc_node *n_ptr = l_ptr->owner; 613 struct tipc_node *n_ptr = l_ptr->owner;
607 614
@@ -609,7 +616,7 @@ int tipc_block_bearer(const char *name)
609 tipc_link_reset(l_ptr); 616 tipc_link_reset(l_ptr);
610 spin_unlock_bh(&n_ptr->lock); 617 spin_unlock_bh(&n_ptr->lock);
611 } 618 }
612 spin_unlock_bh(&b_ptr->publ.lock); 619 spin_unlock_bh(&b_ptr->lock);
613 read_unlock_bh(&tipc_net_lock); 620 read_unlock_bh(&tipc_net_lock);
614 return 0; 621 return 0;
615} 622}
@@ -620,27 +627,27 @@ int tipc_block_bearer(const char *name)
620 * Note: This routine assumes caller holds tipc_net_lock. 627 * Note: This routine assumes caller holds tipc_net_lock.
621 */ 628 */
622 629
623static void bearer_disable(struct bearer *b_ptr) 630static void bearer_disable(struct tipc_bearer *b_ptr)
624{ 631{
625 struct link *l_ptr; 632 struct link *l_ptr;
626 struct link *temp_l_ptr; 633 struct link *temp_l_ptr;
627 634
628 info("Disabling bearer <%s>\n", b_ptr->publ.name); 635 info("Disabling bearer <%s>\n", b_ptr->name);
629 tipc_disc_stop_link_req(b_ptr->link_req); 636 spin_lock_bh(&b_ptr->lock);
630 spin_lock_bh(&b_ptr->publ.lock); 637 b_ptr->blocked = 1;
631 b_ptr->link_req = NULL; 638 b_ptr->media->disable_bearer(b_ptr);
632 b_ptr->publ.blocked = 1;
633 b_ptr->media->disable_bearer(&b_ptr->publ);
634 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) {
635 tipc_link_delete(l_ptr); 640 tipc_link_delete(l_ptr);
636 } 641 }
637 spin_unlock_bh(&b_ptr->publ.lock); 642 if (b_ptr->link_req)
638 memset(b_ptr, 0, sizeof(struct bearer)); 643 tipc_disc_delete(b_ptr->link_req);
644 spin_unlock_bh(&b_ptr->lock);
645 memset(b_ptr, 0, sizeof(struct tipc_bearer));
639} 646}
640 647
641int tipc_disable_bearer(const char *name) 648int tipc_disable_bearer(const char *name)
642{ 649{
643 struct bearer *b_ptr; 650 struct tipc_bearer *b_ptr;
644 int res; 651 int res;
645 652
646 write_lock_bh(&tipc_net_lock); 653 write_lock_bh(&tipc_net_lock);
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 85f451d5aacf..31d6172b20fd 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.h: Include file for TIPC bearer code 2 * net/tipc/bearer.h: Include file for TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -61,26 +61,7 @@ struct tipc_media_addr {
61 } dev_addr; 61 } dev_addr;
62}; 62};
63 63
64/** 64struct tipc_bearer;
65 * struct tipc_bearer - TIPC bearer info available to media code
66 * @usr_handle: pointer to additional media-specific information about bearer
67 * @mtu: max packet size bearer can support
68 * @blocked: non-zero if bearer is blocked
69 * @lock: spinlock for controlling access to bearer
70 * @addr: media-specific address associated with bearer
71 * @name: bearer name (format = media:interface)
72 *
73 * Note: TIPC initializes "name" and "lock" fields; media code is responsible
74 * for initialization all other fields when a bearer is enabled.
75 */
76struct tipc_bearer {
77 void *usr_handle;
78 u32 mtu;
79 int blocked;
80 spinlock_t lock;
81 struct tipc_media_addr addr;
82 char name[TIPC_MAX_BEARER_NAME];
83};
84 65
85/** 66/**
86 * struct media - TIPC media information available to internal users 67 * struct media - TIPC media information available to internal users
@@ -89,7 +70,6 @@ struct tipc_bearer {
89 * @disable_bearer: routine which disables a bearer 70 * @disable_bearer: routine which disables a bearer
90 * @addr2str: routine which converts bearer's address to string form 71 * @addr2str: routine which converts bearer's address to string form
91 * @bcast_addr: media address used in broadcasting 72 * @bcast_addr: media address used in broadcasting
92 * @bcast: non-zero if media supports broadcasting [currently mandatory]
93 * @priority: default link (and bearer) priority 73 * @priority: default link (and bearer) priority
94 * @tolerance: default time (in ms) before declaring link failure 74 * @tolerance: default time (in ms) before declaring link failure
95 * @window: default window (in packets) before declaring link congestion 75 * @window: default window (in packets) before declaring link congestion
@@ -106,7 +86,6 @@ struct media {
106 char *(*addr2str)(struct tipc_media_addr *a, 86 char *(*addr2str)(struct tipc_media_addr *a,
107 char *str_buf, int str_size); 87 char *str_buf, int str_size);
108 struct tipc_media_addr bcast_addr; 88 struct tipc_media_addr bcast_addr;
109 int bcast;
110 u32 priority; 89 u32 priority;
111 u32 tolerance; 90 u32 tolerance;
112 u32 window; 91 u32 window;
@@ -115,11 +94,15 @@ struct media {
115}; 94};
116 95
117/** 96/**
118 * struct bearer - TIPC bearer information available to internal users 97 * struct tipc_bearer - TIPC bearer structure
119 * @publ: bearer information available to privileged users 98 * @usr_handle: pointer to additional media-specific information about bearer
99 * @mtu: max packet size bearer can support
100 * @blocked: non-zero if bearer is blocked
101 * @lock: spinlock for controlling access to bearer
102 * @addr: media-specific address associated with bearer
103 * @name: bearer name (format = media:interface)
120 * @media: ptr to media structure associated with bearer 104 * @media: ptr to media structure associated with bearer
121 * @priority: default link priority for bearer 105 * @priority: default link priority for bearer
122 * @detect_scope: network address mask used during automatic link creation
123 * @identity: array index of this bearer within TIPC bearer array 106 * @identity: array index of this bearer within TIPC bearer array
124 * @link_req: ptr to (optional) structure making periodic link setup requests 107 * @link_req: ptr to (optional) structure making periodic link setup requests
125 * @links: list of non-congested links associated with bearer 108 * @links: list of non-congested links associated with bearer
@@ -128,13 +111,20 @@ struct media {
128 * @active: non-zero if bearer structure is represents a bearer 111 * @active: non-zero if bearer structure is represents a bearer
129 * @net_plane: network plane ('A' through 'H') currently associated with bearer 112 * @net_plane: network plane ('A' through 'H') currently associated with bearer
130 * @nodes: indicates which nodes in cluster can be reached through bearer 113 * @nodes: indicates which nodes in cluster can be reached through bearer
114 *
115 * Note: media-specific code is responsible for initialization of the fields
116 * indicated below when a bearer is enabled; TIPC's generic bearer code takes
117 * care of initializing all other fields.
131 */ 118 */
132 119struct tipc_bearer {
133struct bearer { 120 void *usr_handle; /* initalized by media */
134 struct tipc_bearer publ; 121 u32 mtu; /* initalized by media */
122 int blocked; /* initalized by media */
123 struct tipc_media_addr addr; /* initalized by media */
124 char name[TIPC_MAX_BEARER_NAME];
125 spinlock_t lock;
135 struct media *media; 126 struct media *media;
136 u32 priority; 127 u32 priority;
137 u32 detect_scope;
138 u32 identity; 128 u32 identity;
139 struct link_req *link_req; 129 struct link_req *link_req;
140 struct list_head links; 130 struct list_head links;
@@ -152,7 +142,7 @@ struct bearer_name {
152 142
153struct link; 143struct link;
154 144
155extern struct bearer tipc_bearers[]; 145extern struct tipc_bearer tipc_bearers[];
156 146
157/* 147/*
158 * TIPC routines available to supported media types 148 * TIPC routines available to supported media types
@@ -173,7 +163,7 @@ void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
173int tipc_block_bearer(const char *name); 163int tipc_block_bearer(const char *name);
174void tipc_continue(struct tipc_bearer *tb_ptr); 164void tipc_continue(struct tipc_bearer *tb_ptr);
175 165
176int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority); 166int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
177int tipc_disable_bearer(const char *name); 167int tipc_disable_bearer(const char *name);
178 168
179/* 169/*
@@ -186,14 +176,14 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a);
186struct sk_buff *tipc_media_get_names(void); 176struct sk_buff *tipc_media_get_names(void);
187 177
188struct sk_buff *tipc_bearer_get_names(void); 178struct sk_buff *tipc_bearer_get_names(void);
189void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest); 179void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest);
190void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest); 180void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest);
191void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr); 181void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr);
192struct bearer *tipc_bearer_find_interface(const char *if_name); 182struct tipc_bearer *tipc_bearer_find_interface(const char *if_name);
193int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr); 183int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr);
194int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr); 184int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr);
195void tipc_bearer_stop(void); 185void tipc_bearer_stop(void);
196void tipc_bearer_lock_push(struct bearer *b_ptr); 186void tipc_bearer_lock_push(struct tipc_bearer *b_ptr);
197 187
198 188
199/** 189/**
@@ -214,10 +204,11 @@ void tipc_bearer_lock_push(struct bearer *b_ptr);
214 * and let TIPC's link code deal with the undelivered message. 204 * and let TIPC's link code deal with the undelivered message.
215 */ 205 */
216 206
217static inline int tipc_bearer_send(struct bearer *b_ptr, struct sk_buff *buf, 207static inline int tipc_bearer_send(struct tipc_bearer *b_ptr,
208 struct sk_buff *buf,
218 struct tipc_media_addr *dest) 209 struct tipc_media_addr *dest)
219{ 210{
220 return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest); 211 return !b_ptr->media->send_msg(buf, b_ptr, dest);
221} 212}
222 213
223#endif /* _TIPC_BEARER_H */ 214#endif /* _TIPC_BEARER_H */
diff --git a/net/tipc/config.c b/net/tipc/config.c
index e16750dcf3c1..b25a396b7e1e 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -2,7 +2,7 @@
2 * net/tipc/config.c: TIPC configuration management code 2 * net/tipc/config.c: TIPC configuration management code
3 * 3 *
4 * Copyright (c) 2002-2006, Ericsson AB 4 * Copyright (c) 2002-2006, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -148,7 +148,7 @@ static struct sk_buff *cfg_enable_bearer(void)
148 148
149 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); 149 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
150 if (tipc_enable_bearer(args->name, 150 if (tipc_enable_bearer(args->name,
151 ntohl(args->detect_scope), 151 ntohl(args->disc_domain),
152 ntohl(args->priority))) 152 ntohl(args->priority)))
153 return tipc_cfg_reply_error_string("unable to enable bearer"); 153 return tipc_cfg_reply_error_string("unable to enable bearer");
154 154
@@ -260,25 +260,6 @@ static struct sk_buff *cfg_set_max_ports(void)
260 return tipc_cfg_reply_none(); 260 return tipc_cfg_reply_none();
261} 261}
262 262
263static struct sk_buff *cfg_set_max_nodes(void)
264{
265 u32 value;
266
267 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
268 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
269 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
270 if (value == tipc_max_nodes)
271 return tipc_cfg_reply_none();
272 if (value != delimit(value, 8, 2047))
273 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
274 " (max nodes must be 8-2047)");
275 if (tipc_mode == TIPC_NET_MODE)
276 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
277 " (cannot change max nodes once TIPC has joined a network)");
278 tipc_max_nodes = value;
279 return tipc_cfg_reply_none();
280}
281
282static struct sk_buff *cfg_set_netid(void) 263static struct sk_buff *cfg_set_netid(void)
283{ 264{
284 u32 value; 265 u32 value;
@@ -397,9 +378,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
397 case TIPC_CMD_SET_MAX_SUBSCR: 378 case TIPC_CMD_SET_MAX_SUBSCR:
398 rep_tlv_buf = cfg_set_max_subscriptions(); 379 rep_tlv_buf = cfg_set_max_subscriptions();
399 break; 380 break;
400 case TIPC_CMD_SET_MAX_NODES:
401 rep_tlv_buf = cfg_set_max_nodes();
402 break;
403 case TIPC_CMD_SET_NETID: 381 case TIPC_CMD_SET_NETID:
404 rep_tlv_buf = cfg_set_netid(); 382 rep_tlv_buf = cfg_set_netid();
405 break; 383 break;
@@ -415,9 +393,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
415 case TIPC_CMD_GET_MAX_SUBSCR: 393 case TIPC_CMD_GET_MAX_SUBSCR:
416 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); 394 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
417 break; 395 break;
418 case TIPC_CMD_GET_MAX_NODES:
419 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
420 break;
421 case TIPC_CMD_GET_NETID: 396 case TIPC_CMD_GET_NETID:
422 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 397 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
423 break; 398 break;
@@ -431,6 +406,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
431 case TIPC_CMD_GET_MAX_SLAVES: 406 case TIPC_CMD_GET_MAX_SLAVES:
432 case TIPC_CMD_SET_MAX_CLUSTERS: 407 case TIPC_CMD_SET_MAX_CLUSTERS:
433 case TIPC_CMD_GET_MAX_CLUSTERS: 408 case TIPC_CMD_GET_MAX_CLUSTERS:
409 case TIPC_CMD_SET_MAX_NODES:
410 case TIPC_CMD_GET_MAX_NODES:
434 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 411 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
435 " (obsolete command)"); 412 " (obsolete command)");
436 break; 413 break;
diff --git a/net/tipc/core.c b/net/tipc/core.c
index e071579e0850..943b6af84265 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -2,7 +2,7 @@
2 * net/tipc/core.c: TIPC module code 2 * net/tipc/core.c: TIPC module code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -41,10 +41,6 @@
41#include "config.h" 41#include "config.h"
42 42
43 43
44#ifndef CONFIG_TIPC_NODES
45#define CONFIG_TIPC_NODES 255
46#endif
47
48#ifndef CONFIG_TIPC_PORTS 44#ifndef CONFIG_TIPC_PORTS
49#define CONFIG_TIPC_PORTS 8191 45#define CONFIG_TIPC_PORTS 8191
50#endif 46#endif
@@ -57,7 +53,6 @@
57 53
58int tipc_mode = TIPC_NOT_RUNNING; 54int tipc_mode = TIPC_NOT_RUNNING;
59int tipc_random; 55int tipc_random;
60atomic_t tipc_user_count = ATOMIC_INIT(0);
61 56
62const char tipc_alphabet[] = 57const char tipc_alphabet[] =
63 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; 58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
@@ -65,7 +60,6 @@ const char tipc_alphabet[] =
65/* configurable TIPC parameters */ 60/* configurable TIPC parameters */
66 61
67u32 tipc_own_addr; 62u32 tipc_own_addr;
68int tipc_max_nodes;
69int tipc_max_ports; 63int tipc_max_ports;
70int tipc_max_subscriptions; 64int tipc_max_subscriptions;
71int tipc_max_publications; 65int tipc_max_publications;
@@ -185,15 +179,13 @@ static int __init tipc_init(void)
185 if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) 179 if (tipc_log_resize(CONFIG_TIPC_LOG) != 0)
186 warn("Unable to create log buffer\n"); 180 warn("Unable to create log buffer\n");
187 181
188 info("Activated (version " TIPC_MOD_VER 182 info("Activated (version " TIPC_MOD_VER ")\n");
189 " compiled " __DATE__ " " __TIME__ ")\n");
190 183
191 tipc_own_addr = 0; 184 tipc_own_addr = 0;
192 tipc_remote_management = 1; 185 tipc_remote_management = 1;
193 tipc_max_publications = 10000; 186 tipc_max_publications = 10000;
194 tipc_max_subscriptions = 2000; 187 tipc_max_subscriptions = 2000;
195 tipc_max_ports = CONFIG_TIPC_PORTS; 188 tipc_max_ports = CONFIG_TIPC_PORTS;
196 tipc_max_nodes = CONFIG_TIPC_NODES;
197 tipc_net_id = 4711; 189 tipc_net_id = 4711;
198 190
199 res = tipc_core_start(); 191 res = tipc_core_start();
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 997158546e25..436dda1159d2 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -2,7 +2,7 @@
2 * net/tipc/core.h: Include file for TIPC global declarations 2 * net/tipc/core.h: Include file for TIPC global declarations
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -147,7 +147,6 @@ void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
147 */ 147 */
148 148
149extern u32 tipc_own_addr; 149extern u32 tipc_own_addr;
150extern int tipc_max_nodes;
151extern int tipc_max_ports; 150extern int tipc_max_ports;
152extern int tipc_max_subscriptions; 151extern int tipc_max_subscriptions;
153extern int tipc_max_publications; 152extern int tipc_max_publications;
@@ -161,7 +160,6 @@ extern int tipc_remote_management;
161extern int tipc_mode; 160extern int tipc_mode;
162extern int tipc_random; 161extern int tipc_random;
163extern const char tipc_alphabet[]; 162extern const char tipc_alphabet[];
164extern atomic_t tipc_user_count;
165 163
166 164
167/* 165/*
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index fa026bd91a68..0987933155b9 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -2,7 +2,7 @@
2 * net/tipc/discover.c 2 * net/tipc/discover.c
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -39,26 +39,26 @@
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)
58 */ 56 */
59struct link_req { 57struct link_req {
60 struct 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;
@@ -67,27 +67,24 @@ struct link_req {
67/** 67/**
68 * tipc_disc_init_msg - initialize a link setup message 68 * tipc_disc_init_msg - initialize a link setup message
69 * @type: message type (request or response) 69 * @type: message type (request or response)
70 * @req_links: number of links associated with message
71 * @dest_domain: network domain of node(s) which should respond to message 70 * @dest_domain: network domain of node(s) which should respond to message
72 * @b_ptr: ptr to bearer issuing message 71 * @b_ptr: ptr to bearer issuing message
73 */ 72 */
74 73
75static struct sk_buff *tipc_disc_init_msg(u32 type, 74static struct sk_buff *tipc_disc_init_msg(u32 type,
76 u32 req_links,
77 u32 dest_domain, 75 u32 dest_domain,
78 struct bearer *b_ptr) 76 struct tipc_bearer *b_ptr)
79{ 77{
80 struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE); 78 struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
81 struct tipc_msg *msg; 79 struct tipc_msg *msg;
82 80
83 if (buf) { 81 if (buf) {
84 msg = buf_msg(buf); 82 msg = buf_msg(buf);
85 tipc_msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain); 83 tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
86 msg_set_non_seq(msg, 1); 84 msg_set_non_seq(msg, 1);
87 msg_set_req_links(msg, req_links);
88 msg_set_dest_domain(msg, dest_domain); 85 msg_set_dest_domain(msg, dest_domain);
89 msg_set_bc_netid(msg, tipc_net_id); 86 msg_set_bc_netid(msg, tipc_net_id);
90 msg_set_media_addr(msg, &b_ptr->publ.addr); 87 msg_set_media_addr(msg, &b_ptr->addr);
91 } 88 }
92 return buf; 89 return buf;
93} 90}
@@ -99,7 +96,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
99 * @media_addr: media address advertised by duplicated node 96 * @media_addr: media address advertised by duplicated node
100 */ 97 */
101 98
102static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr, 99static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr,
103 struct tipc_media_addr *media_addr) 100 struct tipc_media_addr *media_addr)
104{ 101{
105 char node_addr_str[16]; 102 char node_addr_str[16];
@@ -111,7 +108,7 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
111 tipc_media_addr_printf(&pb, media_addr); 108 tipc_media_addr_printf(&pb, media_addr);
112 tipc_printbuf_validate(&pb); 109 tipc_printbuf_validate(&pb);
113 warn("Duplicate %s using %s seen on <%s>\n", 110 warn("Duplicate %s using %s seen on <%s>\n",
114 node_addr_str, media_addr_str, b_ptr->publ.name); 111 node_addr_str, media_addr_str, b_ptr->name);
115} 112}
116 113
117/** 114/**
@@ -120,19 +117,23 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
120 * @b_ptr: bearer that message arrived on 117 * @b_ptr: bearer that message arrived on
121 */ 118 */
122 119
123void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) 120void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
124{ 121{
122 struct tipc_node *n_ptr;
125 struct link *link; 123 struct link *link;
126 struct tipc_media_addr media_addr; 124 struct tipc_media_addr media_addr, *addr;
125 struct sk_buff *rbuf;
127 struct tipc_msg *msg = buf_msg(buf); 126 struct tipc_msg *msg = buf_msg(buf);
128 u32 dest = msg_dest_domain(msg); 127 u32 dest = msg_dest_domain(msg);
129 u32 orig = msg_prevnode(msg); 128 u32 orig = msg_prevnode(msg);
130 u32 net_id = msg_bc_netid(msg); 129 u32 net_id = msg_bc_netid(msg);
131 u32 type = msg_type(msg); 130 u32 type = msg_type(msg);
131 int link_fully_up;
132 132
133 msg_get_media_addr(msg, &media_addr); 133 msg_get_media_addr(msg, &media_addr);
134 buf_discard(buf); 134 buf_discard(buf);
135 135
136 /* Validate discovery message from requesting node */
136 if (net_id != tipc_net_id) 137 if (net_id != tipc_net_id)
137 return; 138 return;
138 if (!tipc_addr_domain_valid(dest)) 139 if (!tipc_addr_domain_valid(dest))
@@ -140,104 +141,127 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
140 if (!tipc_addr_node_valid(orig)) 141 if (!tipc_addr_node_valid(orig))
141 return; 142 return;
142 if (orig == tipc_own_addr) { 143 if (orig == tipc_own_addr) {
143 if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr))) 144 if (memcmp(&media_addr, &b_ptr->addr, sizeof(media_addr)))
144 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr); 145 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
145 return; 146 return;
146 } 147 }
147 if (!tipc_in_scope(dest, tipc_own_addr)) 148 if (!tipc_in_scope(dest, tipc_own_addr))
148 return; 149 return;
149 if (in_own_cluster(orig)) { 150 if (!tipc_in_scope(b_ptr->link_req->domain, orig))
150 /* Always accept link here */ 151 return;
151 struct sk_buff *rbuf;
152 struct tipc_media_addr *addr;
153 struct tipc_node *n_ptr = tipc_node_find(orig);
154 int link_fully_up;
155
156 if (n_ptr == NULL) {
157 n_ptr = tipc_node_create(orig);
158 if (!n_ptr)
159 return;
160 }
161 spin_lock_bh(&n_ptr->lock);
162
163 /* Don't talk to neighbor during cleanup after last session */
164 152
165 if (n_ptr->cleanup_required) { 153 /* Locate structure corresponding to requesting node */
166 spin_unlock_bh(&n_ptr->lock); 154 n_ptr = tipc_node_find(orig);
155 if (!n_ptr) {
156 n_ptr = tipc_node_create(orig);
157 if (!n_ptr)
167 return; 158 return;
168 } 159 }
160 tipc_node_lock(n_ptr);
161
162 /* Don't talk to neighbor during cleanup after last session */
163 if (n_ptr->cleanup_required) {
164 tipc_node_unlock(n_ptr);
165 return;
166 }
167
168 link = n_ptr->links[b_ptr->identity];
169 169
170 link = n_ptr->links[b_ptr->identity]; 170 /* Create a link endpoint for this bearer, if necessary */
171 if (!link) {
172 link = tipc_link_create(n_ptr, b_ptr, &media_addr);
171 if (!link) { 173 if (!link) {
172 link = tipc_link_create(b_ptr, orig, &media_addr); 174 tipc_node_unlock(n_ptr);
173 if (!link) { 175 return;
174 spin_unlock_bh(&n_ptr->lock);
175 return;
176 }
177 }
178 addr = &link->media_addr;
179 if (memcmp(addr, &media_addr, sizeof(*addr))) {
180 if (tipc_link_is_up(link) || (!link->started)) {
181 disc_dupl_alert(b_ptr, orig, &media_addr);
182 spin_unlock_bh(&n_ptr->lock);
183 return;
184 }
185 warn("Resetting link <%s>, peer interface address changed\n",
186 link->name);
187 memcpy(addr, &media_addr, sizeof(*addr));
188 tipc_link_reset(link);
189 } 176 }
190 link_fully_up = link_working_working(link); 177 }
191 spin_unlock_bh(&n_ptr->lock); 178
192 if ((type == DSC_RESP_MSG) || link_fully_up) 179 /*
180 * Ensure requesting node's media address is correct
181 *
182 * If media address doesn't match and the link is working, reject the
183 * request (must be from a duplicate node).
184 *
185 * If media address doesn't match and the link is not working, accept
186 * the new media address and reset the link to ensure it starts up
187 * cleanly.
188 */
189 addr = &link->media_addr;
190 if (memcmp(addr, &media_addr, sizeof(*addr))) {
191 if (tipc_link_is_up(link) || (!link->started)) {
192 disc_dupl_alert(b_ptr, orig, &media_addr);
193 tipc_node_unlock(n_ptr);
193 return; 194 return;
194 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); 195 }
195 if (rbuf != NULL) { 196 warn("Resetting link <%s>, peer interface address changed\n",
196 b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); 197 link->name);
198 memcpy(addr, &media_addr, sizeof(*addr));
199 tipc_link_reset(link);
200 }
201
202 /* Accept discovery message & send response, if necessary */
203 link_fully_up = link_working_working(link);
204
205 if ((type == DSC_REQ_MSG) && !link_fully_up && !b_ptr->blocked) {
206 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, orig, b_ptr);
207 if (rbuf) {
208 b_ptr->media->send_msg(rbuf, b_ptr, &media_addr);
197 buf_discard(rbuf); 209 buf_discard(rbuf);
198 } 210 }
199 } 211 }
212
213 tipc_node_unlock(n_ptr);
200} 214}
201 215
202/** 216/**
203 * tipc_disc_stop_link_req - stop sending periodic link setup requests 217 * disc_update - update frequency of periodic link setup requests
204 * @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
205 */ 222 */
206 223
207void tipc_disc_stop_link_req(struct link_req *req) 224static void disc_update(struct link_req *req)
208{ 225{
209 if (!req) 226 if (!req->num_nodes) {
210 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}
211 234
212 k_cancel_timer(&req->timer); 235/**
213 k_term_timer(&req->timer); 236 * tipc_disc_add_dest - increment set of discovered nodes
214 buf_discard(req->buf); 237 * @req: ptr to link request structure
215 kfree(req); 238 */
239
240void tipc_disc_add_dest(struct link_req *req)
241{
242 req->num_nodes++;
216} 243}
217 244
218/** 245/**
219 * tipc_disc_update_link_req - update frequency of periodic link setup requests 246 * tipc_disc_remove_dest - decrement set of discovered nodes
220 * @req: ptr to link request structure 247 * @req: ptr to link request structure
221 */ 248 */
222 249
223void tipc_disc_update_link_req(struct link_req *req) 250void tipc_disc_remove_dest(struct link_req *req)
224{ 251{
225 if (!req) 252 req->num_nodes--;
226 return; 253 disc_update(req);
254}
227 255
228 if (req->timer_intv == TIPC_LINK_REQ_SLOW) { 256/**
229 if (!req->bearer->nodes.count) { 257 * disc_send_msg - send link setup request message
230 req->timer_intv = TIPC_LINK_REQ_FAST; 258 * @req: ptr to link request structure
231 k_start_timer(&req->timer, req->timer_intv); 259 */
232 } 260
233 } else if (req->timer_intv == TIPC_LINK_REQ_FAST) { 261static void disc_send_msg(struct link_req *req)
234 if (req->bearer->nodes.count) { 262{
235 req->timer_intv = TIPC_LINK_REQ_SLOW; 263 if (!req->bearer->blocked)
236 k_start_timer(&req->timer, req->timer_intv); 264 tipc_bearer_send(req->bearer, req->buf, &req->dest);
237 }
238 } else {
239 /* leave timer "as is" if haven't yet reached a "normal" rate */
240 }
241} 265}
242 266
243/** 267/**
@@ -249,58 +273,86 @@ void tipc_disc_update_link_req(struct link_req *req)
249 273
250static void disc_timeout(struct link_req *req) 274static void disc_timeout(struct link_req *req)
251{ 275{
252 spin_lock_bh(&req->bearer->publ.lock); 276 int max_delay;
253 277
254 req->bearer->media->send_msg(req->buf, &req->bearer->publ, &req->dest); 278 spin_lock_bh(&req->bearer->lock);
255 279
256 if ((req->timer_intv == TIPC_LINK_REQ_SLOW) || 280 /* Stop searching if only desired node has been found */
257 (req->timer_intv == TIPC_LINK_REQ_FAST)) { 281
258 /* leave timer interval "as is" if already at a "normal" rate */ 282 if (tipc_node(req->domain) && req->num_nodes) {
259 } else { 283 req->timer_intv = TIPC_LINK_REQ_INACTIVE;
260 req->timer_intv *= 2; 284 goto exit;
261 if (req->timer_intv > TIPC_LINK_REQ_FAST)
262 req->timer_intv = TIPC_LINK_REQ_FAST;
263 if ((req->timer_intv == TIPC_LINK_REQ_FAST) &&
264 (req->bearer->nodes.count))
265 req->timer_intv = TIPC_LINK_REQ_SLOW;
266 } 285 }
267 k_start_timer(&req->timer, req->timer_intv);
268 286
269 spin_unlock_bh(&req->bearer->publ.lock); 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:
307 spin_unlock_bh(&req->bearer->lock);
270} 308}
271 309
272/** 310/**
273 * tipc_disc_init_link_req - start sending periodic link setup requests 311 * tipc_disc_create - create object to send periodic link setup requests
274 * @b_ptr: ptr to bearer issuing requests 312 * @b_ptr: ptr to bearer issuing requests
275 * @dest: destination address for request messages 313 * @dest: destination address for request messages
276 * @dest_domain: network domain of node(s) which should respond to message 314 * @dest_domain: network domain to which links can be established
277 * @req_links: max number of desired links
278 * 315 *
279 * Returns pointer to link request structure, or NULL if unable to create. 316 * Returns 0 if successful, otherwise -errno.
280 */ 317 */
281 318
282struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 319int tipc_disc_create(struct tipc_bearer *b_ptr,
283 const struct tipc_media_addr *dest, 320 struct tipc_media_addr *dest, u32 dest_domain)
284 u32 dest_domain,
285 u32 req_links)
286{ 321{
287 struct link_req *req; 322 struct link_req *req;
288 323
289 req = kmalloc(sizeof(*req), GFP_ATOMIC); 324 req = kmalloc(sizeof(*req), GFP_ATOMIC);
290 if (!req) 325 if (!req)
291 return NULL; 326 return -ENOMEM;
292 327
293 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr); 328 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
294 if (!req->buf) { 329 if (!req->buf) {
295 kfree(req); 330 kfree(req);
296 return NULL; 331 return -ENOMSG;
297 } 332 }
298 333
299 memcpy(&req->dest, dest, sizeof(*dest)); 334 memcpy(&req->dest, dest, sizeof(*dest));
300 req->bearer = b_ptr; 335 req->bearer = b_ptr;
336 req->domain = dest_domain;
337 req->num_nodes = 0;
301 req->timer_intv = TIPC_LINK_REQ_INIT; 338 req->timer_intv = TIPC_LINK_REQ_INIT;
302 k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); 339 k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
303 k_start_timer(&req->timer, req->timer_intv); 340 k_start_timer(&req->timer, req->timer_intv);
304 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);
305} 357}
306 358
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index d2c3cffb79fc..a3af595b86cb 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -2,7 +2,7 @@
2 * net/tipc/discover.h 2 * net/tipc/discover.h
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -39,13 +39,11 @@
39 39
40struct link_req; 40struct link_req;
41 41
42struct link_req *tipc_disc_init_link_req(struct 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);
45 u32 req_links); 45void tipc_disc_add_dest(struct link_req *req);
46void tipc_disc_update_link_req(struct link_req *req); 46void tipc_disc_remove_dest(struct link_req *req);
47void tipc_disc_stop_link_req(struct link_req *req); 47void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
48
49void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr);
50 48
51#endif 49#endif
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 18702f58d111..5ed4b4f7452d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2,7 +2,7 @@
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2007, Ericsson AB 4 * Copyright (c) 1996-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -90,9 +90,10 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr,
90static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); 90static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf);
91static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); 91static 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 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);
@@ -113,7 +114,7 @@ static void link_init_max_pkt(struct link *l_ptr)
113{ 114{
114 u32 max_pkt; 115 u32 max_pkt;
115 116
116 max_pkt = (l_ptr->b_ptr->publ.mtu & ~3); 117 max_pkt = (l_ptr->b_ptr->mtu & ~3);
117 if (max_pkt > MAX_MSG_SIZE) 118 if (max_pkt > MAX_MSG_SIZE)
118 max_pkt = MAX_MSG_SIZE; 119 max_pkt = MAX_MSG_SIZE;
119 120
@@ -246,9 +247,6 @@ static void link_timeout(struct link *l_ptr)
246 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; 247 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size;
247 l_ptr->stats.queue_sz_counts++; 248 l_ptr->stats.queue_sz_counts++;
248 249
249 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
250 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
251
252 if (l_ptr->first_out) { 250 if (l_ptr->first_out) {
253 struct tipc_msg *msg = buf_msg(l_ptr->first_out); 251 struct tipc_msg *msg = buf_msg(l_ptr->first_out);
254 u32 length = msg_size(msg); 252 u32 length = msg_size(msg);
@@ -296,19 +294,35 @@ static void link_set_timer(struct link *l_ptr, u32 time)
296 294
297/** 295/**
298 * tipc_link_create - create a new link 296 * tipc_link_create - create a new link
297 * @n_ptr: pointer to associated node
299 * @b_ptr: pointer to associated bearer 298 * @b_ptr: pointer to associated bearer
300 * @peer: network address of node at other end of link
301 * @media_addr: media address to use when sending messages over link 299 * @media_addr: media address to use when sending messages over link
302 * 300 *
303 * Returns pointer to link. 301 * Returns pointer to link.
304 */ 302 */
305 303
306struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 304struct link *tipc_link_create(struct tipc_node *n_ptr,
305 struct tipc_bearer *b_ptr,
307 const struct tipc_media_addr *media_addr) 306 const struct tipc_media_addr *media_addr)
308{ 307{
309 struct link *l_ptr; 308 struct link *l_ptr;
310 struct tipc_msg *msg; 309 struct tipc_msg *msg;
311 char *if_name; 310 char *if_name;
311 char addr_string[16];
312 u32 peer = n_ptr->addr;
313
314 if (n_ptr->link_cnt >= 2) {
315 tipc_addr_string_fill(addr_string, n_ptr->addr);
316 err("Attempt to establish third link to %s\n", addr_string);
317 return NULL;
318 }
319
320 if (n_ptr->links[b_ptr->identity]) {
321 tipc_addr_string_fill(addr_string, n_ptr->addr);
322 err("Attempt to establish second link on <%s> to %s\n",
323 b_ptr->name, addr_string);
324 return NULL;
325 }
312 326
313 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 327 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC);
314 if (!l_ptr) { 328 if (!l_ptr) {
@@ -317,7 +331,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
317 } 331 }
318 332
319 l_ptr->addr = peer; 333 l_ptr->addr = peer;
320 if_name = strchr(b_ptr->publ.name, ':') + 1; 334 if_name = strchr(b_ptr->name, ':') + 1;
321 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 335 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
322 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
323 tipc_node(tipc_own_addr), 337 tipc_node(tipc_own_addr),
@@ -325,6 +339,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
325 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
326 /* note: peer i/f is appended to link name by reset/activate */ 340 /* note: peer i/f is appended to link name by reset/activate */
327 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
342 l_ptr->owner = n_ptr;
328 l_ptr->checkpoint = 1; 343 l_ptr->checkpoint = 1;
329 l_ptr->b_ptr = b_ptr; 344 l_ptr->b_ptr = b_ptr;
330 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 345 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
@@ -348,11 +363,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
348 363
349 link_reset_statistics(l_ptr); 364 link_reset_statistics(l_ptr);
350 365
351 l_ptr->owner = tipc_node_attach_link(l_ptr); 366 tipc_node_attach_link(n_ptr, l_ptr);
352 if (!l_ptr->owner) {
353 kfree(l_ptr);
354 return NULL;
355 }
356 367
357 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 368 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
358 list_add_tail(&l_ptr->link_list, &b_ptr->links); 369 list_add_tail(&l_ptr->link_list, &b_ptr->links);
@@ -391,7 +402,9 @@ void tipc_link_delete(struct link *l_ptr)
391 402
392static void link_start(struct link *l_ptr) 403static void link_start(struct link *l_ptr)
393{ 404{
405 tipc_node_lock(l_ptr->owner);
394 link_state_event(l_ptr, STARTING_EVT); 406 link_state_event(l_ptr, STARTING_EVT);
407 tipc_node_unlock(l_ptr->owner);
395} 408}
396 409
397/** 410/**
@@ -406,7 +419,7 @@ static void link_start(struct link *l_ptr)
406 419
407static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) 420static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
408{ 421{
409 struct port *p_ptr; 422 struct tipc_port *p_ptr;
410 423
411 spin_lock_bh(&tipc_port_list_lock); 424 spin_lock_bh(&tipc_port_list_lock);
412 p_ptr = tipc_port_lock(origport); 425 p_ptr = tipc_port_lock(origport);
@@ -415,7 +428,7 @@ static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
415 goto exit; 428 goto exit;
416 if (!list_empty(&p_ptr->wait_list)) 429 if (!list_empty(&p_ptr->wait_list))
417 goto exit; 430 goto exit;
418 p_ptr->publ.congested = 1; 431 p_ptr->congested = 1;
419 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); 432 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt);
420 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); 433 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
421 l_ptr->stats.link_congs++; 434 l_ptr->stats.link_congs++;
@@ -428,8 +441,8 @@ exit:
428 441
429void tipc_link_wakeup_ports(struct link *l_ptr, int all) 442void tipc_link_wakeup_ports(struct link *l_ptr, int all)
430{ 443{
431 struct port *p_ptr; 444 struct tipc_port *p_ptr;
432 struct port *temp_p_ptr; 445 struct tipc_port *temp_p_ptr;
433 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; 446 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size;
434 447
435 if (all) 448 if (all)
@@ -445,11 +458,11 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all)
445 if (win <= 0) 458 if (win <= 0)
446 break; 459 break;
447 list_del_init(&p_ptr->wait_list); 460 list_del_init(&p_ptr->wait_list);
448 spin_lock_bh(p_ptr->publ.lock); 461 spin_lock_bh(p_ptr->lock);
449 p_ptr->publ.congested = 0; 462 p_ptr->congested = 0;
450 p_ptr->wakeup(&p_ptr->publ); 463 p_ptr->wakeup(p_ptr);
451 win -= p_ptr->waiting_pkts; 464 win -= p_ptr->waiting_pkts;
452 spin_unlock_bh(p_ptr->publ.lock); 465 spin_unlock_bh(p_ptr->lock);
453 } 466 }
454 467
455exit: 468exit:
@@ -549,7 +562,7 @@ void tipc_link_reset(struct link *l_ptr)
549 tipc_node_link_down(l_ptr->owner, l_ptr); 562 tipc_node_link_down(l_ptr->owner, l_ptr);
550 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); 563 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
551 564
552 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && 565 if (was_active_link && tipc_node_active_links(l_ptr->owner) &&
553 l_ptr->owner->permit_changeover) { 566 l_ptr->owner->permit_changeover) {
554 l_ptr->reset_checkpoint = checkpoint; 567 l_ptr->reset_checkpoint = checkpoint;
555 l_ptr->exp_msg_count = START_CHANGEOVER; 568 l_ptr->exp_msg_count = START_CHANGEOVER;
@@ -824,7 +837,29 @@ static void link_add_to_outqueue(struct link *l_ptr,
824 l_ptr->last_out = buf; 837 l_ptr->last_out = buf;
825 } else 838 } else
826 l_ptr->first_out = l_ptr->last_out = buf; 839 l_ptr->first_out = l_ptr->last_out = buf;
840
827 l_ptr->out_queue_size++; 841 l_ptr->out_queue_size++;
842 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
843 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
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 }
828} 863}
829 864
830/* 865/*
@@ -849,8 +884,9 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
849 884
850 if (unlikely(queue_size >= queue_limit)) { 885 if (unlikely(queue_size >= queue_limit)) {
851 if (imp <= TIPC_CRITICAL_IMPORTANCE) { 886 if (imp <= TIPC_CRITICAL_IMPORTANCE) {
852 return link_schedule_port(l_ptr, msg_origport(msg), 887 link_schedule_port(l_ptr, msg_origport(msg), size);
853 size); 888 buf_discard(buf);
889 return -ELINKCONG;
854 } 890 }
855 buf_discard(buf); 891 buf_discard(buf);
856 if (imp > CONN_MANAGER) { 892 if (imp > CONN_MANAGER) {
@@ -867,9 +903,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
867 903
868 /* Packet can be queued or sent: */ 904 /* Packet can be queued or sent: */
869 905
870 if (queue_size > l_ptr->stats.max_queue_sz)
871 l_ptr->stats.max_queue_sz = queue_size;
872
873 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && 906 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) &&
874 !link_congested(l_ptr))) { 907 !link_congested(l_ptr))) {
875 link_add_to_outqueue(l_ptr, buf, msg); 908 link_add_to_outqueue(l_ptr, buf, msg);
@@ -1027,12 +1060,13 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1027 * except for total message length. 1060 * except for total message length.
1028 * Returns user data length or errno. 1061 * Returns user data length or errno.
1029 */ 1062 */
1030int tipc_link_send_sections_fast(struct port *sender, 1063int tipc_link_send_sections_fast(struct tipc_port *sender,
1031 struct iovec const *msg_sect, 1064 struct iovec const *msg_sect,
1032 const u32 num_sect, 1065 const u32 num_sect,
1066 unsigned int total_len,
1033 u32 destaddr) 1067 u32 destaddr)
1034{ 1068{
1035 struct tipc_msg *hdr = &sender->publ.phdr; 1069 struct tipc_msg *hdr = &sender->phdr;
1036 struct link *l_ptr; 1070 struct link *l_ptr;
1037 struct sk_buff *buf; 1071 struct sk_buff *buf;
1038 struct tipc_node *node; 1072 struct tipc_node *node;
@@ -1045,8 +1079,8 @@ again:
1045 * (Must not hold any locks while building message.) 1079 * (Must not hold any locks while building message.)
1046 */ 1080 */
1047 1081
1048 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt, 1082 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
1049 !sender->user_port, &buf); 1083 sender->max_pkt, !sender->user_port, &buf);
1050 1084
1051 read_lock_bh(&tipc_net_lock); 1085 read_lock_bh(&tipc_net_lock);
1052 node = tipc_node_find(destaddr); 1086 node = tipc_node_find(destaddr);
@@ -1056,9 +1090,7 @@ again:
1056 if (likely(l_ptr)) { 1090 if (likely(l_ptr)) {
1057 if (likely(buf)) { 1091 if (likely(buf)) {
1058 res = link_send_buf_fast(l_ptr, buf, 1092 res = link_send_buf_fast(l_ptr, buf,
1059 &sender->publ.max_pkt); 1093 &sender->max_pkt);
1060 if (unlikely(res < 0))
1061 buf_discard(buf);
1062exit: 1094exit:
1063 tipc_node_unlock(node); 1095 tipc_node_unlock(node);
1064 read_unlock_bh(&tipc_net_lock); 1096 read_unlock_bh(&tipc_net_lock);
@@ -1075,7 +1107,7 @@ exit:
1075 if (link_congested(l_ptr) || 1107 if (link_congested(l_ptr) ||
1076 !list_empty(&l_ptr->b_ptr->cong_links)) { 1108 !list_empty(&l_ptr->b_ptr->cong_links)) {
1077 res = link_schedule_port(l_ptr, 1109 res = link_schedule_port(l_ptr,
1078 sender->publ.ref, res); 1110 sender->ref, res);
1079 goto exit; 1111 goto exit;
1080 } 1112 }
1081 1113
@@ -1084,16 +1116,17 @@ exit:
1084 * then re-try fast path or fragment the message 1116 * then re-try fast path or fragment the message
1085 */ 1117 */
1086 1118
1087 sender->publ.max_pkt = l_ptr->max_pkt; 1119 sender->max_pkt = l_ptr->max_pkt;
1088 tipc_node_unlock(node); 1120 tipc_node_unlock(node);
1089 read_unlock_bh(&tipc_net_lock); 1121 read_unlock_bh(&tipc_net_lock);
1090 1122
1091 1123
1092 if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt) 1124 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1093 goto again; 1125 goto again;
1094 1126
1095 return link_send_sections_long(sender, msg_sect, 1127 return link_send_sections_long(sender, msg_sect,
1096 num_sect, destaddr); 1128 num_sect, total_len,
1129 destaddr);
1097 } 1130 }
1098 tipc_node_unlock(node); 1131 tipc_node_unlock(node);
1099 } 1132 }
@@ -1105,7 +1138,7 @@ exit:
1105 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); 1138 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
1106 if (res >= 0) 1139 if (res >= 0)
1107 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1140 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
1108 TIPC_ERR_NO_NODE); 1141 total_len, TIPC_ERR_NO_NODE);
1109 return res; 1142 return res;
1110} 1143}
1111 1144
@@ -1123,15 +1156,16 @@ exit:
1123 * 1156 *
1124 * Returns user data length or errno. 1157 * Returns user data length or errno.
1125 */ 1158 */
1126static int link_send_sections_long(struct port *sender, 1159static int link_send_sections_long(struct tipc_port *sender,
1127 struct iovec const *msg_sect, 1160 struct iovec const *msg_sect,
1128 u32 num_sect, 1161 u32 num_sect,
1162 unsigned int total_len,
1129 u32 destaddr) 1163 u32 destaddr)
1130{ 1164{
1131 struct link *l_ptr; 1165 struct link *l_ptr;
1132 struct tipc_node *node; 1166 struct tipc_node *node;
1133 struct tipc_msg *hdr = &sender->publ.phdr; 1167 struct tipc_msg *hdr = &sender->phdr;
1134 u32 dsz = msg_data_sz(hdr); 1168 u32 dsz = total_len;
1135 u32 max_pkt, fragm_sz, rest; 1169 u32 max_pkt, fragm_sz, rest;
1136 struct tipc_msg fragm_hdr; 1170 struct tipc_msg fragm_hdr;
1137 struct sk_buff *buf, *buf_chain, *prev; 1171 struct sk_buff *buf, *buf_chain, *prev;
@@ -1142,7 +1176,7 @@ static int link_send_sections_long(struct port *sender,
1142 1176
1143again: 1177again:
1144 fragm_no = 1; 1178 fragm_no = 1;
1145 max_pkt = sender->publ.max_pkt - INT_H_SIZE; 1179 max_pkt = sender->max_pkt - INT_H_SIZE;
1146 /* leave room for tunnel header in case of link changeover */ 1180 /* leave room for tunnel header in case of link changeover */
1147 fragm_sz = max_pkt - INT_H_SIZE; 1181 fragm_sz = max_pkt - INT_H_SIZE;
1148 /* leave room for fragmentation header in each fragment */ 1182 /* leave room for fragmentation header in each fragment */
@@ -1157,7 +1191,6 @@ again:
1157 1191
1158 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 1192 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1159 INT_H_SIZE, msg_destnode(hdr)); 1193 INT_H_SIZE, msg_destnode(hdr));
1160 msg_set_link_selector(&fragm_hdr, sender->publ.ref);
1161 msg_set_size(&fragm_hdr, max_pkt); 1194 msg_set_size(&fragm_hdr, max_pkt);
1162 msg_set_fragm_no(&fragm_hdr, 1); 1195 msg_set_fragm_no(&fragm_hdr, 1);
1163 1196
@@ -1238,13 +1271,13 @@ error:
1238 node = tipc_node_find(destaddr); 1271 node = tipc_node_find(destaddr);
1239 if (likely(node)) { 1272 if (likely(node)) {
1240 tipc_node_lock(node); 1273 tipc_node_lock(node);
1241 l_ptr = node->active_links[sender->publ.ref & 1]; 1274 l_ptr = node->active_links[sender->ref & 1];
1242 if (!l_ptr) { 1275 if (!l_ptr) {
1243 tipc_node_unlock(node); 1276 tipc_node_unlock(node);
1244 goto reject; 1277 goto reject;
1245 } 1278 }
1246 if (l_ptr->max_pkt < max_pkt) { 1279 if (l_ptr->max_pkt < max_pkt) {
1247 sender->publ.max_pkt = l_ptr->max_pkt; 1280 sender->max_pkt = l_ptr->max_pkt;
1248 tipc_node_unlock(node); 1281 tipc_node_unlock(node);
1249 for (; buf_chain; buf_chain = buf) { 1282 for (; buf_chain; buf_chain = buf) {
1250 buf = buf_chain->next; 1283 buf = buf_chain->next;
@@ -1259,28 +1292,15 @@ reject:
1259 buf_discard(buf_chain); 1292 buf_discard(buf_chain);
1260 } 1293 }
1261 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1294 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
1262 TIPC_ERR_NO_NODE); 1295 total_len, TIPC_ERR_NO_NODE);
1263 } 1296 }
1264 1297
1265 /* Append whole chain to send queue: */ 1298 /* Append chain of fragments to send queue & send them */
1266 1299
1267 buf = buf_chain; 1300 l_ptr->long_msg_seq_no++;
1268 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);
1269 if (!l_ptr->next_out) 1302 l_ptr->stats.sent_fragments += fragm_no;
1270 l_ptr->next_out = buf_chain;
1271 l_ptr->stats.sent_fragmented++; 1303 l_ptr->stats.sent_fragmented++;
1272 while (buf) {
1273 struct sk_buff *next = buf->next;
1274 struct tipc_msg *msg = buf_msg(buf);
1275
1276 l_ptr->stats.sent_fragments++;
1277 msg_set_long_msgno(msg, l_ptr->long_msg_seq_no);
1278 link_add_to_outqueue(l_ptr, buf, msg);
1279 buf = next;
1280 }
1281
1282 /* Send it, if possible: */
1283
1284 tipc_link_push_queue(l_ptr); 1304 tipc_link_push_queue(l_ptr);
1285 tipc_node_unlock(node); 1305 tipc_node_unlock(node);
1286 return dsz; 1306 return dsz;
@@ -1441,7 +1461,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1441 info("Outstanding acks: %lu\n", 1461 info("Outstanding acks: %lu\n",
1442 (unsigned long) TIPC_SKB_CB(buf)->handle); 1462 (unsigned long) TIPC_SKB_CB(buf)->handle);
1443 1463
1444 n_ptr = l_ptr->owner->next; 1464 n_ptr = tipc_bclink_retransmit_to();
1445 tipc_node_lock(n_ptr); 1465 tipc_node_lock(n_ptr);
1446 1466
1447 tipc_addr_string_fill(addr_string, n_ptr->addr); 1467 tipc_addr_string_fill(addr_string, n_ptr->addr);
@@ -1595,11 +1615,10 @@ static int link_recv_buf_validate(struct sk_buff *buf)
1595 * structure (i.e. cannot be NULL), but bearer can be inactive. 1615 * structure (i.e. cannot be NULL), but bearer can be inactive.
1596 */ 1616 */
1597 1617
1598void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) 1618void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1599{ 1619{
1600 read_lock_bh(&tipc_net_lock); 1620 read_lock_bh(&tipc_net_lock);
1601 while (head) { 1621 while (head) {
1602 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1603 struct tipc_node *n_ptr; 1622 struct tipc_node *n_ptr;
1604 struct link *l_ptr; 1623 struct link *l_ptr;
1605 struct sk_buff *crs; 1624 struct sk_buff *crs;
@@ -1735,10 +1754,6 @@ deliver:
1735 tipc_node_unlock(n_ptr); 1754 tipc_node_unlock(n_ptr);
1736 tipc_link_recv_bundle(buf); 1755 tipc_link_recv_bundle(buf);
1737 continue; 1756 continue;
1738 case ROUTE_DISTRIBUTOR:
1739 tipc_node_unlock(n_ptr);
1740 buf_discard(buf);
1741 continue;
1742 case NAME_DISTRIBUTOR: 1757 case NAME_DISTRIBUTOR:
1743 tipc_node_unlock(n_ptr); 1758 tipc_node_unlock(n_ptr);
1744 tipc_named_recv(buf); 1759 tipc_named_recv(buf);
@@ -1765,6 +1780,10 @@ deliver:
1765 goto protocol_check; 1780 goto protocol_check;
1766 } 1781 }
1767 break; 1782 break;
1783 default:
1784 buf_discard(buf);
1785 buf = NULL;
1786 break;
1768 } 1787 }
1769 } 1788 }
1770 tipc_node_unlock(n_ptr); 1789 tipc_node_unlock(n_ptr);
@@ -1900,6 +1919,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
1900 struct sk_buff *buf = NULL; 1919 struct sk_buff *buf = NULL;
1901 struct tipc_msg *msg = l_ptr->pmsg; 1920 struct tipc_msg *msg = l_ptr->pmsg;
1902 u32 msg_size = sizeof(l_ptr->proto_msg); 1921 u32 msg_size = sizeof(l_ptr->proto_msg);
1922 int r_flag;
1903 1923
1904 if (link_blocked(l_ptr)) 1924 if (link_blocked(l_ptr))
1905 return; 1925 return;
@@ -1950,15 +1970,14 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
1950 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1)); 1970 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1));
1951 msg_set_seq_gap(msg, 0); 1971 msg_set_seq_gap(msg, 0);
1952 msg_set_next_sent(msg, 1); 1972 msg_set_next_sent(msg, 1);
1973 msg_set_probe(msg, 0);
1953 msg_set_link_tolerance(msg, l_ptr->tolerance); 1974 msg_set_link_tolerance(msg, l_ptr->tolerance);
1954 msg_set_linkprio(msg, l_ptr->priority); 1975 msg_set_linkprio(msg, l_ptr->priority);
1955 msg_set_max_pkt(msg, l_ptr->max_pkt_target); 1976 msg_set_max_pkt(msg, l_ptr->max_pkt_target);
1956 } 1977 }
1957 1978
1958 if (tipc_node_has_redundant_links(l_ptr->owner)) 1979 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
1959 msg_set_redundant_link(msg); 1980 msg_set_redundant_link(msg, r_flag);
1960 else
1961 msg_clear_redundant_link(msg);
1962 msg_set_linkprio(msg, l_ptr->priority); 1981 msg_set_linkprio(msg, l_ptr->priority);
1963 1982
1964 /* Ensure sequence number will not fit : */ 1983 /* Ensure sequence number will not fit : */
@@ -1978,7 +1997,6 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
1978 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 1997 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
1979 return; 1998 return;
1980 } 1999 }
1981 msg_set_timestamp(msg, jiffies_to_msecs(jiffies));
1982 2000
1983 /* Message can be sent */ 2001 /* Message can be sent */
1984 2002
@@ -2066,7 +2084,7 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2066 l_ptr->peer_bearer_id = msg_bearer_id(msg); 2084 l_ptr->peer_bearer_id = msg_bearer_id(msg);
2067 2085
2068 /* Synchronize broadcast sequence numbers */ 2086 /* Synchronize broadcast sequence numbers */
2069 if (!tipc_node_has_redundant_links(l_ptr->owner)) 2087 if (!tipc_node_redundant_links(l_ptr->owner))
2070 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); 2088 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
2071 break; 2089 break;
2072 case STATE_MSG: 2090 case STATE_MSG:
@@ -2397,6 +2415,8 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2397 */ 2415 */
2398static 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)
2399{ 2417{
2418 struct sk_buff *buf_chain = NULL;
2419 struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain;
2400 struct tipc_msg *inmsg = buf_msg(buf); 2420 struct tipc_msg *inmsg = buf_msg(buf);
2401 struct tipc_msg fragm_hdr; 2421 struct tipc_msg fragm_hdr;
2402 u32 insize = msg_size(inmsg); 2422 u32 insize = msg_size(inmsg);
@@ -2405,7 +2425,7 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2405 u32 rest = insize; 2425 u32 rest = insize;
2406 u32 pack_sz = l_ptr->max_pkt; 2426 u32 pack_sz = l_ptr->max_pkt;
2407 u32 fragm_sz = pack_sz - INT_H_SIZE; 2427 u32 fragm_sz = pack_sz - INT_H_SIZE;
2408 u32 fragm_no = 1; 2428 u32 fragm_no = 0;
2409 u32 destaddr; 2429 u32 destaddr;
2410 2430
2411 if (msg_short(inmsg)) 2431 if (msg_short(inmsg))
@@ -2413,17 +2433,10 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2413 else 2433 else
2414 destaddr = msg_destnode(inmsg); 2434 destaddr = msg_destnode(inmsg);
2415 2435
2416 if (msg_routed(inmsg))
2417 msg_set_prevnode(inmsg, tipc_own_addr);
2418
2419 /* Prepare reusable fragment header: */ 2436 /* Prepare reusable fragment header: */
2420 2437
2421 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2438 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
2422 INT_H_SIZE, destaddr); 2439 INT_H_SIZE, destaddr);
2423 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg));
2424 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++));
2425 msg_set_fragm_no(&fragm_hdr, fragm_no);
2426 l_ptr->stats.sent_fragmented++;
2427 2440
2428 /* Chop up message: */ 2441 /* Chop up message: */
2429 2442
@@ -2436,27 +2449,37 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2436 } 2449 }
2437 fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); 2450 fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE);
2438 if (fragm == NULL) { 2451 if (fragm == NULL) {
2439 warn("Link unable to fragment message\n"); 2452 buf_discard(buf);
2440 dsz = -ENOMEM; 2453 while (buf_chain) {
2441 goto exit; 2454 buf = buf_chain;
2455 buf_chain = buf_chain->next;
2456 buf_discard(buf);
2457 }
2458 return -ENOMEM;
2442 } 2459 }
2443 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);
2444 skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); 2463 skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE);
2445 skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, 2464 skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs,
2446 fragm_sz); 2465 fragm_sz);
2447 /* Send queued messages first, if any: */ 2466 buf_chain_tail->next = fragm;
2467 buf_chain_tail = fragm;
2448 2468
2449 l_ptr->stats.sent_fragments++;
2450 tipc_link_send_buf(l_ptr, fragm);
2451 if (!tipc_link_is_up(l_ptr))
2452 return dsz;
2453 msg_set_fragm_no(&fragm_hdr, ++fragm_no);
2454 rest -= fragm_sz; 2469 rest -= fragm_sz;
2455 crs += fragm_sz; 2470 crs += fragm_sz;
2456 msg_set_type(&fragm_hdr, FRAGMENT); 2471 msg_set_type(&fragm_hdr, FRAGMENT);
2457 } 2472 }
2458exit:
2459 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
2460 return dsz; 2483 return dsz;
2461} 2484}
2462 2485
@@ -2464,7 +2487,7 @@ exit:
2464 * A pending message being re-assembled must store certain values 2487 * A pending message being re-assembled must store certain values
2465 * to handle subsequent fragments correctly. The following functions 2488 * to handle subsequent fragments correctly. The following functions
2466 * help storing these values in unused, available fields in the 2489 * help storing these values in unused, available fields in the
2467 * pending message. This makes dynamic memory allocation unecessary. 2490 * pending message. This makes dynamic memory allocation unnecessary.
2468 */ 2491 */
2469 2492
2470static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) 2493static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
@@ -2618,6 +2641,9 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2618 2641
2619static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) 2642static void link_set_supervision_props(struct link *l_ptr, u32 tolerance)
2620{ 2643{
2644 if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL))
2645 return;
2646
2621 l_ptr->tolerance = tolerance; 2647 l_ptr->tolerance = tolerance;
2622 l_ptr->continuity_interval = 2648 l_ptr->continuity_interval =
2623 ((tolerance / 4) > 500) ? 500 : tolerance / 4; 2649 ((tolerance / 4) > 500) ? 500 : tolerance / 4;
@@ -2658,7 +2684,7 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2658static struct link *link_find_link(const char *name, struct tipc_node **node) 2684static struct link *link_find_link(const char *name, struct tipc_node **node)
2659{ 2685{
2660 struct link_name link_name_parts; 2686 struct link_name link_name_parts;
2661 struct bearer *b_ptr; 2687 struct tipc_bearer *b_ptr;
2662 struct link *l_ptr; 2688 struct link *l_ptr;
2663 2689
2664 if (!link_name_validate(name, &link_name_parts)) 2690 if (!link_name_validate(name, &link_name_parts))
@@ -2961,7 +2987,7 @@ static void link_print(struct link *l_ptr, const char *str)
2961 2987
2962 tipc_printf(buf, str); 2988 tipc_printf(buf, str);
2963 tipc_printf(buf, "Link %x<%s>:", 2989 tipc_printf(buf, "Link %x<%s>:",
2964 l_ptr->addr, l_ptr->b_ptr->publ.name); 2990 l_ptr->addr, l_ptr->b_ptr->name);
2965 2991
2966#ifdef CONFIG_TIPC_DEBUG 2992#ifdef CONFIG_TIPC_DEBUG
2967 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) 2993 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
@@ -2981,9 +3007,9 @@ static void link_print(struct link *l_ptr, const char *str)
2981 != (l_ptr->out_queue_size - 1)) || 3007 != (l_ptr->out_queue_size - 1)) ||
2982 (l_ptr->last_out->next != NULL)) { 3008 (l_ptr->last_out->next != NULL)) {
2983 tipc_printf(buf, "\nSend queue inconsistency\n"); 3009 tipc_printf(buf, "\nSend queue inconsistency\n");
2984 tipc_printf(buf, "first_out= %x ", l_ptr->first_out); 3010 tipc_printf(buf, "first_out= %p ", l_ptr->first_out);
2985 tipc_printf(buf, "next_out= %x ", l_ptr->next_out); 3011 tipc_printf(buf, "next_out= %p ", l_ptr->next_out);
2986 tipc_printf(buf, "last_out= %x ", l_ptr->last_out); 3012 tipc_printf(buf, "last_out= %p ", l_ptr->last_out);
2987 } 3013 }
2988 } else 3014 } else
2989 tipc_printf(buf, "[]"); 3015 tipc_printf(buf, "[]");
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 70967e637027..74fbecab1ea0 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -2,7 +2,7 @@
2 * net/tipc/link.h: Include file for TIPC link code 2 * net/tipc/link.h: Include file for TIPC link code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -122,7 +122,7 @@ struct link {
122 u32 checkpoint; 122 u32 checkpoint;
123 u32 peer_session; 123 u32 peer_session;
124 u32 peer_bearer_id; 124 u32 peer_bearer_id;
125 struct bearer *b_ptr; 125 struct tipc_bearer *b_ptr;
126 u32 tolerance; 126 u32 tolerance;
127 u32 continuity_interval; 127 u32 continuity_interval;
128 u32 abort_limit; 128 u32 abort_limit;
@@ -196,24 +196,19 @@ struct link {
196 u32 bearer_congs; 196 u32 bearer_congs;
197 u32 deferred_recv; 197 u32 deferred_recv;
198 u32 duplicates; 198 u32 duplicates;
199 199 u32 max_queue_sz; /* send queue size high water mark */
200 /* for statistical profiling of send queue size */ 200 u32 accu_queue_sz; /* used for send queue size profiling */
201 201 u32 queue_sz_counts; /* used for send queue size profiling */
202 u32 max_queue_sz; 202 u32 msg_length_counts; /* used for message length profiling */
203 u32 accu_queue_sz; 203 u32 msg_lengths_total; /* used for message length profiling */
204 u32 queue_sz_counts; 204 u32 msg_length_profile[7]; /* used for msg. length profiling */
205
206 /* for statistical profiling of message lengths */
207
208 u32 msg_length_counts;
209 u32 msg_lengths_total;
210 u32 msg_length_profile[7];
211 } stats; 205 } stats;
212}; 206};
213 207
214struct port; 208struct tipc_port;
215 209
216struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 210struct link *tipc_link_create(struct tipc_node *n_ptr,
211 struct tipc_bearer *b_ptr,
217 const struct tipc_media_addr *media_addr); 212 const struct tipc_media_addr *media_addr);
218void tipc_link_delete(struct link *l_ptr); 213void tipc_link_delete(struct link *l_ptr);
219void tipc_link_changeover(struct link *l_ptr); 214void tipc_link_changeover(struct link *l_ptr);
@@ -230,9 +225,10 @@ void tipc_link_reset(struct link *l_ptr);
230int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector); 225int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
231int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf); 226int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf);
232u32 tipc_link_get_max_pkt(u32 dest, u32 selector); 227u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
233int tipc_link_send_sections_fast(struct port *sender, 228int tipc_link_send_sections_fast(struct tipc_port *sender,
234 struct iovec const *msg_sect, 229 struct iovec const *msg_sect,
235 const u32 num_sect, 230 const u32 num_sect,
231 unsigned int total_len,
236 u32 destnode); 232 u32 destnode);
237void tipc_link_recv_bundle(struct sk_buff *buf); 233void tipc_link_recv_bundle(struct sk_buff *buf);
238int 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 bb6180c4fcbb..03e57bf92c73 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -2,7 +2,7 @@
2 * net/tipc/msg.c: TIPC message header routines 2 * net/tipc/msg.c: TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -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);
@@ -192,8 +173,6 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
192 default: 173 default:
193 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg)); 174 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
194 } 175 }
195 if (msg_routed(msg) && !msg_non_seq(msg))
196 tipc_printf(buf, "ROUT:");
197 if (msg_reroute_cnt(msg)) 176 if (msg_reroute_cnt(msg))
198 tipc_printf(buf, "REROUTED(%u):", 177 tipc_printf(buf, "REROUTED(%u):",
199 msg_reroute_cnt(msg)); 178 msg_reroute_cnt(msg));
@@ -210,8 +189,6 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
210 default: 189 default:
211 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); 190 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
212 } 191 }
213 if (msg_routed(msg))
214 tipc_printf(buf, "ROUT:");
215 if (msg_reroute_cnt(msg)) 192 if (msg_reroute_cnt(msg))
216 tipc_printf(buf, "REROUTED(%u):", 193 tipc_printf(buf, "REROUTED(%u):",
217 msg_reroute_cnt(msg)); 194 msg_reroute_cnt(msg));
@@ -232,13 +209,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
232 default: 209 default:
233 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); 210 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
234 } 211 }
235 if (msg_routed(msg))
236 tipc_printf(buf, "ROUT:");
237 if (msg_reroute_cnt(msg)) 212 if (msg_reroute_cnt(msg))
238 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg)); 213 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
239 break; 214 break;
240 case LINK_PROTOCOL: 215 case LINK_PROTOCOL:
241 tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg));
242 switch (msg_type(msg)) { 216 switch (msg_type(msg)) {
243 case STATE_MSG: 217 case STATE_MSG:
244 tipc_printf(buf, "STATE:"); 218 tipc_printf(buf, "STATE:");
@@ -275,33 +249,6 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
275 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); 249 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
276 } 250 }
277 break; 251 break;
278 case ROUTE_DISTRIBUTOR:
279 tipc_printf(buf, "ROUTING_MNG:");
280 switch (msg_type(msg)) {
281 case EXT_ROUTING_TABLE:
282 tipc_printf(buf, "EXT_TBL:");
283 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
284 break;
285 case LOCAL_ROUTING_TABLE:
286 tipc_printf(buf, "LOCAL_TBL:");
287 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
288 break;
289 case SLAVE_ROUTING_TABLE:
290 tipc_printf(buf, "DP_TBL:");
291 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
292 break;
293 case ROUTE_ADDITION:
294 tipc_printf(buf, "ADD:");
295 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
296 break;
297 case ROUTE_REMOVAL:
298 tipc_printf(buf, "REMOVE:");
299 tipc_printf(buf, "TO:%x:", msg_remote_node(msg));
300 break;
301 default:
302 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
303 }
304 break;
305 case LINK_CONFIG: 252 case LINK_CONFIG:
306 tipc_printf(buf, "CFG:"); 253 tipc_printf(buf, "CFG:");
307 switch (msg_type(msg)) { 254 switch (msg_type(msg)) {
@@ -381,20 +328,15 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
381 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg)); 328 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg));
382 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg)); 329 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg));
383 } 330 }
384 if (msg_routed(msg) && !msg_non_seq(msg))
385 tipc_printf(buf, ":TSEQN(%u)", msg_transp_seqno(msg));
386 } 331 }
387 if (msg_user(msg) == NAME_DISTRIBUTOR) { 332 if (msg_user(msg) == NAME_DISTRIBUTOR) {
388 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); 333 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
389 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); 334 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
390 if (msg_routed(msg))
391 tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg));
392 } 335 }
393 336
394 if (msg_user(msg) == LINK_CONFIG) { 337 if (msg_user(msg) == LINK_CONFIG) {
395 u32 *raw = (u32 *)msg; 338 u32 *raw = (u32 *)msg;
396 struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5]; 339 struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5];
397 tipc_printf(buf, ":REQL(%u):", msg_req_links(msg));
398 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); 340 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
399 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); 341 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
400 tipc_media_addr_printf(buf, orig); 342 tipc_media_addr_printf(buf, orig);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 92c4c4fd7b3f..8452454731fa 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -2,7 +2,7 @@
2 * net/tipc/msg.h: Include file for TIPC message header routines 2 * net/tipc/msg.h: Include file for TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2007, Ericsson AB 4 * Copyright (c) 2000-2007, Ericsson AB
5 * Copyright (c) 2005-2008, Wind River Systems 5 * Copyright (c) 2005-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -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 */
@@ -421,13 +407,6 @@ static inline int msg_is_dest(struct tipc_msg *m, u32 d)
421 return msg_short(m) || (msg_destnode(m) == d); 407 return msg_short(m) || (msg_destnode(m) == d);
422} 408}
423 409
424static inline u32 msg_routed(struct tipc_msg *m)
425{
426 if (likely(msg_short(m)))
427 return 0;
428 return (msg_destnode(m) ^ msg_orignode(m)) >> 11;
429}
430
431static inline u32 msg_nametype(struct tipc_msg *m) 410static inline u32 msg_nametype(struct tipc_msg *m)
432{ 411{
433 return msg_word(m, 8); 412 return msg_word(m, 8);
@@ -438,26 +417,6 @@ static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
438 msg_set_word(m, 8, n); 417 msg_set_word(m, 8, n);
439} 418}
440 419
441static inline u32 msg_transp_seqno(struct tipc_msg *m)
442{
443 return msg_word(m, 8);
444}
445
446static inline void msg_set_timestamp(struct tipc_msg *m, u32 n)
447{
448 msg_set_word(m, 8, n);
449}
450
451static inline u32 msg_timestamp(struct tipc_msg *m)
452{
453 return msg_word(m, 8);
454}
455
456static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n)
457{
458 msg_set_word(m, 8, n);
459}
460
461static inline u32 msg_nameinst(struct tipc_msg *m) 420static inline u32 msg_nameinst(struct tipc_msg *m)
462{ 421{
463 return msg_word(m, 9); 422 return msg_word(m, 9);
@@ -500,40 +459,11 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
500 459
501 460
502/* 461/*
503 TIPC internal message header format, version 2 462 * Constants and routines used to read and write TIPC internal message headers
504 463 */
505 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
506 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
507 w0:|vers |msg usr|hdr sz |n|resrv| packet size |
508 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
509 w1:|m typ| sequence gap | broadcast ack no |
510 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to |
512 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
513 w3:| previous node |
514 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
515 w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no |
516 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
517 w5:| session no |rsv=0|r|berid|link prio|netpl|p|
518 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
519 w6:| originating node |
520 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
521 w7:| destination node |
522 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
523 w8:| transport sequence number |
524 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
525 w9:| msg count / bcast tag | link tolerance |
526 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
527 \ \
528 / User Specific Data /
529 \ \
530 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
531
532 NB: CONN_MANAGER use data message format. LINK_CONFIG has own format.
533*/
534 464
535/* 465/*
536 * Internal users 466 * Internal message users
537 */ 467 */
538 468
539#define BCAST_PROTOCOL 5 469#define BCAST_PROTOCOL 5
@@ -545,10 +475,9 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
545#define NAME_DISTRIBUTOR 11 475#define NAME_DISTRIBUTOR 11
546#define MSG_FRAGMENTER 12 476#define MSG_FRAGMENTER 12
547#define LINK_CONFIG 13 477#define LINK_CONFIG 13
548#define DSC_H_SIZE 40
549 478
550/* 479/*
551 * Connection management protocol messages 480 * Connection management protocol message types
552 */ 481 */
553 482
554#define CONN_PROBE 0 483#define CONN_PROBE 0
@@ -556,12 +485,41 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
556#define CONN_ACK 2 485#define CONN_ACK 2
557 486
558/* 487/*
559 * Name distributor messages 488 * Name distributor message types
560 */ 489 */
561 490
562#define PUBLICATION 0 491#define PUBLICATION 0
563#define WITHDRAWAL 1 492#define WITHDRAWAL 1
564 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
565 523
566/* 524/*
567 * Word 1 525 * Word 1
@@ -577,16 +535,6 @@ static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
577 msg_set_bits(m, 1, 16, 0x1fff, n); 535 msg_set_bits(m, 1, 16, 0x1fff, n);
578} 536}
579 537
580static inline u32 msg_req_links(struct tipc_msg *m)
581{
582 return msg_bits(m, 1, 16, 0xfff);
583}
584
585static inline void msg_set_req_links(struct tipc_msg *m, u32 n)
586{
587 msg_set_bits(m, 1, 16, 0xfff, n);
588}
589
590 538
591/* 539/*
592 * Word 2 540 * Word 2
@@ -749,14 +697,9 @@ static inline u32 msg_redundant_link(struct tipc_msg *m)
749 return msg_bits(m, 5, 12, 0x1); 697 return msg_bits(m, 5, 12, 0x1);
750} 698}
751 699
752static inline void msg_set_redundant_link(struct tipc_msg *m) 700static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
753{ 701{
754 msg_set_bits(m, 5, 12, 0x1, 1); 702 msg_set_bits(m, 5, 12, 0x1, r);
755}
756
757static inline void msg_clear_redundant_link(struct tipc_msg *m)
758{
759 msg_set_bits(m, 5, 12, 0x1, 0);
760} 703}
761 704
762 705
@@ -804,65 +747,11 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
804 msg_set_bits(m, 9, 0, 0xffff, n); 747 msg_set_bits(m, 9, 0, 0xffff, n);
805} 748}
806 749
807/*
808 * Routing table message data
809 */
810
811
812static inline u32 msg_remote_node(struct tipc_msg *m)
813{
814 return msg_word(m, msg_hdr_sz(m)/4);
815}
816
817static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
818{
819 msg_set_word(m, msg_hdr_sz(m)/4, a);
820}
821
822/*
823 * Segmentation message types
824 */
825
826#define FIRST_FRAGMENT 0
827#define FRAGMENT 1
828#define LAST_FRAGMENT 2
829
830/*
831 * Link management protocol message types
832 */
833
834#define STATE_MSG 0
835#define RESET_MSG 1
836#define ACTIVATE_MSG 2
837
838/*
839 * Changeover tunnel message types
840 */
841#define DUPLICATE_MSG 0
842#define ORIGINAL_MSG 1
843
844/*
845 * Routing table message types
846 */
847#define EXT_ROUTING_TABLE 0
848#define LOCAL_ROUTING_TABLE 1 /* obsoleted */
849#define SLAVE_ROUTING_TABLE 2
850#define ROUTE_ADDITION 3
851#define ROUTE_REMOVAL 4
852
853/*
854 * Config protocol message types
855 */
856
857#define DSC_REQ_MSG 0
858#define DSC_RESP_MSG 1
859
860u32 tipc_msg_tot_importance(struct tipc_msg *m); 750u32 tipc_msg_tot_importance(struct tipc_msg *m);
861void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, 751void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
862 u32 hsize, u32 destnode); 752 u32 hsize, u32 destnode);
863int 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,
864int tipc_msg_build(struct tipc_msg *hdr, 754 u32 num_sect, unsigned int total_len,
865 struct iovec const *msg_sect, u32 num_sect,
866 int max_size, int usrmem, struct sk_buff **buf); 755 int max_size, int usrmem, struct sk_buff **buf);
867 756
868static 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/name_distr.c b/net/tipc/name_distr.c
index 483c226c9581..80025a1b3bfd 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -2,7 +2,7 @@
2 * net/tipc/name_distr.c: TIPC name distribution code 2 * net/tipc/name_distr.c: TIPC name distribution code
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -109,11 +109,9 @@ static void named_cluster_distribute(struct sk_buff *buf)
109{ 109{
110 struct sk_buff *buf_copy; 110 struct sk_buff *buf_copy;
111 struct tipc_node *n_ptr; 111 struct tipc_node *n_ptr;
112 u32 n_num;
113 112
114 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { 113 list_for_each_entry(n_ptr, &tipc_node_list, list) {
115 n_ptr = tipc_net.nodes[n_num]; 114 if (tipc_node_active_links(n_ptr)) {
116 if (n_ptr && tipc_node_has_active_links(n_ptr)) {
117 buf_copy = skb_copy(buf, GFP_ATOMIC); 115 buf_copy = skb_copy(buf, GFP_ATOMIC);
118 if (!buf_copy) 116 if (!buf_copy)
119 break; 117 break;
@@ -162,7 +160,7 @@ void tipc_named_withdraw(struct publication *publ)
162 160
163 buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); 161 buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0);
164 if (!buf) { 162 if (!buf) {
165 warn("Withdrawl distribution failure\n"); 163 warn("Withdrawal distribution failure\n");
166 return; 164 return;
167 } 165 }
168 166
@@ -214,17 +212,16 @@ exit:
214} 212}
215 213
216/** 214/**
217 * node_is_down - remove publication associated with a failed node 215 * named_purge_publ - remove publication associated with a failed node
218 * 216 *
219 * Invoked for each publication issued by a newly failed node. 217 * Invoked for each publication issued by a newly failed node.
220 * Removes publication structure from name table & deletes it. 218 * Removes publication structure from name table & deletes it.
221 * In rare cases the link may have come back up again when this 219 * In rare cases the link may have come back up again when this
222 * function is called, and we have two items representing the same 220 * function is called, and we have two items representing the same
223 * publication. Nudge this item's key to distinguish it from the other. 221 * publication. Nudge this item's key to distinguish it from the other.
224 * (Note: Publication's node subscription is already unsubscribed.)
225 */ 222 */
226 223
227static void node_is_down(struct publication *publ) 224static void named_purge_publ(struct publication *publ)
228{ 225{
229 struct publication *p; 226 struct publication *p;
230 227
@@ -232,6 +229,8 @@ static void node_is_down(struct publication *publ)
232 publ->key += 1222345; 229 publ->key += 1222345;
233 p = tipc_nametbl_remove_publ(publ->type, publ->lower, 230 p = tipc_nametbl_remove_publ(publ->type, publ->lower,
234 publ->node, publ->ref, publ->key); 231 publ->node, publ->ref, publ->key);
232 if (p)
233 tipc_nodesub_unsubscribe(&p->subscr);
235 write_unlock_bh(&tipc_nametbl_lock); 234 write_unlock_bh(&tipc_nametbl_lock);
236 235
237 if (p != publ) { 236 if (p != publ) {
@@ -268,7 +267,8 @@ void tipc_named_recv(struct sk_buff *buf)
268 tipc_nodesub_subscribe(&publ->subscr, 267 tipc_nodesub_subscribe(&publ->subscr,
269 msg_orignode(msg), 268 msg_orignode(msg),
270 publ, 269 publ,
271 (net_ev_handler)node_is_down); 270 (net_ev_handler)
271 named_purge_publ);
272 } 272 }
273 } else if (msg_type(msg) == WITHDRAWAL) { 273 } else if (msg_type(msg) == WITHDRAWAL) {
274 publ = tipc_nametbl_remove_publ(ntohl(item->type), 274 publ = tipc_nametbl_remove_publ(ntohl(item->type),
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 9bacfd00b91e..68b3dd637291 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -2,7 +2,7 @@
2 * net/tipc/net.c: TIPC network routing code 2 * net/tipc/net.c: TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
39#include "name_distr.h" 39#include "name_distr.h"
40#include "subscr.h" 40#include "subscr.h"
41#include "port.h" 41#include "port.h"
42#include "node.h"
42#include "config.h" 43#include "config.h"
43 44
44/* 45/*
@@ -108,26 +109,6 @@
108*/ 109*/
109 110
110DEFINE_RWLOCK(tipc_net_lock); 111DEFINE_RWLOCK(tipc_net_lock);
111struct network tipc_net;
112
113static int net_start(void)
114{
115 tipc_net.nodes = kcalloc(tipc_max_nodes + 1,
116 sizeof(*tipc_net.nodes), GFP_ATOMIC);
117 tipc_net.highest_node = 0;
118
119 return tipc_net.nodes ? 0 : -ENOMEM;
120}
121
122static void net_stop(void)
123{
124 u32 n_num;
125
126 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++)
127 tipc_node_delete(tipc_net.nodes[n_num]);
128 kfree(tipc_net.nodes);
129 tipc_net.nodes = NULL;
130}
131 112
132static void net_route_named_msg(struct sk_buff *buf) 113static void net_route_named_msg(struct sk_buff *buf)
133{ 114{
@@ -217,9 +198,6 @@ int tipc_net_start(u32 addr)
217 tipc_named_reinit(); 198 tipc_named_reinit();
218 tipc_port_reinit(); 199 tipc_port_reinit();
219 200
220 res = net_start();
221 if (res)
222 return res;
223 res = tipc_bclink_init(); 201 res = tipc_bclink_init();
224 if (res) 202 if (res)
225 return res; 203 return res;
@@ -235,14 +213,16 @@ int tipc_net_start(u32 addr)
235 213
236void tipc_net_stop(void) 214void tipc_net_stop(void)
237{ 215{
216 struct tipc_node *node, *t_node;
217
238 if (tipc_mode != TIPC_NET_MODE) 218 if (tipc_mode != TIPC_NET_MODE)
239 return; 219 return;
240 write_lock_bh(&tipc_net_lock); 220 write_lock_bh(&tipc_net_lock);
241 tipc_bearer_stop(); 221 tipc_bearer_stop();
242 tipc_mode = TIPC_NODE_MODE; 222 tipc_mode = TIPC_NODE_MODE;
243 tipc_bclink_stop(); 223 tipc_bclink_stop();
244 net_stop(); 224 list_for_each_entry_safe(node, t_node, &tipc_node_list, list)
225 tipc_node_delete(node);
245 write_unlock_bh(&tipc_net_lock); 226 write_unlock_bh(&tipc_net_lock);
246 info("Left network mode\n"); 227 info("Left network mode\n");
247} 228}
248
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 4ae59ad04893..9eb4b9e220eb 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -2,7 +2,7 @@
2 * net/tipc/net.h: Include file for TIPC network routing code 2 * net/tipc/net.h: Include file for TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -37,23 +37,6 @@
37#ifndef _TIPC_NET_H 37#ifndef _TIPC_NET_H
38#define _TIPC_NET_H 38#define _TIPC_NET_H
39 39
40struct tipc_node;
41
42/**
43 * struct network - TIPC network structure
44 * @nodes: array of pointers to all nodes within cluster
45 * @highest_node: id of highest numbered node within cluster
46 * @links: number of (unicast) links to cluster
47 */
48
49struct network {
50 struct tipc_node **nodes;
51 u32 highest_node;
52 u32 links;
53};
54
55
56extern struct network tipc_net;
57extern rwlock_t tipc_net_lock; 40extern rwlock_t tipc_net_lock;
58 41
59void tipc_net_route_msg(struct sk_buff *buf); 42void tipc_net_route_msg(struct sk_buff *buf);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 3af53e327f49..2d106ef4fa4c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2,7 +2,7 @@
2 * net/tipc/node.c: TIPC node management routines 2 * net/tipc/node.c: TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -44,9 +44,33 @@ static void node_established_contact(struct tipc_node *n_ptr);
44 44
45static DEFINE_SPINLOCK(node_create_lock); 45static DEFINE_SPINLOCK(node_create_lock);
46 46
47static struct hlist_head node_htable[NODE_HTABLE_SIZE];
48LIST_HEAD(tipc_node_list);
49static u32 tipc_num_nodes;
50
51static atomic_t tipc_num_links = ATOMIC_INIT(0);
47u32 tipc_own_tag; 52u32 tipc_own_tag;
48 53
49/** 54/**
55 * tipc_node_find - locate specified node object, if it exists
56 */
57
58struct tipc_node *tipc_node_find(u32 addr)
59{
60 struct tipc_node *node;
61 struct hlist_node *pos;
62
63 if (unlikely(!in_own_cluster(addr)))
64 return NULL;
65
66 hlist_for_each_entry(node, pos, &node_htable[tipc_hashfn(addr)], hash) {
67 if (node->addr == addr)
68 return node;
69 }
70 return NULL;
71}
72
73/**
50 * tipc_node_create - create neighboring node 74 * tipc_node_create - create neighboring node
51 * 75 *
52 * Currently, this routine is called by neighbor discovery code, which holds 76 * Currently, this routine is called by neighbor discovery code, which holds
@@ -58,8 +82,7 @@ u32 tipc_own_tag;
58 82
59struct tipc_node *tipc_node_create(u32 addr) 83struct tipc_node *tipc_node_create(u32 addr)
60{ 84{
61 struct tipc_node *n_ptr; 85 struct tipc_node *n_ptr, *temp_node;
62 u32 n_num;
63 86
64 spin_lock_bh(&node_create_lock); 87 spin_lock_bh(&node_create_lock);
65 88
@@ -78,12 +101,19 @@ struct tipc_node *tipc_node_create(u32 addr)
78 101
79 n_ptr->addr = addr; 102 n_ptr->addr = addr;
80 spin_lock_init(&n_ptr->lock); 103 spin_lock_init(&n_ptr->lock);
104 INIT_HLIST_NODE(&n_ptr->hash);
105 INIT_LIST_HEAD(&n_ptr->list);
81 INIT_LIST_HEAD(&n_ptr->nsub); 106 INIT_LIST_HEAD(&n_ptr->nsub);
82 107
83 n_num = tipc_node(addr); 108 hlist_add_head(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
84 tipc_net.nodes[n_num] = n_ptr; 109
85 if (n_num > tipc_net.highest_node) 110 list_for_each_entry(temp_node, &tipc_node_list, list) {
86 tipc_net.highest_node = n_num; 111 if (n_ptr->addr < temp_node->addr)
112 break;
113 }
114 list_add_tail(&n_ptr->list, &temp_node->list);
115
116 tipc_num_nodes++;
87 117
88 spin_unlock_bh(&node_create_lock); 118 spin_unlock_bh(&node_create_lock);
89 return n_ptr; 119 return n_ptr;
@@ -91,18 +121,11 @@ struct tipc_node *tipc_node_create(u32 addr)
91 121
92void tipc_node_delete(struct tipc_node *n_ptr) 122void tipc_node_delete(struct tipc_node *n_ptr)
93{ 123{
94 u32 n_num; 124 list_del(&n_ptr->list);
95 125 hlist_del(&n_ptr->hash);
96 if (!n_ptr)
97 return;
98
99 n_num = tipc_node(n_ptr->addr);
100 tipc_net.nodes[n_num] = NULL;
101 kfree(n_ptr); 126 kfree(n_ptr);
102 127
103 while (!tipc_net.nodes[tipc_net.highest_node]) 128 tipc_num_nodes--;
104 if (--tipc_net.highest_node == 0)
105 break;
106} 129}
107 130
108 131
@@ -200,54 +223,32 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
200 node_lost_contact(n_ptr); 223 node_lost_contact(n_ptr);
201} 224}
202 225
203int tipc_node_has_active_links(struct tipc_node *n_ptr) 226int tipc_node_active_links(struct tipc_node *n_ptr)
204{ 227{
205 return n_ptr->active_links[0] != NULL; 228 return n_ptr->active_links[0] != NULL;
206} 229}
207 230
208int tipc_node_has_redundant_links(struct tipc_node *n_ptr) 231int tipc_node_redundant_links(struct tipc_node *n_ptr)
209{ 232{
210 return n_ptr->working_links > 1; 233 return n_ptr->working_links > 1;
211} 234}
212 235
213int tipc_node_is_up(struct tipc_node *n_ptr) 236int tipc_node_is_up(struct tipc_node *n_ptr)
214{ 237{
215 return tipc_node_has_active_links(n_ptr); 238 return tipc_node_active_links(n_ptr);
216} 239}
217 240
218struct tipc_node *tipc_node_attach_link(struct link *l_ptr) 241void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr)
219{ 242{
220 struct tipc_node *n_ptr = tipc_node_find(l_ptr->addr); 243 n_ptr->links[l_ptr->b_ptr->identity] = l_ptr;
221 244 atomic_inc(&tipc_num_links);
222 if (!n_ptr) 245 n_ptr->link_cnt++;
223 n_ptr = tipc_node_create(l_ptr->addr);
224 if (n_ptr) {
225 u32 bearer_id = l_ptr->b_ptr->identity;
226 char addr_string[16];
227
228 if (n_ptr->link_cnt >= 2) {
229 err("Attempt to create third link to %s\n",
230 tipc_addr_string_fill(addr_string, n_ptr->addr));
231 return NULL;
232 }
233
234 if (!n_ptr->links[bearer_id]) {
235 n_ptr->links[bearer_id] = l_ptr;
236 tipc_net.links++;
237 n_ptr->link_cnt++;
238 return n_ptr;
239 }
240 err("Attempt to establish second link on <%s> to %s\n",
241 l_ptr->b_ptr->publ.name,
242 tipc_addr_string_fill(addr_string, l_ptr->addr));
243 }
244 return NULL;
245} 246}
246 247
247void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr) 248void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
248{ 249{
249 n_ptr->links[l_ptr->b_ptr->identity] = NULL; 250 n_ptr->links[l_ptr->b_ptr->identity] = NULL;
250 tipc_net.links--; 251 atomic_dec(&tipc_num_links);
251 n_ptr->link_cnt--; 252 n_ptr->link_cnt--;
252} 253}
253 254
@@ -327,7 +328,6 @@ static void node_cleanup_finished(unsigned long node_addr)
327 328
328static void node_lost_contact(struct tipc_node *n_ptr) 329static void node_lost_contact(struct tipc_node *n_ptr)
329{ 330{
330 struct tipc_node_subscr *ns, *tns;
331 char addr_string[16]; 331 char addr_string[16];
332 u32 i; 332 u32 i;
333 333
@@ -365,12 +365,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
365 } 365 }
366 366
367 /* Notify subscribers */ 367 /* Notify subscribers */
368 list_for_each_entry_safe(ns, tns, &n_ptr->nsub, nodesub_list) { 368 tipc_nodesub_notify(n_ptr);
369 ns->node = NULL;
370 list_del_init(&ns->nodesub_list);
371 tipc_k_signal((Handler)ns->handle_node_down,
372 (unsigned long)ns->usr_handle);
373 }
374 369
375 /* Prevent re-contact with node until all cleanup is done */ 370 /* Prevent re-contact with node until all cleanup is done */
376 371
@@ -385,7 +380,6 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
385 struct tipc_node *n_ptr; 380 struct tipc_node *n_ptr;
386 struct tipc_node_info node_info; 381 struct tipc_node_info node_info;
387 u32 payload_size; 382 u32 payload_size;
388 u32 n_num;
389 383
390 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 384 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
391 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 385 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -396,15 +390,14 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
396 " (network address)"); 390 " (network address)");
397 391
398 read_lock_bh(&tipc_net_lock); 392 read_lock_bh(&tipc_net_lock);
399 if (!tipc_net.nodes) { 393 if (!tipc_num_nodes) {
400 read_unlock_bh(&tipc_net_lock); 394 read_unlock_bh(&tipc_net_lock);
401 return tipc_cfg_reply_none(); 395 return tipc_cfg_reply_none();
402 } 396 }
403 397
404 /* For now, get space for all other nodes */ 398 /* For now, get space for all other nodes */
405 399
406 payload_size = TLV_SPACE(sizeof(node_info)) * 400 payload_size = TLV_SPACE(sizeof(node_info)) * tipc_num_nodes;
407 (tipc_net.highest_node - 1);
408 if (payload_size > 32768u) { 401 if (payload_size > 32768u) {
409 read_unlock_bh(&tipc_net_lock); 402 read_unlock_bh(&tipc_net_lock);
410 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 403 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -418,9 +411,8 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
418 411
419 /* Add TLVs for all nodes in scope */ 412 /* Add TLVs for all nodes in scope */
420 413
421 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { 414 list_for_each_entry(n_ptr, &tipc_node_list, list) {
422 n_ptr = tipc_net.nodes[n_num]; 415 if (!tipc_in_scope(domain, n_ptr->addr))
423 if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
424 continue; 416 continue;
425 node_info.addr = htonl(n_ptr->addr); 417 node_info.addr = htonl(n_ptr->addr);
426 node_info.up = htonl(tipc_node_is_up(n_ptr)); 418 node_info.up = htonl(tipc_node_is_up(n_ptr));
@@ -439,7 +431,6 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
439 struct tipc_node *n_ptr; 431 struct tipc_node *n_ptr;
440 struct tipc_link_info link_info; 432 struct tipc_link_info link_info;
441 u32 payload_size; 433 u32 payload_size;
442 u32 n_num;
443 434
444 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 435 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
445 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 436 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -456,7 +447,8 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
456 447
457 /* Get space for all unicast links + multicast link */ 448 /* Get space for all unicast links + multicast link */
458 449
459 payload_size = TLV_SPACE(sizeof(link_info)) * (tipc_net.links + 1); 450 payload_size = TLV_SPACE(sizeof(link_info)) *
451 (atomic_read(&tipc_num_links) + 1);
460 if (payload_size > 32768u) { 452 if (payload_size > 32768u) {
461 read_unlock_bh(&tipc_net_lock); 453 read_unlock_bh(&tipc_net_lock);
462 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 454 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -470,18 +462,17 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
470 462
471 /* Add TLV for broadcast link */ 463 /* Add TLV for broadcast link */
472 464
473 link_info.dest = htonl(tipc_own_addr & 0xfffff00); 465 link_info.dest = htonl(tipc_cluster_mask(tipc_own_addr));
474 link_info.up = htonl(1); 466 link_info.up = htonl(1);
475 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME); 467 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME);
476 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); 468 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
477 469
478 /* Add TLVs for any other links in scope */ 470 /* Add TLVs for any other links in scope */
479 471
480 for (n_num = 1; n_num <= tipc_net.highest_node; n_num++) { 472 list_for_each_entry(n_ptr, &tipc_node_list, list) {
481 u32 i; 473 u32 i;
482 474
483 n_ptr = tipc_net.nodes[n_num]; 475 if (!tipc_in_scope(domain, n_ptr->addr))
484 if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
485 continue; 476 continue;
486 tipc_node_lock(n_ptr); 477 tipc_node_lock(n_ptr);
487 for (i = 0; i < MAX_BEARERS; i++) { 478 for (i = 0; i < MAX_BEARERS; i++) {
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 206a8efa410e..5c61afc7a0b9 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -2,7 +2,7 @@
2 * net/tipc/node.h: Include file for TIPC node management routines 2 * net/tipc/node.h: Include file for TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,8 @@
46 * struct tipc_node - TIPC node structure 46 * struct tipc_node - TIPC node structure
47 * @addr: network address of node 47 * @addr: network address of node
48 * @lock: spinlock governing access to structure 48 * @lock: spinlock governing access to structure
49 * @next: pointer to next node in sorted list of cluster's nodes 49 * @hash: links to adjacent nodes in unsorted hash chain
50 * @list: links to adjacent nodes in sorted list of cluster's nodes
50 * @nsub: list of "node down" subscriptions monitoring node 51 * @nsub: list of "node down" subscriptions monitoring node
51 * @active_links: pointers to active links to node 52 * @active_links: pointers to active links to node
52 * @links: pointers to all links to node 53 * @links: pointers to all links to node
@@ -69,7 +70,8 @@
69struct tipc_node { 70struct tipc_node {
70 u32 addr; 71 u32 addr;
71 spinlock_t lock; 72 spinlock_t lock;
72 struct tipc_node *next; 73 struct hlist_node hash;
74 struct list_head list;
73 struct list_head nsub; 75 struct list_head nsub;
74 struct link *active_links[2]; 76 struct link *active_links[2];
75 struct link *links[MAX_BEARERS]; 77 struct link *links[MAX_BEARERS];
@@ -90,27 +92,35 @@ struct tipc_node {
90 } bclink; 92 } bclink;
91}; 93};
92 94
95#define NODE_HTABLE_SIZE 512
96extern struct list_head tipc_node_list;
97
98/*
99 * A trivial power-of-two bitmask technique is used for speed, since this
100 * operation is done for every incoming TIPC packet. The number of hash table
101 * entries has been chosen so that no hash chain exceeds 8 nodes and will
102 * usually be much smaller (typically only a single node).
103 */
104static inline unsigned int tipc_hashfn(u32 addr)
105{
106 return addr & (NODE_HTABLE_SIZE - 1);
107}
108
93extern u32 tipc_own_tag; 109extern u32 tipc_own_tag;
94 110
111struct tipc_node *tipc_node_find(u32 addr);
95struct tipc_node *tipc_node_create(u32 addr); 112struct tipc_node *tipc_node_create(u32 addr);
96void tipc_node_delete(struct tipc_node *n_ptr); 113void tipc_node_delete(struct tipc_node *n_ptr);
97struct tipc_node *tipc_node_attach_link(struct link *l_ptr); 114void tipc_node_attach_link(struct tipc_node *n_ptr, struct link *l_ptr);
98void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr); 115void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr);
99void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr); 116void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
100void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr); 117void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
101int tipc_node_has_active_links(struct tipc_node *n_ptr); 118int tipc_node_active_links(struct tipc_node *n_ptr);
102int tipc_node_has_redundant_links(struct tipc_node *n_ptr); 119int tipc_node_redundant_links(struct tipc_node *n_ptr);
103int tipc_node_is_up(struct tipc_node *n_ptr); 120int tipc_node_is_up(struct tipc_node *n_ptr);
104struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space); 121struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
105struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); 122struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
106 123
107static inline struct tipc_node *tipc_node_find(u32 addr)
108{
109 if (likely(in_own_cluster(addr)))
110 return tipc_net.nodes[tipc_node(addr)];
111 return NULL;
112}
113
114static inline void tipc_node_lock(struct tipc_node *n_ptr) 124static inline void tipc_node_lock(struct tipc_node *n_ptr)
115{ 125{
116 spin_lock_bh(&n_ptr->lock); 126 spin_lock_bh(&n_ptr->lock);
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 018a55332d91..c3c2815ae630 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling 2 * net/tipc/node_subscr.c: TIPC "node down" subscription handling
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -76,3 +76,22 @@ void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub)
76 list_del_init(&node_sub->nodesub_list); 76 list_del_init(&node_sub->nodesub_list);
77 tipc_node_unlock(node_sub->node); 77 tipc_node_unlock(node_sub->node);
78} 78}
79
80/**
81 * tipc_nodesub_notify - notify subscribers that a node is unreachable
82 *
83 * Note: node is locked by caller
84 */
85
86void tipc_nodesub_notify(struct tipc_node *node)
87{
88 struct tipc_node_subscr *ns;
89
90 list_for_each_entry(ns, &node->nsub, nodesub_list) {
91 if (ns->handle_node_down) {
92 tipc_k_signal((Handler)ns->handle_node_down,
93 (unsigned long)ns->usr_handle);
94 ns->handle_node_down = NULL;
95 }
96 }
97}
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
index 006ed739f515..4bc2ca0867a1 100644
--- a/net/tipc/node_subscr.h
+++ b/net/tipc/node_subscr.h
@@ -2,7 +2,7 @@
2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling 2 * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -59,5 +59,6 @@ struct tipc_node_subscr {
59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr, 59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
60 void *usr_handle, net_ev_handler handle_down); 60 void *usr_handle, net_ev_handler handle_down);
61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub); 61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub);
62void tipc_nodesub_notify(struct tipc_node *node);
62 63
63#endif 64#endif
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 067bab2a0b98..c68dc956a423 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -2,7 +2,7 @@
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2007, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -54,33 +54,19 @@ static DEFINE_SPINLOCK(queue_lock);
54 54
55static LIST_HEAD(ports); 55static LIST_HEAD(ports);
56static void port_handle_node_down(unsigned long ref); 56static void port_handle_node_down(unsigned long ref);
57static struct sk_buff *port_build_self_abort_msg(struct port *, u32 err); 57static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
58static struct sk_buff *port_build_peer_abort_msg(struct port *, u32 err); 58static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
59static void port_timeout(unsigned long ref); 59static void port_timeout(unsigned long ref);
60 60
61 61
62static u32 port_peernode(struct port *p_ptr) 62static u32 port_peernode(struct tipc_port *p_ptr)
63{ 63{
64 return msg_destnode(&p_ptr->publ.phdr); 64 return msg_destnode(&p_ptr->phdr);
65} 65}
66 66
67static u32 port_peerport(struct port *p_ptr) 67static u32 port_peerport(struct tipc_port *p_ptr)
68{ 68{
69 return msg_destport(&p_ptr->publ.phdr); 69 return msg_destport(&p_ptr->phdr);
70}
71
72static u32 port_out_seqno(struct port *p_ptr)
73{
74 return msg_transp_seqno(&p_ptr->publ.phdr);
75}
76
77static void port_incr_out_seqno(struct port *p_ptr)
78{
79 struct tipc_msg *m = &p_ptr->publ.phdr;
80
81 if (likely(!msg_routed(m)))
82 return;
83 msg_set_transp_seqno(m, (msg_transp_seqno(m) + 1));
84} 70}
85 71
86/** 72/**
@@ -88,13 +74,14 @@ static void port_incr_out_seqno(struct port *p_ptr)
88 */ 74 */
89 75
90int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, 76int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
91 u32 num_sect, struct iovec const *msg_sect) 77 u32 num_sect, struct iovec const *msg_sect,
78 unsigned int total_len)
92{ 79{
93 struct tipc_msg *hdr; 80 struct tipc_msg *hdr;
94 struct sk_buff *buf; 81 struct sk_buff *buf;
95 struct sk_buff *ibuf = NULL; 82 struct sk_buff *ibuf = NULL;
96 struct port_list dports = {0, NULL, }; 83 struct port_list dports = {0, NULL, };
97 struct port *oport = tipc_port_deref(ref); 84 struct tipc_port *oport = tipc_port_deref(ref);
98 int ext_targets; 85 int ext_targets;
99 int res; 86 int res;
100 87
@@ -103,13 +90,16 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
103 90
104 /* Create multicast message */ 91 /* Create multicast message */
105 92
106 hdr = &oport->publ.phdr; 93 hdr = &oport->phdr;
107 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);
108 msg_set_nametype(hdr, seq->type); 98 msg_set_nametype(hdr, seq->type);
109 msg_set_namelower(hdr, seq->lower); 99 msg_set_namelower(hdr, seq->lower);
110 msg_set_nameupper(hdr, seq->upper); 100 msg_set_nameupper(hdr, seq->upper);
111 msg_set_hdr_sz(hdr, MCAST_H_SIZE); 101 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
112 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,
113 !oport->user_port, &buf); 103 !oport->user_port, &buf);
114 if (unlikely(!buf)) 104 if (unlikely(!buf))
115 return res; 105 return res;
@@ -175,6 +165,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
175 /* Deliver a copy of message to each destination port */ 165 /* Deliver a copy of message to each destination port */
176 166
177 if (dp->count != 0) { 167 if (dp->count != 0) {
168 msg_set_destnode(msg, tipc_own_addr);
178 if (dp->count == 1) { 169 if (dp->count == 1) {
179 msg_set_destport(msg, dp->ports[0]); 170 msg_set_destport(msg, dp->ports[0]);
180 tipc_port_recv_msg(buf); 171 tipc_port_recv_msg(buf);
@@ -211,7 +202,7 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
211 void (*wakeup)(struct tipc_port *), 202 void (*wakeup)(struct tipc_port *),
212 const u32 importance) 203 const u32 importance)
213{ 204{
214 struct port *p_ptr; 205 struct tipc_port *p_ptr;
215 struct tipc_msg *msg; 206 struct tipc_msg *msg;
216 u32 ref; 207 u32 ref;
217 208
@@ -220,21 +211,19 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
220 warn("Port creation failed, no memory\n"); 211 warn("Port creation failed, no memory\n");
221 return NULL; 212 return NULL;
222 } 213 }
223 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 214 ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
224 if (!ref) { 215 if (!ref) {
225 warn("Port creation failed, reference table exhausted\n"); 216 warn("Port creation failed, reference table exhausted\n");
226 kfree(p_ptr); 217 kfree(p_ptr);
227 return NULL; 218 return NULL;
228 } 219 }
229 220
230 p_ptr->publ.usr_handle = usr_handle; 221 p_ptr->usr_handle = usr_handle;
231 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 222 p_ptr->max_pkt = MAX_PKT_DEFAULT;
232 p_ptr->publ.ref = ref; 223 p_ptr->ref = ref;
233 msg = &p_ptr->publ.phdr; 224 msg = &p_ptr->phdr;
234 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 225 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
235 msg_set_origport(msg, ref); 226 msg_set_origport(msg, ref);
236 p_ptr->last_in_seqno = 41;
237 p_ptr->sent = 1;
238 INIT_LIST_HEAD(&p_ptr->wait_list); 227 INIT_LIST_HEAD(&p_ptr->wait_list);
239 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 228 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
240 p_ptr->dispatcher = dispatcher; 229 p_ptr->dispatcher = dispatcher;
@@ -246,12 +235,12 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
246 INIT_LIST_HEAD(&p_ptr->port_list); 235 INIT_LIST_HEAD(&p_ptr->port_list);
247 list_add_tail(&p_ptr->port_list, &ports); 236 list_add_tail(&p_ptr->port_list, &ports);
248 spin_unlock_bh(&tipc_port_list_lock); 237 spin_unlock_bh(&tipc_port_list_lock);
249 return &(p_ptr->publ); 238 return p_ptr;
250} 239}
251 240
252int tipc_deleteport(u32 ref) 241int tipc_deleteport(u32 ref)
253{ 242{
254 struct port *p_ptr; 243 struct tipc_port *p_ptr;
255 struct sk_buff *buf = NULL; 244 struct sk_buff *buf = NULL;
256 245
257 tipc_withdraw(ref, 0, NULL); 246 tipc_withdraw(ref, 0, NULL);
@@ -263,7 +252,7 @@ int tipc_deleteport(u32 ref)
263 tipc_port_unlock(p_ptr); 252 tipc_port_unlock(p_ptr);
264 253
265 k_cancel_timer(&p_ptr->timer); 254 k_cancel_timer(&p_ptr->timer);
266 if (p_ptr->publ.connected) { 255 if (p_ptr->connected) {
267 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 256 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
268 tipc_nodesub_unsubscribe(&p_ptr->subscription); 257 tipc_nodesub_unsubscribe(&p_ptr->subscription);
269 } 258 }
@@ -279,14 +268,14 @@ int tipc_deleteport(u32 ref)
279 return 0; 268 return 0;
280} 269}
281 270
282static int port_unreliable(struct port *p_ptr) 271static int port_unreliable(struct tipc_port *p_ptr)
283{ 272{
284 return msg_src_droppable(&p_ptr->publ.phdr); 273 return msg_src_droppable(&p_ptr->phdr);
285} 274}
286 275
287int tipc_portunreliable(u32 ref, unsigned int *isunreliable) 276int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
288{ 277{
289 struct port *p_ptr; 278 struct tipc_port *p_ptr;
290 279
291 p_ptr = tipc_port_lock(ref); 280 p_ptr = tipc_port_lock(ref);
292 if (!p_ptr) 281 if (!p_ptr)
@@ -298,24 +287,24 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
298 287
299int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 288int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
300{ 289{
301 struct port *p_ptr; 290 struct tipc_port *p_ptr;
302 291
303 p_ptr = tipc_port_lock(ref); 292 p_ptr = tipc_port_lock(ref);
304 if (!p_ptr) 293 if (!p_ptr)
305 return -EINVAL; 294 return -EINVAL;
306 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 295 msg_set_src_droppable(&p_ptr->phdr, (isunreliable != 0));
307 tipc_port_unlock(p_ptr); 296 tipc_port_unlock(p_ptr);
308 return 0; 297 return 0;
309} 298}
310 299
311static int port_unreturnable(struct port *p_ptr) 300static int port_unreturnable(struct tipc_port *p_ptr)
312{ 301{
313 return msg_dest_droppable(&p_ptr->publ.phdr); 302 return msg_dest_droppable(&p_ptr->phdr);
314} 303}
315 304
316int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) 305int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
317{ 306{
318 struct port *p_ptr; 307 struct tipc_port *p_ptr;
319 308
320 p_ptr = tipc_port_lock(ref); 309 p_ptr = tipc_port_lock(ref);
321 if (!p_ptr) 310 if (!p_ptr)
@@ -327,12 +316,12 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
327 316
328int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 317int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
329{ 318{
330 struct port *p_ptr; 319 struct tipc_port *p_ptr;
331 320
332 p_ptr = tipc_port_lock(ref); 321 p_ptr = tipc_port_lock(ref);
333 if (!p_ptr) 322 if (!p_ptr)
334 return -EINVAL; 323 return -EINVAL;
335 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 324 msg_set_dest_droppable(&p_ptr->phdr, (isunrejectable != 0));
336 tipc_port_unlock(p_ptr); 325 tipc_port_unlock(p_ptr);
337 return 0; 326 return 0;
338} 327}
@@ -345,7 +334,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
345static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, 334static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
346 u32 origport, u32 orignode, 335 u32 origport, u32 orignode,
347 u32 usr, u32 type, u32 err, 336 u32 usr, u32 type, u32 err,
348 u32 seqno, u32 ack) 337 u32 ack)
349{ 338{
350 struct sk_buff *buf; 339 struct sk_buff *buf;
351 struct tipc_msg *msg; 340 struct tipc_msg *msg;
@@ -358,7 +347,6 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
358 msg_set_destport(msg, destport); 347 msg_set_destport(msg, destport);
359 msg_set_origport(msg, origport); 348 msg_set_origport(msg, origport);
360 msg_set_orignode(msg, orignode); 349 msg_set_orignode(msg, orignode);
361 msg_set_transp_seqno(msg, seqno);
362 msg_set_msgcnt(msg, ack); 350 msg_set_msgcnt(msg, ack);
363 } 351 }
364 return buf; 352 return buf;
@@ -413,10 +401,10 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
413 /* send self-abort message when rejecting on a connected port */ 401 /* send self-abort message when rejecting on a connected port */
414 if (msg_connected(msg)) { 402 if (msg_connected(msg)) {
415 struct sk_buff *abuf = NULL; 403 struct sk_buff *abuf = NULL;
416 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 404 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
417 405
418 if (p_ptr) { 406 if (p_ptr) {
419 if (p_ptr->publ.connected) 407 if (p_ptr->connected)
420 abuf = port_build_self_abort_msg(p_ptr, err); 408 abuf = port_build_self_abort_msg(p_ptr, err);
421 tipc_port_unlock(p_ptr); 409 tipc_port_unlock(p_ptr);
422 } 410 }
@@ -429,14 +417,14 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
429 return data_sz; 417 return data_sz;
430} 418}
431 419
432int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 420int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
433 struct iovec const *msg_sect, u32 num_sect, 421 struct iovec const *msg_sect, u32 num_sect,
434 int err) 422 unsigned int total_len, int err)
435{ 423{
436 struct sk_buff *buf; 424 struct sk_buff *buf;
437 int res; 425 int res;
438 426
439 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,
440 !p_ptr->user_port, &buf); 428 !p_ptr->user_port, &buf);
441 if (!buf) 429 if (!buf)
442 return res; 430 return res;
@@ -446,13 +434,13 @@ int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
446 434
447static void port_timeout(unsigned long ref) 435static void port_timeout(unsigned long ref)
448{ 436{
449 struct port *p_ptr = tipc_port_lock(ref); 437 struct tipc_port *p_ptr = tipc_port_lock(ref);
450 struct sk_buff *buf = NULL; 438 struct sk_buff *buf = NULL;
451 439
452 if (!p_ptr) 440 if (!p_ptr)
453 return; 441 return;
454 442
455 if (!p_ptr->publ.connected) { 443 if (!p_ptr->connected) {
456 tipc_port_unlock(p_ptr); 444 tipc_port_unlock(p_ptr);
457 return; 445 return;
458 } 446 }
@@ -463,14 +451,12 @@ static void port_timeout(unsigned long ref)
463 } else { 451 } else {
464 buf = port_build_proto_msg(port_peerport(p_ptr), 452 buf = port_build_proto_msg(port_peerport(p_ptr),
465 port_peernode(p_ptr), 453 port_peernode(p_ptr),
466 p_ptr->publ.ref, 454 p_ptr->ref,
467 tipc_own_addr, 455 tipc_own_addr,
468 CONN_MANAGER, 456 CONN_MANAGER,
469 CONN_PROBE, 457 CONN_PROBE,
470 TIPC_OK, 458 TIPC_OK,
471 port_out_seqno(p_ptr),
472 0); 459 0);
473 port_incr_out_seqno(p_ptr);
474 p_ptr->probing_state = PROBING; 460 p_ptr->probing_state = PROBING;
475 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 461 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
476 } 462 }
@@ -481,7 +467,7 @@ static void port_timeout(unsigned long ref)
481 467
482static void port_handle_node_down(unsigned long ref) 468static void port_handle_node_down(unsigned long ref)
483{ 469{
484 struct port *p_ptr = tipc_port_lock(ref); 470 struct tipc_port *p_ptr = tipc_port_lock(ref);
485 struct sk_buff *buf = NULL; 471 struct sk_buff *buf = NULL;
486 472
487 if (!p_ptr) 473 if (!p_ptr)
@@ -492,73 +478,71 @@ static void port_handle_node_down(unsigned long ref)
492} 478}
493 479
494 480
495static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err) 481static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
496{ 482{
497 u32 imp = msg_importance(&p_ptr->publ.phdr); 483 u32 imp = msg_importance(&p_ptr->phdr);
498 484
499 if (!p_ptr->publ.connected) 485 if (!p_ptr->connected)
500 return NULL; 486 return NULL;
501 if (imp < TIPC_CRITICAL_IMPORTANCE) 487 if (imp < TIPC_CRITICAL_IMPORTANCE)
502 imp++; 488 imp++;
503 return port_build_proto_msg(p_ptr->publ.ref, 489 return port_build_proto_msg(p_ptr->ref,
504 tipc_own_addr, 490 tipc_own_addr,
505 port_peerport(p_ptr), 491 port_peerport(p_ptr),
506 port_peernode(p_ptr), 492 port_peernode(p_ptr),
507 imp, 493 imp,
508 TIPC_CONN_MSG, 494 TIPC_CONN_MSG,
509 err, 495 err,
510 p_ptr->last_in_seqno + 1,
511 0); 496 0);
512} 497}
513 498
514 499
515static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err) 500static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
516{ 501{
517 u32 imp = msg_importance(&p_ptr->publ.phdr); 502 u32 imp = msg_importance(&p_ptr->phdr);
518 503
519 if (!p_ptr->publ.connected) 504 if (!p_ptr->connected)
520 return NULL; 505 return NULL;
521 if (imp < TIPC_CRITICAL_IMPORTANCE) 506 if (imp < TIPC_CRITICAL_IMPORTANCE)
522 imp++; 507 imp++;
523 return port_build_proto_msg(port_peerport(p_ptr), 508 return port_build_proto_msg(port_peerport(p_ptr),
524 port_peernode(p_ptr), 509 port_peernode(p_ptr),
525 p_ptr->publ.ref, 510 p_ptr->ref,
526 tipc_own_addr, 511 tipc_own_addr,
527 imp, 512 imp,
528 TIPC_CONN_MSG, 513 TIPC_CONN_MSG,
529 err, 514 err,
530 port_out_seqno(p_ptr),
531 0); 515 0);
532} 516}
533 517
534void tipc_port_recv_proto_msg(struct sk_buff *buf) 518void tipc_port_recv_proto_msg(struct sk_buff *buf)
535{ 519{
536 struct tipc_msg *msg = buf_msg(buf); 520 struct tipc_msg *msg = buf_msg(buf);
537 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 521 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
538 u32 err = TIPC_OK; 522 u32 err = TIPC_OK;
539 struct sk_buff *r_buf = NULL; 523 struct sk_buff *r_buf = NULL;
540 struct sk_buff *abort_buf = NULL; 524 struct sk_buff *abort_buf = NULL;
541 525
542 if (!p_ptr) { 526 if (!p_ptr) {
543 err = TIPC_ERR_NO_PORT; 527 err = TIPC_ERR_NO_PORT;
544 } else if (p_ptr->publ.connected) { 528 } else if (p_ptr->connected) {
545 if ((port_peernode(p_ptr) != msg_orignode(msg)) || 529 if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
546 (port_peerport(p_ptr) != msg_origport(msg))) { 530 (port_peerport(p_ptr) != msg_origport(msg))) {
547 err = TIPC_ERR_NO_PORT; 531 err = TIPC_ERR_NO_PORT;
548 } else if (msg_type(msg) == CONN_ACK) { 532 } else if (msg_type(msg) == CONN_ACK) {
549 int wakeup = tipc_port_congested(p_ptr) && 533 int wakeup = tipc_port_congested(p_ptr) &&
550 p_ptr->publ.congested && 534 p_ptr->congested &&
551 p_ptr->wakeup; 535 p_ptr->wakeup;
552 p_ptr->acked += msg_msgcnt(msg); 536 p_ptr->acked += msg_msgcnt(msg);
553 if (tipc_port_congested(p_ptr)) 537 if (tipc_port_congested(p_ptr))
554 goto exit; 538 goto exit;
555 p_ptr->publ.congested = 0; 539 p_ptr->congested = 0;
556 if (!wakeup) 540 if (!wakeup)
557 goto exit; 541 goto exit;
558 p_ptr->wakeup(&p_ptr->publ); 542 p_ptr->wakeup(p_ptr);
559 goto exit; 543 goto exit;
560 } 544 }
561 } else if (p_ptr->publ.published) { 545 } else if (p_ptr->published) {
562 err = TIPC_ERR_NO_PORT; 546 err = TIPC_ERR_NO_PORT;
563 } 547 }
564 if (err) { 548 if (err) {
@@ -569,7 +553,6 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
569 TIPC_HIGH_IMPORTANCE, 553 TIPC_HIGH_IMPORTANCE,
570 TIPC_CONN_MSG, 554 TIPC_CONN_MSG,
571 err, 555 err,
572 0,
573 0); 556 0);
574 goto exit; 557 goto exit;
575 } 558 }
@@ -583,11 +566,9 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
583 CONN_MANAGER, 566 CONN_MANAGER,
584 CONN_PROBE_REPLY, 567 CONN_PROBE_REPLY,
585 TIPC_OK, 568 TIPC_OK,
586 port_out_seqno(p_ptr),
587 0); 569 0);
588 } 570 }
589 p_ptr->probing_state = CONFIRMED; 571 p_ptr->probing_state = CONFIRMED;
590 port_incr_out_seqno(p_ptr);
591exit: 572exit:
592 if (p_ptr) 573 if (p_ptr)
593 tipc_port_unlock(p_ptr); 574 tipc_port_unlock(p_ptr);
@@ -596,29 +577,29 @@ exit:
596 buf_discard(buf); 577 buf_discard(buf);
597} 578}
598 579
599static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) 580static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id)
600{ 581{
601 struct publication *publ; 582 struct publication *publ;
602 583
603 if (full_id) 584 if (full_id)
604 tipc_printf(buf, "<%u.%u.%u:%u>:", 585 tipc_printf(buf, "<%u.%u.%u:%u>:",
605 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 586 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
606 tipc_node(tipc_own_addr), p_ptr->publ.ref); 587 tipc_node(tipc_own_addr), p_ptr->ref);
607 else 588 else
608 tipc_printf(buf, "%-10u:", p_ptr->publ.ref); 589 tipc_printf(buf, "%-10u:", p_ptr->ref);
609 590
610 if (p_ptr->publ.connected) { 591 if (p_ptr->connected) {
611 u32 dport = port_peerport(p_ptr); 592 u32 dport = port_peerport(p_ptr);
612 u32 destnode = port_peernode(p_ptr); 593 u32 destnode = port_peernode(p_ptr);
613 594
614 tipc_printf(buf, " connected to <%u.%u.%u:%u>", 595 tipc_printf(buf, " connected to <%u.%u.%u:%u>",
615 tipc_zone(destnode), tipc_cluster(destnode), 596 tipc_zone(destnode), tipc_cluster(destnode),
616 tipc_node(destnode), dport); 597 tipc_node(destnode), dport);
617 if (p_ptr->publ.conn_type != 0) 598 if (p_ptr->conn_type != 0)
618 tipc_printf(buf, " via {%u,%u}", 599 tipc_printf(buf, " via {%u,%u}",
619 p_ptr->publ.conn_type, 600 p_ptr->conn_type,
620 p_ptr->publ.conn_instance); 601 p_ptr->conn_instance);
621 } else if (p_ptr->publ.published) { 602 } else if (p_ptr->published) {
622 tipc_printf(buf, " bound to"); 603 tipc_printf(buf, " bound to");
623 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 604 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
624 if (publ->lower == publ->upper) 605 if (publ->lower == publ->upper)
@@ -639,7 +620,7 @@ struct sk_buff *tipc_port_get_ports(void)
639 struct sk_buff *buf; 620 struct sk_buff *buf;
640 struct tlv_desc *rep_tlv; 621 struct tlv_desc *rep_tlv;
641 struct print_buf pb; 622 struct print_buf pb;
642 struct port *p_ptr; 623 struct tipc_port *p_ptr;
643 int str_len; 624 int str_len;
644 625
645 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); 626 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
@@ -650,9 +631,9 @@ struct sk_buff *tipc_port_get_ports(void)
650 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); 631 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
651 spin_lock_bh(&tipc_port_list_lock); 632 spin_lock_bh(&tipc_port_list_lock);
652 list_for_each_entry(p_ptr, &ports, port_list) { 633 list_for_each_entry(p_ptr, &ports, port_list) {
653 spin_lock_bh(p_ptr->publ.lock); 634 spin_lock_bh(p_ptr->lock);
654 port_print(p_ptr, &pb, 0); 635 port_print(p_ptr, &pb, 0);
655 spin_unlock_bh(p_ptr->publ.lock); 636 spin_unlock_bh(p_ptr->lock);
656 } 637 }
657 spin_unlock_bh(&tipc_port_list_lock); 638 spin_unlock_bh(&tipc_port_list_lock);
658 str_len = tipc_printbuf_validate(&pb); 639 str_len = tipc_printbuf_validate(&pb);
@@ -665,12 +646,12 @@ struct sk_buff *tipc_port_get_ports(void)
665 646
666void tipc_port_reinit(void) 647void tipc_port_reinit(void)
667{ 648{
668 struct port *p_ptr; 649 struct tipc_port *p_ptr;
669 struct tipc_msg *msg; 650 struct tipc_msg *msg;
670 651
671 spin_lock_bh(&tipc_port_list_lock); 652 spin_lock_bh(&tipc_port_list_lock);
672 list_for_each_entry(p_ptr, &ports, port_list) { 653 list_for_each_entry(p_ptr, &ports, port_list) {
673 msg = &p_ptr->publ.phdr; 654 msg = &p_ptr->phdr;
674 if (msg_orignode(msg) == tipc_own_addr) 655 if (msg_orignode(msg) == tipc_own_addr)
675 break; 656 break;
676 msg_set_prevnode(msg, tipc_own_addr); 657 msg_set_prevnode(msg, tipc_own_addr);
@@ -695,7 +676,7 @@ static void port_dispatcher_sigh(void *dummy)
695 spin_unlock_bh(&queue_lock); 676 spin_unlock_bh(&queue_lock);
696 677
697 while (buf) { 678 while (buf) {
698 struct port *p_ptr; 679 struct tipc_port *p_ptr;
699 struct user_port *up_ptr; 680 struct user_port *up_ptr;
700 struct tipc_portid orig; 681 struct tipc_portid orig;
701 struct tipc_name_seq dseq; 682 struct tipc_name_seq dseq;
@@ -720,8 +701,8 @@ static void port_dispatcher_sigh(void *dummy)
720 orig.node = msg_orignode(msg); 701 orig.node = msg_orignode(msg);
721 up_ptr = p_ptr->user_port; 702 up_ptr = p_ptr->user_port;
722 usr_handle = up_ptr->usr_handle; 703 usr_handle = up_ptr->usr_handle;
723 connected = p_ptr->publ.connected; 704 connected = p_ptr->connected;
724 published = p_ptr->publ.published; 705 published = p_ptr->published;
725 706
726 if (unlikely(msg_errcode(msg))) 707 if (unlikely(msg_errcode(msg)))
727 goto err; 708 goto err;
@@ -732,6 +713,7 @@ static void port_dispatcher_sigh(void *dummy)
732 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 713 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
733 u32 peer_port = port_peerport(p_ptr); 714 u32 peer_port = port_peerport(p_ptr);
734 u32 peer_node = port_peernode(p_ptr); 715 u32 peer_node = port_peernode(p_ptr);
716 u32 dsz;
735 717
736 tipc_port_unlock(p_ptr); 718 tipc_port_unlock(p_ptr);
737 if (unlikely(!cb)) 719 if (unlikely(!cb))
@@ -742,13 +724,14 @@ static void port_dispatcher_sigh(void *dummy)
742 } else if ((msg_origport(msg) != peer_port) || 724 } else if ((msg_origport(msg) != peer_port) ||
743 (msg_orignode(msg) != peer_node)) 725 (msg_orignode(msg) != peer_node))
744 goto reject; 726 goto reject;
745 if (unlikely(++p_ptr->publ.conn_unacked >= 727 dsz = msg_data_sz(msg);
746 TIPC_FLOW_CONTROL_WIN)) 728 if (unlikely(dsz &&
729 (++p_ptr->conn_unacked >=
730 TIPC_FLOW_CONTROL_WIN)))
747 tipc_acknowledge(dref, 731 tipc_acknowledge(dref,
748 p_ptr->publ.conn_unacked); 732 p_ptr->conn_unacked);
749 skb_pull(buf, msg_hdr_sz(msg)); 733 skb_pull(buf, msg_hdr_sz(msg));
750 cb(usr_handle, dref, &buf, msg_data(msg), 734 cb(usr_handle, dref, &buf, msg_data(msg), dsz);
751 msg_data_sz(msg));
752 break; 735 break;
753 } 736 }
754 case TIPC_DIRECT_MSG:{ 737 case TIPC_DIRECT_MSG:{
@@ -872,7 +855,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
872 855
873static void port_wakeup_sh(unsigned long ref) 856static void port_wakeup_sh(unsigned long ref)
874{ 857{
875 struct port *p_ptr; 858 struct tipc_port *p_ptr;
876 struct user_port *up_ptr; 859 struct user_port *up_ptr;
877 tipc_continue_event cb = NULL; 860 tipc_continue_event cb = NULL;
878 void *uh = NULL; 861 void *uh = NULL;
@@ -898,14 +881,14 @@ static void port_wakeup(struct tipc_port *p_ptr)
898 881
899void tipc_acknowledge(u32 ref, u32 ack) 882void tipc_acknowledge(u32 ref, u32 ack)
900{ 883{
901 struct port *p_ptr; 884 struct tipc_port *p_ptr;
902 struct sk_buff *buf = NULL; 885 struct sk_buff *buf = NULL;
903 886
904 p_ptr = tipc_port_lock(ref); 887 p_ptr = tipc_port_lock(ref);
905 if (!p_ptr) 888 if (!p_ptr)
906 return; 889 return;
907 if (p_ptr->publ.connected) { 890 if (p_ptr->connected) {
908 p_ptr->publ.conn_unacked -= ack; 891 p_ptr->conn_unacked -= ack;
909 buf = port_build_proto_msg(port_peerport(p_ptr), 892 buf = port_build_proto_msg(port_peerport(p_ptr),
910 port_peernode(p_ptr), 893 port_peernode(p_ptr),
911 ref, 894 ref,
@@ -913,7 +896,6 @@ void tipc_acknowledge(u32 ref, u32 ack)
913 CONN_MANAGER, 896 CONN_MANAGER,
914 CONN_ACK, 897 CONN_ACK,
915 TIPC_OK, 898 TIPC_OK,
916 port_out_seqno(p_ptr),
917 ack); 899 ack);
918 } 900 }
919 tipc_port_unlock(p_ptr); 901 tipc_port_unlock(p_ptr);
@@ -936,14 +918,14 @@ int tipc_createport(void *usr_handle,
936 u32 *portref) 918 u32 *portref)
937{ 919{
938 struct user_port *up_ptr; 920 struct user_port *up_ptr;
939 struct port *p_ptr; 921 struct tipc_port *p_ptr;
940 922
941 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 923 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
942 if (!up_ptr) { 924 if (!up_ptr) {
943 warn("Port creation failed, no memory\n"); 925 warn("Port creation failed, no memory\n");
944 return -ENOMEM; 926 return -ENOMEM;
945 } 927 }
946 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, 928 p_ptr = (struct tipc_port *)tipc_createport_raw(NULL, port_dispatcher,
947 port_wakeup, importance); 929 port_wakeup, importance);
948 if (!p_ptr) { 930 if (!p_ptr) {
949 kfree(up_ptr); 931 kfree(up_ptr);
@@ -952,7 +934,7 @@ int tipc_createport(void *usr_handle,
952 934
953 p_ptr->user_port = up_ptr; 935 p_ptr->user_port = up_ptr;
954 up_ptr->usr_handle = usr_handle; 936 up_ptr->usr_handle = usr_handle;
955 up_ptr->ref = p_ptr->publ.ref; 937 up_ptr->ref = p_ptr->ref;
956 up_ptr->err_cb = error_cb; 938 up_ptr->err_cb = error_cb;
957 up_ptr->named_err_cb = named_error_cb; 939 up_ptr->named_err_cb = named_error_cb;
958 up_ptr->conn_err_cb = conn_error_cb; 940 up_ptr->conn_err_cb = conn_error_cb;
@@ -960,26 +942,26 @@ int tipc_createport(void *usr_handle,
960 up_ptr->named_msg_cb = named_msg_cb; 942 up_ptr->named_msg_cb = named_msg_cb;
961 up_ptr->conn_msg_cb = conn_msg_cb; 943 up_ptr->conn_msg_cb = conn_msg_cb;
962 up_ptr->continue_event_cb = continue_event_cb; 944 up_ptr->continue_event_cb = continue_event_cb;
963 *portref = p_ptr->publ.ref; 945 *portref = p_ptr->ref;
964 tipc_port_unlock(p_ptr); 946 tipc_port_unlock(p_ptr);
965 return 0; 947 return 0;
966} 948}
967 949
968int tipc_portimportance(u32 ref, unsigned int *importance) 950int tipc_portimportance(u32 ref, unsigned int *importance)
969{ 951{
970 struct port *p_ptr; 952 struct tipc_port *p_ptr;
971 953
972 p_ptr = tipc_port_lock(ref); 954 p_ptr = tipc_port_lock(ref);
973 if (!p_ptr) 955 if (!p_ptr)
974 return -EINVAL; 956 return -EINVAL;
975 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 957 *importance = (unsigned int)msg_importance(&p_ptr->phdr);
976 tipc_port_unlock(p_ptr); 958 tipc_port_unlock(p_ptr);
977 return 0; 959 return 0;
978} 960}
979 961
980int tipc_set_portimportance(u32 ref, unsigned int imp) 962int tipc_set_portimportance(u32 ref, unsigned int imp)
981{ 963{
982 struct port *p_ptr; 964 struct tipc_port *p_ptr;
983 965
984 if (imp > TIPC_CRITICAL_IMPORTANCE) 966 if (imp > TIPC_CRITICAL_IMPORTANCE)
985 return -EINVAL; 967 return -EINVAL;
@@ -987,7 +969,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
987 p_ptr = tipc_port_lock(ref); 969 p_ptr = tipc_port_lock(ref);
988 if (!p_ptr) 970 if (!p_ptr)
989 return -EINVAL; 971 return -EINVAL;
990 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 972 msg_set_importance(&p_ptr->phdr, (u32)imp);
991 tipc_port_unlock(p_ptr); 973 tipc_port_unlock(p_ptr);
992 return 0; 974 return 0;
993} 975}
@@ -995,7 +977,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
995 977
996int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 978int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
997{ 979{
998 struct port *p_ptr; 980 struct tipc_port *p_ptr;
999 struct publication *publ; 981 struct publication *publ;
1000 u32 key; 982 u32 key;
1001 int res = -EINVAL; 983 int res = -EINVAL;
@@ -1004,7 +986,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1004 if (!p_ptr) 986 if (!p_ptr)
1005 return -EINVAL; 987 return -EINVAL;
1006 988
1007 if (p_ptr->publ.connected) 989 if (p_ptr->connected)
1008 goto exit; 990 goto exit;
1009 if (seq->lower > seq->upper) 991 if (seq->lower > seq->upper)
1010 goto exit; 992 goto exit;
@@ -1016,11 +998,11 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1016 goto exit; 998 goto exit;
1017 } 999 }
1018 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 1000 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
1019 scope, p_ptr->publ.ref, key); 1001 scope, p_ptr->ref, key);
1020 if (publ) { 1002 if (publ) {
1021 list_add(&publ->pport_list, &p_ptr->publications); 1003 list_add(&publ->pport_list, &p_ptr->publications);
1022 p_ptr->pub_count++; 1004 p_ptr->pub_count++;
1023 p_ptr->publ.published = 1; 1005 p_ptr->published = 1;
1024 res = 0; 1006 res = 0;
1025 } 1007 }
1026exit: 1008exit:
@@ -1030,7 +1012,7 @@ exit:
1030 1012
1031int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 1013int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1032{ 1014{
1033 struct port *p_ptr; 1015 struct tipc_port *p_ptr;
1034 struct publication *publ; 1016 struct publication *publ;
1035 struct publication *tpubl; 1017 struct publication *tpubl;
1036 int res = -EINVAL; 1018 int res = -EINVAL;
@@ -1063,37 +1045,37 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1063 } 1045 }
1064 } 1046 }
1065 if (list_empty(&p_ptr->publications)) 1047 if (list_empty(&p_ptr->publications))
1066 p_ptr->publ.published = 0; 1048 p_ptr->published = 0;
1067 tipc_port_unlock(p_ptr); 1049 tipc_port_unlock(p_ptr);
1068 return res; 1050 return res;
1069} 1051}
1070 1052
1071int tipc_connect2port(u32 ref, struct tipc_portid const *peer) 1053int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1072{ 1054{
1073 struct port *p_ptr; 1055 struct tipc_port *p_ptr;
1074 struct tipc_msg *msg; 1056 struct tipc_msg *msg;
1075 int res = -EINVAL; 1057 int res = -EINVAL;
1076 1058
1077 p_ptr = tipc_port_lock(ref); 1059 p_ptr = tipc_port_lock(ref);
1078 if (!p_ptr) 1060 if (!p_ptr)
1079 return -EINVAL; 1061 return -EINVAL;
1080 if (p_ptr->publ.published || p_ptr->publ.connected) 1062 if (p_ptr->published || p_ptr->connected)
1081 goto exit; 1063 goto exit;
1082 if (!peer->ref) 1064 if (!peer->ref)
1083 goto exit; 1065 goto exit;
1084 1066
1085 msg = &p_ptr->publ.phdr; 1067 msg = &p_ptr->phdr;
1086 msg_set_destnode(msg, peer->node); 1068 msg_set_destnode(msg, peer->node);
1087 msg_set_destport(msg, peer->ref); 1069 msg_set_destport(msg, peer->ref);
1088 msg_set_orignode(msg, tipc_own_addr); 1070 msg_set_orignode(msg, tipc_own_addr);
1089 msg_set_origport(msg, p_ptr->publ.ref); 1071 msg_set_origport(msg, p_ptr->ref);
1090 msg_set_transp_seqno(msg, 42);
1091 msg_set_type(msg, TIPC_CONN_MSG); 1072 msg_set_type(msg, TIPC_CONN_MSG);
1073 msg_set_lookup_scope(msg, 0);
1092 msg_set_hdr_sz(msg, SHORT_H_SIZE); 1074 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1093 1075
1094 p_ptr->probing_interval = PROBING_INTERVAL; 1076 p_ptr->probing_interval = PROBING_INTERVAL;
1095 p_ptr->probing_state = CONFIRMED; 1077 p_ptr->probing_state = CONFIRMED;
1096 p_ptr->publ.connected = 1; 1078 p_ptr->connected = 1;
1097 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 1079 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
1098 1080
1099 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node, 1081 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
@@ -1102,7 +1084,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1102 res = 0; 1084 res = 0;
1103exit: 1085exit:
1104 tipc_port_unlock(p_ptr); 1086 tipc_port_unlock(p_ptr);
1105 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1087 p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
1106 return res; 1088 return res;
1107} 1089}
1108 1090
@@ -1120,7 +1102,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1120 tp_ptr->connected = 0; 1102 tp_ptr->connected = 0;
1121 /* let timer expire on it's own to avoid deadlock! */ 1103 /* let timer expire on it's own to avoid deadlock! */
1122 tipc_nodesub_unsubscribe( 1104 tipc_nodesub_unsubscribe(
1123 &((struct port *)tp_ptr)->subscription); 1105 &((struct tipc_port *)tp_ptr)->subscription);
1124 res = 0; 1106 res = 0;
1125 } else { 1107 } else {
1126 res = -ENOTCONN; 1108 res = -ENOTCONN;
@@ -1135,7 +1117,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1135 1117
1136int tipc_disconnect(u32 ref) 1118int tipc_disconnect(u32 ref)
1137{ 1119{
1138 struct port *p_ptr; 1120 struct tipc_port *p_ptr;
1139 int res; 1121 int res;
1140 1122
1141 p_ptr = tipc_port_lock(ref); 1123 p_ptr = tipc_port_lock(ref);
@@ -1151,15 +1133,15 @@ int tipc_disconnect(u32 ref)
1151 */ 1133 */
1152int tipc_shutdown(u32 ref) 1134int tipc_shutdown(u32 ref)
1153{ 1135{
1154 struct port *p_ptr; 1136 struct tipc_port *p_ptr;
1155 struct sk_buff *buf = NULL; 1137 struct sk_buff *buf = NULL;
1156 1138
1157 p_ptr = tipc_port_lock(ref); 1139 p_ptr = tipc_port_lock(ref);
1158 if (!p_ptr) 1140 if (!p_ptr)
1159 return -EINVAL; 1141 return -EINVAL;
1160 1142
1161 if (p_ptr->publ.connected) { 1143 if (p_ptr->connected) {
1162 u32 imp = msg_importance(&p_ptr->publ.phdr); 1144 u32 imp = msg_importance(&p_ptr->phdr);
1163 if (imp < TIPC_CRITICAL_IMPORTANCE) 1145 if (imp < TIPC_CRITICAL_IMPORTANCE)
1164 imp++; 1146 imp++;
1165 buf = port_build_proto_msg(port_peerport(p_ptr), 1147 buf = port_build_proto_msg(port_peerport(p_ptr),
@@ -1169,7 +1151,6 @@ int tipc_shutdown(u32 ref)
1169 imp, 1151 imp,
1170 TIPC_CONN_MSG, 1152 TIPC_CONN_MSG,
1171 TIPC_CONN_SHUTDOWN, 1153 TIPC_CONN_SHUTDOWN,
1172 port_out_seqno(p_ptr),
1173 0); 1154 0);
1174 } 1155 }
1175 tipc_port_unlock(p_ptr); 1156 tipc_port_unlock(p_ptr);
@@ -1182,13 +1163,14 @@ int tipc_shutdown(u32 ref)
1182 * message for this node. 1163 * message for this node.
1183 */ 1164 */
1184 1165
1185static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, 1166static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
1186 struct iovec const *msg_sect) 1167 struct iovec const *msg_sect,
1168 unsigned int total_len)
1187{ 1169{
1188 struct sk_buff *buf; 1170 struct sk_buff *buf;
1189 int res; 1171 int res;
1190 1172
1191 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect, 1173 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len,
1192 MAX_MSG_SIZE, !sender->user_port, &buf); 1174 MAX_MSG_SIZE, !sender->user_port, &buf);
1193 if (likely(buf)) 1175 if (likely(buf))
1194 tipc_port_recv_msg(buf); 1176 tipc_port_recv_msg(buf);
@@ -1199,36 +1181,37 @@ static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
1199 * tipc_send - send message sections on connection 1181 * tipc_send - send message sections on connection
1200 */ 1182 */
1201 1183
1202int 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)
1203{ 1186{
1204 struct port *p_ptr; 1187 struct tipc_port *p_ptr;
1205 u32 destnode; 1188 u32 destnode;
1206 int res; 1189 int res;
1207 1190
1208 p_ptr = tipc_port_deref(ref); 1191 p_ptr = tipc_port_deref(ref);
1209 if (!p_ptr || !p_ptr->publ.connected) 1192 if (!p_ptr || !p_ptr->connected)
1210 return -EINVAL; 1193 return -EINVAL;
1211 1194
1212 p_ptr->publ.congested = 1; 1195 p_ptr->congested = 1;
1213 if (!tipc_port_congested(p_ptr)) { 1196 if (!tipc_port_congested(p_ptr)) {
1214 destnode = port_peernode(p_ptr); 1197 destnode = port_peernode(p_ptr);
1215 if (likely(destnode != tipc_own_addr)) 1198 if (likely(destnode != tipc_own_addr))
1216 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,
1217 destnode); 1200 total_len, destnode);
1218 else 1201 else
1219 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);
1220 1204
1221 if (likely(res != -ELINKCONG)) { 1205 if (likely(res != -ELINKCONG)) {
1222 port_incr_out_seqno(p_ptr); 1206 p_ptr->congested = 0;
1223 p_ptr->publ.congested = 0; 1207 if (res > 0)
1224 p_ptr->sent++; 1208 p_ptr->sent++;
1225 return res; 1209 return res;
1226 } 1210 }
1227 } 1211 }
1228 if (port_unreliable(p_ptr)) { 1212 if (port_unreliable(p_ptr)) {
1229 p_ptr->publ.congested = 0; 1213 p_ptr->congested = 0;
1230 /* Just calculate msg length and return */ 1214 return total_len;
1231 return tipc_msg_calc_data_size(msg_sect, num_sect);
1232 } 1215 }
1233 return -ELINKCONG; 1216 return -ELINKCONG;
1234} 1217}
@@ -1238,19 +1221,20 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1238 */ 1221 */
1239 1222
1240int 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,
1241 unsigned int num_sect, struct iovec const *msg_sect) 1224 unsigned int num_sect, struct iovec const *msg_sect,
1225 unsigned int total_len)
1242{ 1226{
1243 struct port *p_ptr; 1227 struct tipc_port *p_ptr;
1244 struct tipc_msg *msg; 1228 struct tipc_msg *msg;
1245 u32 destnode = domain; 1229 u32 destnode = domain;
1246 u32 destport; 1230 u32 destport;
1247 int res; 1231 int res;
1248 1232
1249 p_ptr = tipc_port_deref(ref); 1233 p_ptr = tipc_port_deref(ref);
1250 if (!p_ptr || p_ptr->publ.connected) 1234 if (!p_ptr || p_ptr->connected)
1251 return -EINVAL; 1235 return -EINVAL;
1252 1236
1253 msg = &p_ptr->publ.phdr; 1237 msg = &p_ptr->phdr;
1254 msg_set_type(msg, TIPC_NAMED_MSG); 1238 msg_set_type(msg, TIPC_NAMED_MSG);
1255 msg_set_orignode(msg, tipc_own_addr); 1239 msg_set_orignode(msg, tipc_own_addr);
1256 msg_set_origport(msg, ref); 1240 msg_set_origport(msg, ref);
@@ -1263,21 +1247,25 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1263 msg_set_destport(msg, destport); 1247 msg_set_destport(msg, destport);
1264 1248
1265 if (likely(destport)) { 1249 if (likely(destport)) {
1266 p_ptr->sent++;
1267 if (likely(destnode == tipc_own_addr)) 1250 if (likely(destnode == tipc_own_addr))
1268 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1251 res = tipc_port_recv_sections(p_ptr, num_sect,
1269 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1252 msg_sect, total_len);
1270 destnode); 1253 else
1271 if (likely(res != -ELINKCONG)) 1254 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
1255 num_sect, total_len,
1256 destnode);
1257 if (likely(res != -ELINKCONG)) {
1258 if (res > 0)
1259 p_ptr->sent++;
1272 return res; 1260 return res;
1261 }
1273 if (port_unreliable(p_ptr)) { 1262 if (port_unreliable(p_ptr)) {
1274 /* Just calculate msg length and return */ 1263 return total_len;
1275 return tipc_msg_calc_data_size(msg_sect, num_sect);
1276 } 1264 }
1277 return -ELINKCONG; 1265 return -ELINKCONG;
1278 } 1266 }
1279 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,
1280 TIPC_ERR_NO_NAME); 1268 total_len, TIPC_ERR_NO_NAME);
1281} 1269}
1282 1270
1283/** 1271/**
@@ -1285,32 +1273,39 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1285 */ 1273 */
1286 1274
1287int tipc_send2port(u32 ref, struct tipc_portid const *dest, 1275int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1288 unsigned int num_sect, struct iovec const *msg_sect) 1276 unsigned int num_sect, struct iovec const *msg_sect,
1277 unsigned int total_len)
1289{ 1278{
1290 struct port *p_ptr; 1279 struct tipc_port *p_ptr;
1291 struct tipc_msg *msg; 1280 struct tipc_msg *msg;
1292 int res; 1281 int res;
1293 1282
1294 p_ptr = tipc_port_deref(ref); 1283 p_ptr = tipc_port_deref(ref);
1295 if (!p_ptr || p_ptr->publ.connected) 1284 if (!p_ptr || p_ptr->connected)
1296 return -EINVAL; 1285 return -EINVAL;
1297 1286
1298 msg = &p_ptr->publ.phdr; 1287 msg = &p_ptr->phdr;
1299 msg_set_type(msg, TIPC_DIRECT_MSG); 1288 msg_set_type(msg, TIPC_DIRECT_MSG);
1289 msg_set_lookup_scope(msg, 0);
1300 msg_set_orignode(msg, tipc_own_addr); 1290 msg_set_orignode(msg, tipc_own_addr);
1301 msg_set_origport(msg, ref); 1291 msg_set_origport(msg, ref);
1302 msg_set_destnode(msg, dest->node); 1292 msg_set_destnode(msg, dest->node);
1303 msg_set_destport(msg, dest->ref); 1293 msg_set_destport(msg, dest->ref);
1304 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1294 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1305 p_ptr->sent++; 1295
1306 if (dest->node == tipc_own_addr) 1296 if (dest->node == tipc_own_addr)
1307 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1297 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect,
1308 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node); 1298 total_len);
1309 if (likely(res != -ELINKCONG)) 1299 else
1300 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1301 total_len, dest->node);
1302 if (likely(res != -ELINKCONG)) {
1303 if (res > 0)
1304 p_ptr->sent++;
1310 return res; 1305 return res;
1306 }
1311 if (port_unreliable(p_ptr)) { 1307 if (port_unreliable(p_ptr)) {
1312 /* Just calculate msg length and return */ 1308 return total_len;
1313 return tipc_msg_calc_data_size(msg_sect, num_sect);
1314 } 1309 }
1315 return -ELINKCONG; 1310 return -ELINKCONG;
1316} 1311}
@@ -1322,15 +1317,15 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1322int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, 1317int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1323 struct sk_buff *buf, unsigned int dsz) 1318 struct sk_buff *buf, unsigned int dsz)
1324{ 1319{
1325 struct port *p_ptr; 1320 struct tipc_port *p_ptr;
1326 struct tipc_msg *msg; 1321 struct tipc_msg *msg;
1327 int res; 1322 int res;
1328 1323
1329 p_ptr = (struct port *)tipc_ref_deref(ref); 1324 p_ptr = (struct tipc_port *)tipc_ref_deref(ref);
1330 if (!p_ptr || p_ptr->publ.connected) 1325 if (!p_ptr || p_ptr->connected)
1331 return -EINVAL; 1326 return -EINVAL;
1332 1327
1333 msg = &p_ptr->publ.phdr; 1328 msg = &p_ptr->phdr;
1334 msg_set_type(msg, TIPC_DIRECT_MSG); 1329 msg_set_type(msg, TIPC_DIRECT_MSG);
1335 msg_set_orignode(msg, tipc_own_addr); 1330 msg_set_orignode(msg, tipc_own_addr);
1336 msg_set_origport(msg, ref); 1331 msg_set_origport(msg, ref);
@@ -1343,12 +1338,16 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1343 1338
1344 skb_push(buf, DIR_MSG_H_SIZE); 1339 skb_push(buf, DIR_MSG_H_SIZE);
1345 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1340 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1346 p_ptr->sent++; 1341
1347 if (dest->node == tipc_own_addr) 1342 if (dest->node == tipc_own_addr)
1348 return tipc_port_recv_msg(buf); 1343 res = tipc_port_recv_msg(buf);
1349 res = tipc_send_buf_fast(buf, dest->node); 1344 else
1350 if (likely(res != -ELINKCONG)) 1345 res = tipc_send_buf_fast(buf, dest->node);
1346 if (likely(res != -ELINKCONG)) {
1347 if (res > 0)
1348 p_ptr->sent++;
1351 return res; 1349 return res;
1350 }
1352 if (port_unreliable(p_ptr)) 1351 if (port_unreliable(p_ptr))
1353 return dsz; 1352 return dsz;
1354 return -ELINKCONG; 1353 return -ELINKCONG;
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 8e84b989949c..b9aa34195aec 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -2,7 +2,7 @@
2 * net/tipc/port.h: Include file for TIPC port code 2 * net/tipc/port.h: Include file for TIPC port code
3 * 3 *
4 * Copyright (c) 1994-2007, Ericsson AB 4 * Copyright (c) 1994-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -95,7 +95,7 @@ struct user_port {
95}; 95};
96 96
97/** 97/**
98 * struct tipc_port - TIPC port info available to socket API 98 * struct tipc_port - TIPC port structure
99 * @usr_handle: pointer to additional user-defined information about port 99 * @usr_handle: pointer to additional user-defined information about port
100 * @lock: pointer to spinlock for controlling access to port 100 * @lock: pointer to spinlock for controlling access to port
101 * @connected: non-zero if port is currently connected to a peer port 101 * @connected: non-zero if port is currently connected to a peer port
@@ -107,43 +107,33 @@ struct user_port {
107 * @max_pkt: maximum packet size "hint" used when building messages sent by port 107 * @max_pkt: maximum packet size "hint" used when building messages sent by port
108 * @ref: unique reference to port in TIPC object registry 108 * @ref: unique reference to port in TIPC object registry
109 * @phdr: preformatted message header used when sending messages 109 * @phdr: preformatted message header used when sending messages
110 */
111struct tipc_port {
112 void *usr_handle;
113 spinlock_t *lock;
114 int connected;
115 u32 conn_type;
116 u32 conn_instance;
117 u32 conn_unacked;
118 int published;
119 u32 congested;
120 u32 max_pkt;
121 u32 ref;
122 struct tipc_msg phdr;
123};
124
125/**
126 * struct port - TIPC port structure
127 * @publ: TIPC port info available to privileged users
128 * @port_list: adjacent ports in TIPC's global list of ports 110 * @port_list: adjacent ports in TIPC's global list of ports
129 * @dispatcher: ptr to routine which handles received messages 111 * @dispatcher: ptr to routine which handles received messages
130 * @wakeup: ptr to routine to call when port is no longer congested 112 * @wakeup: ptr to routine to call when port is no longer congested
131 * @user_port: ptr to user port associated with port (if any) 113 * @user_port: ptr to user port associated with port (if any)
132 * @wait_list: adjacent ports in list of ports waiting on link congestion 114 * @wait_list: adjacent ports in list of ports waiting on link congestion
133 * @waiting_pkts: 115 * @waiting_pkts:
134 * @sent: 116 * @sent: # of non-empty messages sent by port
135 * @acked: 117 * @acked: # of non-empty message acknowledgements from connected port's peer
136 * @publications: list of publications for port 118 * @publications: list of publications for port
137 * @pub_count: total # of publications port has made during its lifetime 119 * @pub_count: total # of publications port has made during its lifetime
138 * @probing_state: 120 * @probing_state:
139 * @probing_interval: 121 * @probing_interval:
140 * @last_in_seqno:
141 * @timer_ref: 122 * @timer_ref:
142 * @subscription: "node down" subscription used to terminate failed connections 123 * @subscription: "node down" subscription used to terminate failed connections
143 */ 124 */
144 125struct tipc_port {
145struct port { 126 void *usr_handle;
146 struct tipc_port publ; 127 spinlock_t *lock;
128 int connected;
129 u32 conn_type;
130 u32 conn_instance;
131 u32 conn_unacked;
132 int published;
133 u32 congested;
134 u32 max_pkt;
135 u32 ref;
136 struct tipc_msg phdr;
147 struct list_head port_list; 137 struct list_head port_list;
148 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); 138 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *);
149 void (*wakeup)(struct tipc_port *); 139 void (*wakeup)(struct tipc_port *);
@@ -156,7 +146,6 @@ struct port {
156 u32 pub_count; 146 u32 pub_count;
157 u32 probing_state; 147 u32 probing_state;
158 u32 probing_interval; 148 u32 probing_interval;
159 u32 last_in_seqno;
160 struct timer_list timer; 149 struct timer_list timer;
161 struct tipc_node_subscr subscription; 150 struct tipc_node_subscr subscription;
162}; 151};
@@ -216,23 +205,27 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr);
216/* 205/*
217 * TIPC messaging routines 206 * TIPC messaging routines
218 */ 207 */
219int 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);
220 210
221int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, 211int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
222 unsigned int num_sect, struct iovec const *msg_sect); 212 unsigned int num_sect, struct iovec const *msg_sect,
213 unsigned int total_len);
223 214
224int tipc_send2port(u32 portref, struct tipc_portid const *dest, 215int tipc_send2port(u32 portref, struct tipc_portid const *dest,
225 unsigned int num_sect, struct iovec const *msg_sect); 216 unsigned int num_sect, struct iovec const *msg_sect,
217 unsigned int total_len);
226 218
227int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, 219int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
228 struct sk_buff *buf, unsigned int dsz); 220 struct sk_buff *buf, unsigned int dsz);
229 221
230int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, 222int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
231 unsigned int section_count, struct iovec const *msg); 223 unsigned int section_count, struct iovec const *msg,
224 unsigned int total_len);
232 225
233int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 226int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
234 struct iovec const *msg_sect, u32 num_sect, 227 struct iovec const *msg_sect, u32 num_sect,
235 int err); 228 unsigned int total_len, int err);
236struct sk_buff *tipc_port_get_ports(void); 229struct sk_buff *tipc_port_get_ports(void);
237void tipc_port_recv_proto_msg(struct sk_buff *buf); 230void tipc_port_recv_proto_msg(struct sk_buff *buf);
238void 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);
@@ -242,9 +235,9 @@ void tipc_port_reinit(void);
242 * tipc_port_lock - lock port instance referred to and return its pointer 235 * tipc_port_lock - lock port instance referred to and return its pointer
243 */ 236 */
244 237
245static inline struct port *tipc_port_lock(u32 ref) 238static inline struct tipc_port *tipc_port_lock(u32 ref)
246{ 239{
247 return (struct port *)tipc_ref_lock(ref); 240 return (struct tipc_port *)tipc_ref_lock(ref);
248} 241}
249 242
250/** 243/**
@@ -253,27 +246,27 @@ static inline struct port *tipc_port_lock(u32 ref)
253 * Can use pointer instead of tipc_ref_unlock() since port is already locked. 246 * Can use pointer instead of tipc_ref_unlock() since port is already locked.
254 */ 247 */
255 248
256static inline void tipc_port_unlock(struct port *p_ptr) 249static inline void tipc_port_unlock(struct tipc_port *p_ptr)
257{ 250{
258 spin_unlock_bh(p_ptr->publ.lock); 251 spin_unlock_bh(p_ptr->lock);
259} 252}
260 253
261static inline struct port *tipc_port_deref(u32 ref) 254static inline struct tipc_port *tipc_port_deref(u32 ref)
262{ 255{
263 return (struct port *)tipc_ref_deref(ref); 256 return (struct tipc_port *)tipc_ref_deref(ref);
264} 257}
265 258
266static inline u32 tipc_peer_port(struct port *p_ptr) 259static inline u32 tipc_peer_port(struct tipc_port *p_ptr)
267{ 260{
268 return msg_destport(&p_ptr->publ.phdr); 261 return msg_destport(&p_ptr->phdr);
269} 262}
270 263
271static inline u32 tipc_peer_node(struct port *p_ptr) 264static inline u32 tipc_peer_node(struct tipc_port *p_ptr)
272{ 265{
273 return msg_destnode(&p_ptr->publ.phdr); 266 return msg_destnode(&p_ptr->phdr);
274} 267}
275 268
276static inline int tipc_port_congested(struct port *p_ptr) 269static inline int tipc_port_congested(struct tipc_port *p_ptr)
277{ 270{
278 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); 271 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
279} 272}
@@ -284,7 +277,7 @@ static inline int tipc_port_congested(struct port *p_ptr)
284 277
285static inline int tipc_port_recv_msg(struct sk_buff *buf) 278static inline int tipc_port_recv_msg(struct sk_buff *buf)
286{ 279{
287 struct port *p_ptr; 280 struct tipc_port *p_ptr;
288 struct tipc_msg *msg = buf_msg(buf); 281 struct tipc_msg *msg = buf_msg(buf);
289 u32 destport = msg_destport(msg); 282 u32 destport = msg_destport(msg);
290 u32 dsz = msg_data_sz(msg); 283 u32 dsz = msg_data_sz(msg);
@@ -299,7 +292,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
299 /* validate destination & pass to port, otherwise reject message */ 292 /* validate destination & pass to port, otherwise reject message */
300 p_ptr = tipc_port_lock(destport); 293 p_ptr = tipc_port_lock(destport);
301 if (likely(p_ptr)) { 294 if (likely(p_ptr)) {
302 if (likely(p_ptr->publ.connected)) { 295 if (likely(p_ptr->connected)) {
303 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) || 296 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
304 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) || 297 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
305 (unlikely(!msg_connected(msg)))) { 298 (unlikely(!msg_connected(msg)))) {
@@ -308,7 +301,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
308 goto reject; 301 goto reject;
309 } 302 }
310 } 303 }
311 err = p_ptr->dispatcher(&p_ptr->publ, buf); 304 err = p_ptr->dispatcher(p_ptr, buf);
312 tipc_port_unlock(p_ptr); 305 tipc_port_unlock(p_ptr);
313 if (likely(!err)) 306 if (likely(!err))
314 return dsz; 307 return dsz;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 2b02a3a80313..338837396642 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2,7 +2,7 @@
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,9 @@ struct tipc_sock {
58#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 58#define tipc_sk(sk) ((struct tipc_sock *)(sk))
59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) 59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p))
60 60
61#define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \
62 (sock->state == SS_DISCONNECTING))
63
61static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 64static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
62static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 65static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
63static void wakeupdispatch(struct tipc_port *tport); 66static void wakeupdispatch(struct tipc_port *tport);
@@ -241,7 +244,6 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
241 tipc_set_portunreliable(tp_ptr->ref, 1); 244 tipc_set_portunreliable(tp_ptr->ref, 1);
242 } 245 }
243 246
244 atomic_inc(&tipc_user_count);
245 return 0; 247 return 0;
246} 248}
247 249
@@ -290,7 +292,7 @@ static int release(struct socket *sock)
290 if (buf == NULL) 292 if (buf == NULL)
291 break; 293 break;
292 atomic_dec(&tipc_queue_size); 294 atomic_dec(&tipc_queue_size);
293 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) 295 if (TIPC_SKB_CB(buf)->handle != 0)
294 buf_discard(buf); 296 buf_discard(buf);
295 else { 297 else {
296 if ((sock->state == SS_CONNECTING) || 298 if ((sock->state == SS_CONNECTING) ||
@@ -321,7 +323,6 @@ static int release(struct socket *sock)
321 sock_put(sk); 323 sock_put(sk);
322 sock->sk = NULL; 324 sock->sk = NULL;
323 325
324 atomic_dec(&tipc_user_count);
325 return res; 326 return res;
326} 327}
327 328
@@ -495,6 +496,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
495 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) 496 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV))
496 return -EACCES; 497 return -EACCES;
497 498
499 if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr)))
500 return -EMSGSIZE;
498 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) 501 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr)))
499 return -EFAULT; 502 return -EFAULT;
500 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) 503 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN)))
@@ -532,6 +535,9 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
532 if (unlikely((m->msg_namelen < sizeof(*dest)) || 535 if (unlikely((m->msg_namelen < sizeof(*dest)) ||
533 (dest->family != AF_TIPC))) 536 (dest->family != AF_TIPC)))
534 return -EINVAL; 537 return -EINVAL;
538 if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
539 (m->msg_iovlen > (unsigned)INT_MAX))
540 return -EMSGSIZE;
535 541
536 if (iocb) 542 if (iocb)
537 lock_sock(sk); 543 lock_sock(sk);
@@ -570,12 +576,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
570 &dest->addr.name.name, 576 &dest->addr.name.name,
571 dest->addr.name.domain, 577 dest->addr.name.domain,
572 m->msg_iovlen, 578 m->msg_iovlen,
573 m->msg_iov); 579 m->msg_iov,
580 total_len);
574 } else if (dest->addrtype == TIPC_ADDR_ID) { 581 } else if (dest->addrtype == TIPC_ADDR_ID) {
575 res = tipc_send2port(tport->ref, 582 res = tipc_send2port(tport->ref,
576 &dest->addr.id, 583 &dest->addr.id,
577 m->msg_iovlen, 584 m->msg_iovlen,
578 m->msg_iov); 585 m->msg_iov,
586 total_len);
579 } else if (dest->addrtype == TIPC_ADDR_MCAST) { 587 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
580 if (needs_conn) { 588 if (needs_conn) {
581 res = -EOPNOTSUPP; 589 res = -EOPNOTSUPP;
@@ -587,7 +595,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
587 res = tipc_multicast(tport->ref, 595 res = tipc_multicast(tport->ref,
588 &dest->addr.nameseq, 596 &dest->addr.nameseq,
589 m->msg_iovlen, 597 m->msg_iovlen,
590 m->msg_iov); 598 m->msg_iov,
599 total_len);
591 } 600 }
592 if (likely(res != -ELINKCONG)) { 601 if (likely(res != -ELINKCONG)) {
593 if (needs_conn && (res >= 0)) 602 if (needs_conn && (res >= 0))
@@ -637,6 +646,10 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
637 if (unlikely(dest)) 646 if (unlikely(dest))
638 return send_msg(iocb, sock, m, total_len); 647 return send_msg(iocb, sock, m, total_len);
639 648
649 if ((total_len > TIPC_MAX_USER_MSG_SIZE) ||
650 (m->msg_iovlen > (unsigned)INT_MAX))
651 return -EMSGSIZE;
652
640 if (iocb) 653 if (iocb)
641 lock_sock(sk); 654 lock_sock(sk);
642 655
@@ -649,7 +662,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
649 break; 662 break;
650 } 663 }
651 664
652 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);
653 if (likely(res != -ELINKCONG)) 667 if (likely(res != -ELINKCONG))
654 break; 668 break;
655 if (m->msg_flags & MSG_DONTWAIT) { 669 if (m->msg_flags & MSG_DONTWAIT) {
@@ -720,6 +734,12 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
720 goto exit; 734 goto exit;
721 } 735 }
722 736
737 if ((total_len > (unsigned)INT_MAX) ||
738 (m->msg_iovlen > (unsigned)INT_MAX)) {
739 res = -EMSGSIZE;
740 goto exit;
741 }
742
723 /* 743 /*
724 * Send each iovec entry using one or more messages 744 * Send each iovec entry using one or more messages
725 * 745 *
@@ -750,7 +770,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
750 bytes_to_send = curr_left; 770 bytes_to_send = curr_left;
751 my_iov.iov_base = curr_start; 771 my_iov.iov_base = curr_start;
752 my_iov.iov_len = bytes_to_send; 772 my_iov.iov_len = bytes_to_send;
753 res = send_packet(NULL, sock, &my_msg, 0); 773 res = send_packet(NULL, sock, &my_msg, bytes_to_send);
754 if (res < 0) { 774 if (res < 0) {
755 if (bytes_sent) 775 if (bytes_sent)
756 res = bytes_sent; 776 res = bytes_sent;
@@ -911,15 +931,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
911 struct tipc_port *tport = tipc_sk_port(sk); 931 struct tipc_port *tport = tipc_sk_port(sk);
912 struct sk_buff *buf; 932 struct sk_buff *buf;
913 struct tipc_msg *msg; 933 struct tipc_msg *msg;
934 long timeout;
914 unsigned int sz; 935 unsigned int sz;
915 u32 err; 936 u32 err;
916 int res; 937 int res;
917 938
918 /* Catch invalid receive requests */ 939 /* Catch invalid receive requests */
919 940
920 if (m->msg_iovlen != 1)
921 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
922
923 if (unlikely(!buf_len)) 941 if (unlikely(!buf_len))
924 return -EINVAL; 942 return -EINVAL;
925 943
@@ -930,6 +948,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
930 goto exit; 948 goto exit;
931 } 949 }
932 950
951 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
933restart: 952restart:
934 953
935 /* Look for a message in receive queue; wait if necessary */ 954 /* Look for a message in receive queue; wait if necessary */
@@ -939,17 +958,15 @@ restart:
939 res = -ENOTCONN; 958 res = -ENOTCONN;
940 goto exit; 959 goto exit;
941 } 960 }
942 if (flags & MSG_DONTWAIT) { 961 if (timeout <= 0L) {
943 res = -EWOULDBLOCK; 962 res = timeout ? timeout : -EWOULDBLOCK;
944 goto exit; 963 goto exit;
945 } 964 }
946 release_sock(sk); 965 release_sock(sk);
947 res = wait_event_interruptible(*sk_sleep(sk), 966 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
948 (!skb_queue_empty(&sk->sk_receive_queue) || 967 tipc_rx_ready(sock),
949 (sock->state == SS_DISCONNECTING))); 968 timeout);
950 lock_sock(sk); 969 lock_sock(sk);
951 if (res)
952 goto exit;
953 } 970 }
954 971
955 /* Look at first message in receive queue */ 972 /* Look at first message in receive queue */
@@ -991,11 +1008,10 @@ restart:
991 sz = buf_len; 1008 sz = buf_len;
992 m->msg_flags |= MSG_TRUNC; 1009 m->msg_flags |= MSG_TRUNC;
993 } 1010 }
994 if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), 1011 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
995 sz))) { 1012 m->msg_iov, sz);
996 res = -EFAULT; 1013 if (res)
997 goto exit; 1014 goto exit;
998 }
999 res = sz; 1015 res = sz;
1000 } else { 1016 } else {
1001 if ((sock->state == SS_READY) || 1017 if ((sock->state == SS_READY) ||
@@ -1038,19 +1054,15 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1038 struct tipc_port *tport = tipc_sk_port(sk); 1054 struct tipc_port *tport = tipc_sk_port(sk);
1039 struct sk_buff *buf; 1055 struct sk_buff *buf;
1040 struct tipc_msg *msg; 1056 struct tipc_msg *msg;
1057 long timeout;
1041 unsigned int sz; 1058 unsigned int sz;
1042 int sz_to_copy, target, needed; 1059 int sz_to_copy, target, needed;
1043 int sz_copied = 0; 1060 int sz_copied = 0;
1044 char __user *crs = m->msg_iov->iov_base;
1045 unsigned char *buf_crs;
1046 u32 err; 1061 u32 err;
1047 int res = 0; 1062 int res = 0;
1048 1063
1049 /* Catch invalid receive attempts */ 1064 /* Catch invalid receive attempts */
1050 1065
1051 if (m->msg_iovlen != 1)
1052 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
1053
1054 if (unlikely(!buf_len)) 1066 if (unlikely(!buf_len))
1055 return -EINVAL; 1067 return -EINVAL;
1056 1068
@@ -1063,7 +1075,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1063 } 1075 }
1064 1076
1065 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1077 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1066 1078 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1067restart: 1079restart:
1068 1080
1069 /* Look for a message in receive queue; wait if necessary */ 1081 /* Look for a message in receive queue; wait if necessary */
@@ -1073,17 +1085,15 @@ restart:
1073 res = -ENOTCONN; 1085 res = -ENOTCONN;
1074 goto exit; 1086 goto exit;
1075 } 1087 }
1076 if (flags & MSG_DONTWAIT) { 1088 if (timeout <= 0L) {
1077 res = -EWOULDBLOCK; 1089 res = timeout ? timeout : -EWOULDBLOCK;
1078 goto exit; 1090 goto exit;
1079 } 1091 }
1080 release_sock(sk); 1092 release_sock(sk);
1081 res = wait_event_interruptible(*sk_sleep(sk), 1093 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1082 (!skb_queue_empty(&sk->sk_receive_queue) || 1094 tipc_rx_ready(sock),
1083 (sock->state == SS_DISCONNECTING))); 1095 timeout);
1084 lock_sock(sk); 1096 lock_sock(sk);
1085 if (res)
1086 goto exit;
1087 } 1097 }
1088 1098
1089 /* Look at first message in receive queue */ 1099 /* Look at first message in receive queue */
@@ -1112,24 +1122,25 @@ restart:
1112 /* Capture message data (if valid) & compute return value (always) */ 1122 /* Capture message data (if valid) & compute return value (always) */
1113 1123
1114 if (!err) { 1124 if (!err) {
1115 buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); 1125 u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
1116 sz = (unsigned char *)msg + msg_size(msg) - buf_crs;
1117 1126
1127 sz -= offset;
1118 needed = (buf_len - sz_copied); 1128 needed = (buf_len - sz_copied);
1119 sz_to_copy = (sz <= needed) ? sz : needed; 1129 sz_to_copy = (sz <= needed) ? sz : needed;
1120 if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { 1130
1121 res = -EFAULT; 1131 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
1132 m->msg_iov, sz_to_copy);
1133 if (res)
1122 goto exit; 1134 goto exit;
1123 } 1135
1124 sz_copied += sz_to_copy; 1136 sz_copied += sz_to_copy;
1125 1137
1126 if (sz_to_copy < sz) { 1138 if (sz_to_copy < sz) {
1127 if (!(flags & MSG_PEEK)) 1139 if (!(flags & MSG_PEEK))
1128 TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; 1140 TIPC_SKB_CB(buf)->handle =
1141 (void *)(unsigned long)(offset + sz_to_copy);
1129 goto exit; 1142 goto exit;
1130 } 1143 }
1131
1132 crs += sz_to_copy;
1133 } else { 1144 } else {
1134 if (sz_copied != 0) 1145 if (sz_copied != 0)
1135 goto exit; /* can't add error msg to valid data */ 1146 goto exit; /* can't add error msg to valid data */
@@ -1256,7 +1267,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1256 1267
1257 /* Enqueue message (finally!) */ 1268 /* Enqueue message (finally!) */
1258 1269
1259 TIPC_SKB_CB(buf)->handle = msg_data(msg); 1270 TIPC_SKB_CB(buf)->handle = 0;
1260 atomic_inc(&tipc_queue_size); 1271 atomic_inc(&tipc_queue_size);
1261 __skb_queue_tail(&sk->sk_receive_queue, buf); 1272 __skb_queue_tail(&sk->sk_receive_queue, buf);
1262 1273
@@ -1608,7 +1619,7 @@ restart:
1608 buf = __skb_dequeue(&sk->sk_receive_queue); 1619 buf = __skb_dequeue(&sk->sk_receive_queue);
1609 if (buf) { 1620 if (buf) {
1610 atomic_dec(&tipc_queue_size); 1621 atomic_dec(&tipc_queue_size);
1611 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { 1622 if (TIPC_SKB_CB(buf)->handle != 0) {
1612 buf_discard(buf); 1623 buf_discard(buf);
1613 goto restart; 1624 goto restart;
1614 } 1625 }
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index ca04479c3d42..6cf726863485 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -2,7 +2,7 @@
2 * net/tipc/subscr.c: TIPC network topology service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -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/**
@@ -160,7 +160,7 @@ void tipc_subscr_report_overlap(struct subscription *sub,
160 160
161static void subscr_timeout(struct subscription *sub) 161static void subscr_timeout(struct subscription *sub)
162{ 162{
163 struct port *server_port; 163 struct tipc_port *server_port;
164 164
165 /* Validate server port reference (in case subscriber is terminating) */ 165 /* Validate server port reference (in case subscriber is terminating) */
166 166
@@ -472,8 +472,6 @@ static void subscr_named_msg_event(void *usr_handle,
472 struct tipc_portid const *orig, 472 struct tipc_portid const *orig,
473 struct tipc_name_seq const *dest) 473 struct tipc_name_seq const *dest)
474{ 474{
475 static struct iovec msg_sect = {NULL, 0};
476
477 struct subscriber *subscriber; 475 struct subscriber *subscriber;
478 u32 server_port_ref; 476 u32 server_port_ref;
479 477
@@ -508,7 +506,7 @@ static void subscr_named_msg_event(void *usr_handle,
508 506
509 /* Lock server port (& save lock address for future use) */ 507 /* Lock server port (& save lock address for future use) */
510 508
511 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock; 509 subscriber->lock = tipc_port_lock(subscriber->port_ref)->lock;
512 510
513 /* Add subscriber to topology server's subscriber list */ 511 /* Add subscriber to topology server's subscriber list */
514 512
@@ -523,7 +521,7 @@ static void subscr_named_msg_event(void *usr_handle,
523 521
524 /* Send an ACK- to complete connection handshaking */ 522 /* Send an ACK- to complete connection handshaking */
525 523
526 tipc_send(server_port_ref, 1, &msg_sect); 524 tipc_send(server_port_ref, 0, NULL, 0);
527 525
528 /* Handle optional subscription request */ 526 /* Handle optional subscription request */
529 527
@@ -542,7 +540,6 @@ int tipc_subscr_start(void)
542 spin_lock_init(&topsrv.lock); 540 spin_lock_init(&topsrv.lock);
543 INIT_LIST_HEAD(&topsrv.subscriber_list); 541 INIT_LIST_HEAD(&topsrv.subscriber_list);
544 542
545 spin_lock_bh(&topsrv.lock);
546 res = tipc_createport(NULL, 543 res = tipc_createport(NULL,
547 TIPC_CRITICAL_IMPORTANCE, 544 TIPC_CRITICAL_IMPORTANCE,
548 NULL, 545 NULL,
@@ -563,12 +560,10 @@ int tipc_subscr_start(void)
563 goto failed; 560 goto failed;
564 } 561 }
565 562
566 spin_unlock_bh(&topsrv.lock);
567 return 0; 563 return 0;
568 564
569failed: 565failed:
570 err("Failed to create subscription service\n"); 566 err("Failed to create subscription service\n");
571 spin_unlock_bh(&topsrv.lock);
572 return res; 567 return res;
573} 568}
574 569