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.h17
-rw-r--r--net/tipc/bcast.c47
-rw-r--r--net/tipc/bcast.h3
-rw-r--r--net/tipc/bearer.c116
-rw-r--r--net/tipc/bearer.h73
-rw-r--r--net/tipc/config.c31
-rw-r--r--net/tipc/core.c9
-rw-r--r--net/tipc/core.h4
-rw-r--r--net/tipc/discover.c140
-rw-r--r--net/tipc/discover.h9
-rw-r--r--net/tipc/link.c132
-rw-r--r--net/tipc/link.h29
-rw-r--r--net/tipc/msg.c41
-rw-r--r--net/tipc/msg.h64
-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.c306
-rw-r--r--net/tipc/port.h73
-rw-r--r--net/tipc/socket.c76
-rw-r--r--net/tipc/subscr.c13
27 files changed, 646 insertions, 820 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..8971aba99aea 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -37,6 +37,16 @@
37#ifndef _TIPC_ADDR_H 37#ifndef _TIPC_ADDR_H
38#define _TIPC_ADDR_H 38#define _TIPC_ADDR_H
39 39
40static inline u32 tipc_zone_mask(u32 addr)
41{
42 return addr & 0xff000000u;
43}
44
45static inline u32 tipc_cluster_mask(u32 addr)
46{
47 return addr & 0xfffff000u;
48}
49
40static inline int in_own_cluster(u32 addr) 50static inline int in_own_cluster(u32 addr)
41{ 51{
42 return !((addr ^ tipc_own_addr) >> 12); 52 return !((addr ^ tipc_own_addr) >> 12);
@@ -49,14 +59,13 @@ static inline int in_own_cluster(u32 addr)
49 * after a network hop. 59 * after a network hop.
50 */ 60 */
51 61
52static inline int addr_domain(int sc) 62static inline u32 addr_domain(u32 sc)
53{ 63{
54 if (likely(sc == TIPC_NODE_SCOPE)) 64 if (likely(sc == TIPC_NODE_SCOPE))
55 return tipc_own_addr; 65 return tipc_own_addr;
56 if (sc == TIPC_CLUSTER_SCOPE) 66 if (sc == TIPC_CLUSTER_SCOPE)
57 return tipc_addr(tipc_zone(tipc_own_addr), 67 return tipc_cluster_mask(tipc_own_addr);
58 tipc_cluster(tipc_own_addr), 0); 68 return tipc_zone_mask(tipc_own_addr);
59 return tipc_addr(tipc_zone(tipc_own_addr), 0, 0);
60} 69}
61 70
62int tipc_addr_domain_valid(u32); 71int tipc_addr_domain_valid(u32);
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 70ab5ef48766..7dc1dc7151ea 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
@@ -61,8 +61,8 @@
61 */ 61 */
62 62
63struct bcbearer_pair { 63struct bcbearer_pair {
64 struct bearer *primary; 64 struct tipc_bearer *primary;
65 struct bearer *secondary; 65 struct tipc_bearer *secondary;
66}; 66};
67 67
68/** 68/**
@@ -81,7 +81,7 @@ struct bcbearer_pair {
81 */ 81 */
82 82
83struct bcbearer { 83struct bcbearer {
84 struct bearer bearer; 84 struct tipc_bearer bearer;
85 struct media media; 85 struct media media;
86 struct bcbearer_pair bpairs[MAX_BEARERS]; 86 struct bcbearer_pair bpairs[MAX_BEARERS];
87 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 87 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
@@ -93,6 +93,7 @@ struct bcbearer {
93 * struct bclink - link used for broadcast messages 93 * struct bclink - link used for broadcast messages
94 * @link: (non-standard) broadcast link structure 94 * @link: (non-standard) broadcast link structure
95 * @node: (non-standard) node structure representing b'cast link's peer node 95 * @node: (non-standard) node structure representing b'cast link's peer node
96 * @retransmit_to: node that most recently requested a retransmit
96 * 97 *
97 * Handles sequence numbering, fragmentation, bundling, etc. 98 * Handles sequence numbering, fragmentation, bundling, etc.
98 */ 99 */
@@ -100,6 +101,7 @@ struct bcbearer {
100struct bclink { 101struct bclink {
101 struct link link; 102 struct link link;
102 struct tipc_node node; 103 struct tipc_node node;
104 struct tipc_node *retransmit_to;
103}; 105};
104 106
105 107
@@ -184,6 +186,17 @@ static int bclink_ack_allowed(u32 n)
184 186
185 187
186/** 188/**
189 * tipc_bclink_retransmit_to - get most recent node to request retransmission
190 *
191 * Called with bc_lock locked
192 */
193
194struct tipc_node *tipc_bclink_retransmit_to(void)
195{
196 return bclink->retransmit_to;
197}
198
199/**
187 * bclink_retransmit_pkt - retransmit broadcast packets 200 * bclink_retransmit_pkt - retransmit broadcast packets
188 * @after: sequence number of last packet to *not* retransmit 201 * @after: sequence number of last packet to *not* retransmit
189 * @to: sequence number of last packet to retransmit 202 * @to: sequence number of last packet to retransmit
@@ -285,6 +298,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr)
285 msg = buf_msg(buf); 298 msg = buf_msg(buf);
286 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 299 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
287 INT_H_SIZE, n_ptr->addr); 300 INT_H_SIZE, n_ptr->addr);
301 msg_set_non_seq(msg, 1);
288 msg_set_mc_netid(msg, tipc_net_id); 302 msg_set_mc_netid(msg, tipc_net_id);
289 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 303 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
290 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 304 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -405,8 +419,6 @@ int tipc_bclink_send_msg(struct sk_buff *buf)
405 else 419 else
406 bclink_set_last_sent(); 420 bclink_set_last_sent();
407 421
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++; 422 bcl->stats.queue_sz_counts++;
411 bcl->stats.accu_queue_sz += bcl->out_queue_size; 423 bcl->stats.accu_queue_sz += bcl->out_queue_size;
412 424
@@ -444,10 +456,9 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
444 tipc_node_unlock(node); 456 tipc_node_unlock(node);
445 spin_lock_bh(&bc_lock); 457 spin_lock_bh(&bc_lock);
446 bcl->stats.recv_nacks++; 458 bcl->stats.recv_nacks++;
447 bcl->owner->next = node; /* remember requestor */ 459 bclink->retransmit_to = node;
448 bclink_retransmit_pkt(msg_bcgap_after(msg), 460 bclink_retransmit_pkt(msg_bcgap_after(msg),
449 msg_bcgap_to(msg)); 461 msg_bcgap_to(msg));
450 bcl->owner->next = NULL;
451 spin_unlock_bh(&bc_lock); 462 spin_unlock_bh(&bc_lock);
452 } else { 463 } else {
453 tipc_bclink_peek_nack(msg_destnode(msg), 464 tipc_bclink_peek_nack(msg_destnode(msg),
@@ -574,8 +585,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
574 bcbearer->remains = tipc_bcast_nmap; 585 bcbearer->remains = tipc_bcast_nmap;
575 586
576 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 587 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
577 struct bearer *p = bcbearer->bpairs[bp_index].primary; 588 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
578 struct bearer *s = bcbearer->bpairs[bp_index].secondary; 589 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary;
579 590
580 if (!p) 591 if (!p)
581 break; /* no more bearers to try */ 592 break; /* no more bearers to try */
@@ -584,11 +595,11 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
584 if (bcbearer->remains_new.count == bcbearer->remains.count) 595 if (bcbearer->remains_new.count == bcbearer->remains.count)
585 continue; /* bearer pair doesn't add anything */ 596 continue; /* bearer pair doesn't add anything */
586 597
587 if (p->publ.blocked || 598 if (p->blocked ||
588 p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { 599 p->media->send_msg(buf, p, &p->media->bcast_addr)) {
589 /* unable to send on primary bearer */ 600 /* unable to send on primary bearer */
590 if (!s || s->publ.blocked || 601 if (!s || s->blocked ||
591 s->media->send_msg(buf, &s->publ, 602 s->media->send_msg(buf, s,
592 &s->media->bcast_addr)) { 603 &s->media->bcast_addr)) {
593 /* unable to send on either bearer */ 604 /* unable to send on either bearer */
594 continue; 605 continue;
@@ -633,7 +644,7 @@ void tipc_bcbearer_sort(void)
633 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); 644 memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
634 645
635 for (b_index = 0; b_index < MAX_BEARERS; b_index++) { 646 for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
636 struct bearer *b = &tipc_bearers[b_index]; 647 struct tipc_bearer *b = &tipc_bearers[b_index];
637 648
638 if (!b->active || !b->nodes.count) 649 if (!b->active || !b->nodes.count)
639 continue; 650 continue;
@@ -682,12 +693,12 @@ void tipc_bcbearer_sort(void)
682 693
683void tipc_bcbearer_push(void) 694void tipc_bcbearer_push(void)
684{ 695{
685 struct bearer *b_ptr; 696 struct tipc_bearer *b_ptr;
686 697
687 spin_lock_bh(&bc_lock); 698 spin_lock_bh(&bc_lock);
688 b_ptr = &bcbearer->bearer; 699 b_ptr = &bcbearer->bearer;
689 if (b_ptr->publ.blocked) { 700 if (b_ptr->blocked) {
690 b_ptr->publ.blocked = 0; 701 b_ptr->blocked = 0;
691 tipc_bearer_lock_push(b_ptr); 702 tipc_bearer_lock_push(b_ptr);
692 } 703 }
693 spin_unlock_bh(&bc_lock); 704 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..411719feb803 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,7 @@
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 48
49/** 49/**
50 * media_name_valid - validate media name 50 * media_name_valid - validate media name
@@ -158,7 +158,6 @@ int tipc_register_media(u32 media_type,
158 m_ptr->disable_bearer = disable; 158 m_ptr->disable_bearer = disable;
159 m_ptr->addr2str = addr2str; 159 m_ptr->addr2str = addr2str;
160 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); 160 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr));
161 m_ptr->bcast = 1;
162 strcpy(m_ptr->name, name); 161 strcpy(m_ptr->name, name);
163 m_ptr->priority = bearer_priority; 162 m_ptr->priority = bearer_priority;
164 m_ptr->tolerance = link_tolerance; 163 m_ptr->tolerance = link_tolerance;
@@ -278,13 +277,13 @@ static int bearer_name_validate(const char *name,
278 * bearer_find - locates bearer object with matching bearer name 277 * bearer_find - locates bearer object with matching bearer name
279 */ 278 */
280 279
281static struct bearer *bearer_find(const char *name) 280static struct tipc_bearer *bearer_find(const char *name)
282{ 281{
283 struct bearer *b_ptr; 282 struct tipc_bearer *b_ptr;
284 u32 i; 283 u32 i;
285 284
286 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 285 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
287 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) 286 if (b_ptr->active && (!strcmp(b_ptr->name, name)))
288 return b_ptr; 287 return b_ptr;
289 } 288 }
290 return NULL; 289 return NULL;
@@ -294,16 +293,16 @@ static struct bearer *bearer_find(const char *name)
294 * tipc_bearer_find_interface - locates bearer object with matching interface name 293 * tipc_bearer_find_interface - locates bearer object with matching interface name
295 */ 294 */
296 295
297struct bearer *tipc_bearer_find_interface(const char *if_name) 296struct tipc_bearer *tipc_bearer_find_interface(const char *if_name)
298{ 297{
299 struct bearer *b_ptr; 298 struct tipc_bearer *b_ptr;
300 char *b_if_name; 299 char *b_if_name;
301 u32 i; 300 u32 i;
302 301
303 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { 302 for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) {
304 if (!b_ptr->active) 303 if (!b_ptr->active)
305 continue; 304 continue;
306 b_if_name = strchr(b_ptr->publ.name, ':') + 1; 305 b_if_name = strchr(b_ptr->name, ':') + 1;
307 if (!strcmp(b_if_name, if_name)) 306 if (!strcmp(b_if_name, if_name))
308 return b_ptr; 307 return b_ptr;
309 } 308 }
@@ -318,7 +317,7 @@ struct sk_buff *tipc_bearer_get_names(void)
318{ 317{
319 struct sk_buff *buf; 318 struct sk_buff *buf;
320 struct media *m_ptr; 319 struct media *m_ptr;
321 struct bearer *b_ptr; 320 struct tipc_bearer *b_ptr;
322 int i, j; 321 int i, j;
323 322
324 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); 323 buf = tipc_cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
@@ -331,8 +330,8 @@ struct sk_buff *tipc_bearer_get_names(void)
331 b_ptr = &tipc_bearers[j]; 330 b_ptr = &tipc_bearers[j];
332 if (b_ptr->active && (b_ptr->media == m_ptr)) { 331 if (b_ptr->active && (b_ptr->media == m_ptr)) {
333 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 332 tipc_cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME,
334 b_ptr->publ.name, 333 b_ptr->name,
335 strlen(b_ptr->publ.name) + 1); 334 strlen(b_ptr->name) + 1);
336 } 335 }
337 } 336 }
338 } 337 }
@@ -340,14 +339,14 @@ struct sk_buff *tipc_bearer_get_names(void)
340 return buf; 339 return buf;
341} 340}
342 341
343void tipc_bearer_add_dest(struct bearer *b_ptr, u32 dest) 342void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
344{ 343{
345 tipc_nmap_add(&b_ptr->nodes, dest); 344 tipc_nmap_add(&b_ptr->nodes, dest);
346 tipc_disc_update_link_req(b_ptr->link_req); 345 tipc_disc_update_link_req(b_ptr->link_req);
347 tipc_bcbearer_sort(); 346 tipc_bcbearer_sort();
348} 347}
349 348
350void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest) 349void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
351{ 350{
352 tipc_nmap_remove(&b_ptr->nodes, dest); 351 tipc_nmap_remove(&b_ptr->nodes, dest);
353 tipc_disc_update_link_req(b_ptr->link_req); 352 tipc_disc_update_link_req(b_ptr->link_req);
@@ -362,12 +361,12 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest)
362 * bearer.lock must be taken before calling 361 * bearer.lock must be taken before calling
363 * Returns binary true(1) ore false(0) 362 * Returns binary true(1) ore false(0)
364 */ 363 */
365static int bearer_push(struct bearer *b_ptr) 364static int bearer_push(struct tipc_bearer *b_ptr)
366{ 365{
367 u32 res = 0; 366 u32 res = 0;
368 struct link *ln, *tln; 367 struct link *ln, *tln;
369 368
370 if (b_ptr->publ.blocked) 369 if (b_ptr->blocked)
371 return 0; 370 return 0;
372 371
373 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) { 372 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {
@@ -382,13 +381,13 @@ static int bearer_push(struct bearer *b_ptr)
382 return list_empty(&b_ptr->cong_links); 381 return list_empty(&b_ptr->cong_links);
383} 382}
384 383
385void tipc_bearer_lock_push(struct bearer *b_ptr) 384void tipc_bearer_lock_push(struct tipc_bearer *b_ptr)
386{ 385{
387 int res; 386 int res;
388 387
389 spin_lock_bh(&b_ptr->publ.lock); 388 spin_lock_bh(&b_ptr->lock);
390 res = bearer_push(b_ptr); 389 res = bearer_push(b_ptr);
391 spin_unlock_bh(&b_ptr->publ.lock); 390 spin_unlock_bh(&b_ptr->lock);
392 if (res) 391 if (res)
393 tipc_bcbearer_push(); 392 tipc_bcbearer_push();
394} 393}
@@ -398,16 +397,14 @@ void tipc_bearer_lock_push(struct bearer *b_ptr)
398 * Interrupt enabling new requests after bearer congestion or blocking: 397 * Interrupt enabling new requests after bearer congestion or blocking:
399 * See bearer_send(). 398 * See bearer_send().
400 */ 399 */
401void tipc_continue(struct tipc_bearer *tb_ptr) 400void tipc_continue(struct tipc_bearer *b_ptr)
402{ 401{
403 struct bearer *b_ptr = (struct bearer *)tb_ptr; 402 spin_lock_bh(&b_ptr->lock);
404
405 spin_lock_bh(&b_ptr->publ.lock);
406 b_ptr->continue_count++; 403 b_ptr->continue_count++;
407 if (!list_empty(&b_ptr->cong_links)) 404 if (!list_empty(&b_ptr->cong_links))
408 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr); 405 tipc_k_signal((Handler)tipc_bearer_lock_push, (unsigned long)b_ptr);
409 b_ptr->publ.blocked = 0; 406 b_ptr->blocked = 0;
410 spin_unlock_bh(&b_ptr->publ.lock); 407 spin_unlock_bh(&b_ptr->lock);
411} 408}
412 409
413/* 410/*
@@ -418,7 +415,7 @@ void tipc_continue(struct tipc_bearer *tb_ptr)
418 * bearer.lock is busy 415 * bearer.lock is busy
419 */ 416 */
420 417
421static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr) 418static void tipc_bearer_schedule_unlocked(struct tipc_bearer *b_ptr, struct link *l_ptr)
422{ 419{
423 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); 420 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
424} 421}
@@ -431,11 +428,11 @@ static void tipc_bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_p
431 * bearer.lock is free 428 * bearer.lock is free
432 */ 429 */
433 430
434void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr) 431void tipc_bearer_schedule(struct tipc_bearer *b_ptr, struct link *l_ptr)
435{ 432{
436 spin_lock_bh(&b_ptr->publ.lock); 433 spin_lock_bh(&b_ptr->lock);
437 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 434 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
438 spin_unlock_bh(&b_ptr->publ.lock); 435 spin_unlock_bh(&b_ptr->lock);
439} 436}
440 437
441 438
@@ -444,18 +441,18 @@ void tipc_bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
444 * and if there is, try to resolve it before returning. 441 * and if there is, try to resolve it before returning.
445 * 'tipc_net_lock' is read_locked when this function is called 442 * 'tipc_net_lock' is read_locked when this function is called
446 */ 443 */
447int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr) 444int tipc_bearer_resolve_congestion(struct tipc_bearer *b_ptr, struct link *l_ptr)
448{ 445{
449 int res = 1; 446 int res = 1;
450 447
451 if (list_empty(&b_ptr->cong_links)) 448 if (list_empty(&b_ptr->cong_links))
452 return 1; 449 return 1;
453 spin_lock_bh(&b_ptr->publ.lock); 450 spin_lock_bh(&b_ptr->lock);
454 if (!bearer_push(b_ptr)) { 451 if (!bearer_push(b_ptr)) {
455 tipc_bearer_schedule_unlocked(b_ptr, l_ptr); 452 tipc_bearer_schedule_unlocked(b_ptr, l_ptr);
456 res = 0; 453 res = 0;
457 } 454 }
458 spin_unlock_bh(&b_ptr->publ.lock); 455 spin_unlock_bh(&b_ptr->lock);
459 return res; 456 return res;
460} 457}
461 458
@@ -463,9 +460,9 @@ int tipc_bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
463 * tipc_bearer_congested - determines if bearer is currently congested 460 * tipc_bearer_congested - determines if bearer is currently congested
464 */ 461 */
465 462
466int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr) 463int tipc_bearer_congested(struct tipc_bearer *b_ptr, struct link *l_ptr)
467{ 464{
468 if (unlikely(b_ptr->publ.blocked)) 465 if (unlikely(b_ptr->blocked))
469 return 1; 466 return 1;
470 if (likely(list_empty(&b_ptr->cong_links))) 467 if (likely(list_empty(&b_ptr->cong_links)))
471 return 0; 468 return 0;
@@ -476,9 +473,9 @@ int tipc_bearer_congested(struct bearer *b_ptr, struct link *l_ptr)
476 * tipc_enable_bearer - enable bearer with the given name 473 * tipc_enable_bearer - enable bearer with the given name
477 */ 474 */
478 475
479int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) 476int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
480{ 477{
481 struct bearer *b_ptr; 478 struct tipc_bearer *b_ptr;
482 struct media *m_ptr; 479 struct media *m_ptr;
483 struct bearer_name b_name; 480 struct bearer_name b_name;
484 char addr_string[16]; 481 char addr_string[16];
@@ -496,9 +493,9 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
496 warn("Bearer <%s> rejected, illegal name\n", name); 493 warn("Bearer <%s> rejected, illegal name\n", name);
497 return -EINVAL; 494 return -EINVAL;
498 } 495 }
499 if (!tipc_addr_domain_valid(bcast_scope) || 496 if (!tipc_addr_domain_valid(disc_domain) ||
500 !tipc_in_scope(bcast_scope, tipc_own_addr)) { 497 !tipc_in_scope(disc_domain, tipc_own_addr)) {
501 warn("Bearer <%s> rejected, illegal broadcast scope\n", name); 498 warn("Bearer <%s> rejected, illegal discovery domain\n", name);
502 return -EINVAL; 499 return -EINVAL;
503 } 500 }
504 if ((priority < TIPC_MIN_LINK_PRI || 501 if ((priority < TIPC_MIN_LINK_PRI ||
@@ -528,7 +525,7 @@ restart:
528 bearer_id = i; 525 bearer_id = i;
529 continue; 526 continue;
530 } 527 }
531 if (!strcmp(name, tipc_bearers[i].publ.name)) { 528 if (!strcmp(name, tipc_bearers[i].name)) {
532 warn("Bearer <%s> rejected, already enabled\n", name); 529 warn("Bearer <%s> rejected, already enabled\n", name);
533 goto failed; 530 goto failed;
534 } 531 }
@@ -551,8 +548,8 @@ restart:
551 } 548 }
552 549
553 b_ptr = &tipc_bearers[bearer_id]; 550 b_ptr = &tipc_bearers[bearer_id];
554 strcpy(b_ptr->publ.name, name); 551 strcpy(b_ptr->name, name);
555 res = m_ptr->enable_bearer(&b_ptr->publ); 552 res = m_ptr->enable_bearer(b_ptr);
556 if (res) { 553 if (res) {
557 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); 554 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
558 goto failed; 555 goto failed;
@@ -562,18 +559,15 @@ restart:
562 b_ptr->media = m_ptr; 559 b_ptr->media = m_ptr;
563 b_ptr->net_plane = bearer_id + 'A'; 560 b_ptr->net_plane = bearer_id + 'A';
564 b_ptr->active = 1; 561 b_ptr->active = 1;
565 b_ptr->detect_scope = bcast_scope;
566 b_ptr->priority = priority; 562 b_ptr->priority = priority;
567 INIT_LIST_HEAD(&b_ptr->cong_links); 563 INIT_LIST_HEAD(&b_ptr->cong_links);
568 INIT_LIST_HEAD(&b_ptr->links); 564 INIT_LIST_HEAD(&b_ptr->links);
569 if (m_ptr->bcast) { 565 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
570 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 566 disc_domain);
571 bcast_scope, 2); 567 spin_lock_init(&b_ptr->lock);
572 }
573 spin_lock_init(&b_ptr->publ.lock);
574 write_unlock_bh(&tipc_net_lock); 568 write_unlock_bh(&tipc_net_lock);
575 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 569 info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
576 name, tipc_addr_string_fill(addr_string, bcast_scope), priority); 570 name, tipc_addr_string_fill(addr_string, disc_domain), priority);
577 return 0; 571 return 0;
578failed: 572failed:
579 write_unlock_bh(&tipc_net_lock); 573 write_unlock_bh(&tipc_net_lock);
@@ -587,7 +581,7 @@ failed:
587 581
588int tipc_block_bearer(const char *name) 582int tipc_block_bearer(const char *name)
589{ 583{
590 struct bearer *b_ptr = NULL; 584 struct tipc_bearer *b_ptr = NULL;
591 struct link *l_ptr; 585 struct link *l_ptr;
592 struct link *temp_l_ptr; 586 struct link *temp_l_ptr;
593 587
@@ -600,8 +594,8 @@ int tipc_block_bearer(const char *name)
600 } 594 }
601 595
602 info("Blocking bearer <%s>\n", name); 596 info("Blocking bearer <%s>\n", name);
603 spin_lock_bh(&b_ptr->publ.lock); 597 spin_lock_bh(&b_ptr->lock);
604 b_ptr->publ.blocked = 1; 598 b_ptr->blocked = 1;
605 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 599 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
606 struct tipc_node *n_ptr = l_ptr->owner; 600 struct tipc_node *n_ptr = l_ptr->owner;
607 601
@@ -609,7 +603,7 @@ int tipc_block_bearer(const char *name)
609 tipc_link_reset(l_ptr); 603 tipc_link_reset(l_ptr);
610 spin_unlock_bh(&n_ptr->lock); 604 spin_unlock_bh(&n_ptr->lock);
611 } 605 }
612 spin_unlock_bh(&b_ptr->publ.lock); 606 spin_unlock_bh(&b_ptr->lock);
613 read_unlock_bh(&tipc_net_lock); 607 read_unlock_bh(&tipc_net_lock);
614 return 0; 608 return 0;
615} 609}
@@ -620,27 +614,27 @@ int tipc_block_bearer(const char *name)
620 * Note: This routine assumes caller holds tipc_net_lock. 614 * Note: This routine assumes caller holds tipc_net_lock.
621 */ 615 */
622 616
623static void bearer_disable(struct bearer *b_ptr) 617static void bearer_disable(struct tipc_bearer *b_ptr)
624{ 618{
625 struct link *l_ptr; 619 struct link *l_ptr;
626 struct link *temp_l_ptr; 620 struct link *temp_l_ptr;
627 621
628 info("Disabling bearer <%s>\n", b_ptr->publ.name); 622 info("Disabling bearer <%s>\n", b_ptr->name);
629 tipc_disc_stop_link_req(b_ptr->link_req); 623 tipc_disc_stop_link_req(b_ptr->link_req);
630 spin_lock_bh(&b_ptr->publ.lock); 624 spin_lock_bh(&b_ptr->lock);
631 b_ptr->link_req = NULL; 625 b_ptr->link_req = NULL;
632 b_ptr->publ.blocked = 1; 626 b_ptr->blocked = 1;
633 b_ptr->media->disable_bearer(&b_ptr->publ); 627 b_ptr->media->disable_bearer(b_ptr);
634 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 628 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
635 tipc_link_delete(l_ptr); 629 tipc_link_delete(l_ptr);
636 } 630 }
637 spin_unlock_bh(&b_ptr->publ.lock); 631 spin_unlock_bh(&b_ptr->lock);
638 memset(b_ptr, 0, sizeof(struct bearer)); 632 memset(b_ptr, 0, sizeof(struct tipc_bearer));
639} 633}
640 634
641int tipc_disable_bearer(const char *name) 635int tipc_disable_bearer(const char *name)
642{ 636{
643 struct bearer *b_ptr; 637 struct tipc_bearer *b_ptr;
644 int res; 638 int res;
645 639
646 write_lock_bh(&tipc_net_lock); 640 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..c9a73e7763f6 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;
@@ -193,7 +187,6 @@ static int __init tipc_init(void)
193 tipc_max_publications = 10000; 187 tipc_max_publications = 10000;
194 tipc_max_subscriptions = 2000; 188 tipc_max_subscriptions = 2000;
195 tipc_max_ports = CONFIG_TIPC_PORTS; 189 tipc_max_ports = CONFIG_TIPC_PORTS;
196 tipc_max_nodes = CONFIG_TIPC_NODES;
197 tipc_net_id = 4711; 190 tipc_net_id = 4711;
198 191
199 res = tipc_core_start(); 192 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..491eff56b9da 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
@@ -57,7 +57,7 @@
57 * @timer_intv: current interval between requests (in ms) 57 * @timer_intv: current interval between requests (in ms)
58 */ 58 */
59struct link_req { 59struct link_req {
60 struct bearer *bearer; 60 struct tipc_bearer *bearer;
61 struct tipc_media_addr dest; 61 struct tipc_media_addr dest;
62 struct sk_buff *buf; 62 struct sk_buff *buf;
63 struct timer_list timer; 63 struct timer_list timer;
@@ -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,63 +141,76 @@ 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 (!in_own_cluster(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/**
@@ -249,9 +263,9 @@ void tipc_disc_update_link_req(struct link_req *req)
249 263
250static void disc_timeout(struct link_req *req) 264static void disc_timeout(struct link_req *req)
251{ 265{
252 spin_lock_bh(&req->bearer->publ.lock); 266 spin_lock_bh(&req->bearer->lock);
253 267
254 req->bearer->media->send_msg(req->buf, &req->bearer->publ, &req->dest); 268 req->bearer->media->send_msg(req->buf, req->bearer, &req->dest);
255 269
256 if ((req->timer_intv == TIPC_LINK_REQ_SLOW) || 270 if ((req->timer_intv == TIPC_LINK_REQ_SLOW) ||
257 (req->timer_intv == TIPC_LINK_REQ_FAST)) { 271 (req->timer_intv == TIPC_LINK_REQ_FAST)) {
@@ -266,7 +280,7 @@ static void disc_timeout(struct link_req *req)
266 } 280 }
267 k_start_timer(&req->timer, req->timer_intv); 281 k_start_timer(&req->timer, req->timer_intv);
268 282
269 spin_unlock_bh(&req->bearer->publ.lock); 283 spin_unlock_bh(&req->bearer->lock);
270} 284}
271 285
272/** 286/**
@@ -274,15 +288,13 @@ static void disc_timeout(struct link_req *req)
274 * @b_ptr: ptr to bearer issuing requests 288 * @b_ptr: ptr to bearer issuing requests
275 * @dest: destination address for request messages 289 * @dest: destination address for request messages
276 * @dest_domain: network domain of node(s) which should respond to message 290 * @dest_domain: network domain of node(s) which should respond to message
277 * @req_links: max number of desired links
278 * 291 *
279 * Returns pointer to link request structure, or NULL if unable to create. 292 * Returns pointer to link request structure, or NULL if unable to create.
280 */ 293 */
281 294
282struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 295struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
283 const struct tipc_media_addr *dest, 296 const struct tipc_media_addr *dest,
284 u32 dest_domain, 297 u32 dest_domain)
285 u32 req_links)
286{ 298{
287 struct link_req *req; 299 struct link_req *req;
288 300
@@ -290,7 +302,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
290 if (!req) 302 if (!req)
291 return NULL; 303 return NULL;
292 304
293 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr); 305 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
294 if (!req->buf) { 306 if (!req->buf) {
295 kfree(req); 307 kfree(req);
296 return NULL; 308 return NULL;
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index d2c3cffb79fc..e48a167e47b2 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,12 @@
39 39
40struct link_req; 40struct link_req;
41 41
42struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, 42struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
43 const struct tipc_media_addr *dest, 43 const struct tipc_media_addr *dest,
44 u32 dest_domain, 44 u32 dest_domain);
45 u32 req_links);
46void tipc_disc_update_link_req(struct link_req *req); 45void tipc_disc_update_link_req(struct link_req *req);
47void tipc_disc_stop_link_req(struct link_req *req); 46void tipc_disc_stop_link_req(struct link_req *req);
48 47
49void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); 48void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
50 49
51#endif 50#endif
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 18702f58d111..ebf338f7b14e 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,7 +90,7 @@ 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, u32 destnode);
96static void link_check_defragm_bufs(struct link *l_ptr); 96static void link_check_defragm_bufs(struct link *l_ptr);
@@ -113,7 +113,7 @@ static void link_init_max_pkt(struct link *l_ptr)
113{ 113{
114 u32 max_pkt; 114 u32 max_pkt;
115 115
116 max_pkt = (l_ptr->b_ptr->publ.mtu & ~3); 116 max_pkt = (l_ptr->b_ptr->mtu & ~3);
117 if (max_pkt > MAX_MSG_SIZE) 117 if (max_pkt > MAX_MSG_SIZE)
118 max_pkt = MAX_MSG_SIZE; 118 max_pkt = MAX_MSG_SIZE;
119 119
@@ -246,9 +246,6 @@ static void link_timeout(struct link *l_ptr)
246 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; 246 l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size;
247 l_ptr->stats.queue_sz_counts++; 247 l_ptr->stats.queue_sz_counts++;
248 248
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) { 249 if (l_ptr->first_out) {
253 struct tipc_msg *msg = buf_msg(l_ptr->first_out); 250 struct tipc_msg *msg = buf_msg(l_ptr->first_out);
254 u32 length = msg_size(msg); 251 u32 length = msg_size(msg);
@@ -296,19 +293,35 @@ static void link_set_timer(struct link *l_ptr, u32 time)
296 293
297/** 294/**
298 * tipc_link_create - create a new link 295 * tipc_link_create - create a new link
296 * @n_ptr: pointer to associated node
299 * @b_ptr: pointer to associated bearer 297 * @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 298 * @media_addr: media address to use when sending messages over link
302 * 299 *
303 * Returns pointer to link. 300 * Returns pointer to link.
304 */ 301 */
305 302
306struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, 303struct link *tipc_link_create(struct tipc_node *n_ptr,
304 struct tipc_bearer *b_ptr,
307 const struct tipc_media_addr *media_addr) 305 const struct tipc_media_addr *media_addr)
308{ 306{
309 struct link *l_ptr; 307 struct link *l_ptr;
310 struct tipc_msg *msg; 308 struct tipc_msg *msg;
311 char *if_name; 309 char *if_name;
310 char addr_string[16];
311 u32 peer = n_ptr->addr;
312
313 if (n_ptr->link_cnt >= 2) {
314 tipc_addr_string_fill(addr_string, n_ptr->addr);
315 err("Attempt to establish third link to %s\n", addr_string);
316 return NULL;
317 }
318
319 if (n_ptr->links[b_ptr->identity]) {
320 tipc_addr_string_fill(addr_string, n_ptr->addr);
321 err("Attempt to establish second link on <%s> to %s\n",
322 b_ptr->name, addr_string);
323 return NULL;
324 }
312 325
313 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); 326 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC);
314 if (!l_ptr) { 327 if (!l_ptr) {
@@ -317,7 +330,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
317 } 330 }
318 331
319 l_ptr->addr = peer; 332 l_ptr->addr = peer;
320 if_name = strchr(b_ptr->publ.name, ':') + 1; 333 if_name = strchr(b_ptr->name, ':') + 1;
321 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 334 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
322 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 335 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
323 tipc_node(tipc_own_addr), 336 tipc_node(tipc_own_addr),
@@ -325,6 +338,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
325 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 338 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
326 /* note: peer i/f is appended to link name by reset/activate */ 339 /* note: peer i/f is appended to link name by reset/activate */
327 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 340 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
341 l_ptr->owner = n_ptr;
328 l_ptr->checkpoint = 1; 342 l_ptr->checkpoint = 1;
329 l_ptr->b_ptr = b_ptr; 343 l_ptr->b_ptr = b_ptr;
330 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 344 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
@@ -348,11 +362,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
348 362
349 link_reset_statistics(l_ptr); 363 link_reset_statistics(l_ptr);
350 364
351 l_ptr->owner = tipc_node_attach_link(l_ptr); 365 tipc_node_attach_link(n_ptr, l_ptr);
352 if (!l_ptr->owner) {
353 kfree(l_ptr);
354 return NULL;
355 }
356 366
357 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 367 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
358 list_add_tail(&l_ptr->link_list, &b_ptr->links); 368 list_add_tail(&l_ptr->link_list, &b_ptr->links);
@@ -391,7 +401,9 @@ void tipc_link_delete(struct link *l_ptr)
391 401
392static void link_start(struct link *l_ptr) 402static void link_start(struct link *l_ptr)
393{ 403{
404 tipc_node_lock(l_ptr->owner);
394 link_state_event(l_ptr, STARTING_EVT); 405 link_state_event(l_ptr, STARTING_EVT);
406 tipc_node_unlock(l_ptr->owner);
395} 407}
396 408
397/** 409/**
@@ -406,7 +418,7 @@ static void link_start(struct link *l_ptr)
406 418
407static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) 419static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
408{ 420{
409 struct port *p_ptr; 421 struct tipc_port *p_ptr;
410 422
411 spin_lock_bh(&tipc_port_list_lock); 423 spin_lock_bh(&tipc_port_list_lock);
412 p_ptr = tipc_port_lock(origport); 424 p_ptr = tipc_port_lock(origport);
@@ -415,7 +427,7 @@ static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz)
415 goto exit; 427 goto exit;
416 if (!list_empty(&p_ptr->wait_list)) 428 if (!list_empty(&p_ptr->wait_list))
417 goto exit; 429 goto exit;
418 p_ptr->publ.congested = 1; 430 p_ptr->congested = 1;
419 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); 431 p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt);
420 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); 432 list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
421 l_ptr->stats.link_congs++; 433 l_ptr->stats.link_congs++;
@@ -428,8 +440,8 @@ exit:
428 440
429void tipc_link_wakeup_ports(struct link *l_ptr, int all) 441void tipc_link_wakeup_ports(struct link *l_ptr, int all)
430{ 442{
431 struct port *p_ptr; 443 struct tipc_port *p_ptr;
432 struct port *temp_p_ptr; 444 struct tipc_port *temp_p_ptr;
433 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; 445 int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size;
434 446
435 if (all) 447 if (all)
@@ -445,11 +457,11 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all)
445 if (win <= 0) 457 if (win <= 0)
446 break; 458 break;
447 list_del_init(&p_ptr->wait_list); 459 list_del_init(&p_ptr->wait_list);
448 spin_lock_bh(p_ptr->publ.lock); 460 spin_lock_bh(p_ptr->lock);
449 p_ptr->publ.congested = 0; 461 p_ptr->congested = 0;
450 p_ptr->wakeup(&p_ptr->publ); 462 p_ptr->wakeup(p_ptr);
451 win -= p_ptr->waiting_pkts; 463 win -= p_ptr->waiting_pkts;
452 spin_unlock_bh(p_ptr->publ.lock); 464 spin_unlock_bh(p_ptr->lock);
453 } 465 }
454 466
455exit: 467exit:
@@ -549,7 +561,7 @@ void tipc_link_reset(struct link *l_ptr)
549 tipc_node_link_down(l_ptr->owner, l_ptr); 561 tipc_node_link_down(l_ptr->owner, l_ptr);
550 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); 562 tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
551 563
552 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && 564 if (was_active_link && tipc_node_active_links(l_ptr->owner) &&
553 l_ptr->owner->permit_changeover) { 565 l_ptr->owner->permit_changeover) {
554 l_ptr->reset_checkpoint = checkpoint; 566 l_ptr->reset_checkpoint = checkpoint;
555 l_ptr->exp_msg_count = START_CHANGEOVER; 567 l_ptr->exp_msg_count = START_CHANGEOVER;
@@ -824,7 +836,10 @@ static void link_add_to_outqueue(struct link *l_ptr,
824 l_ptr->last_out = buf; 836 l_ptr->last_out = buf;
825 } else 837 } else
826 l_ptr->first_out = l_ptr->last_out = buf; 838 l_ptr->first_out = l_ptr->last_out = buf;
839
827 l_ptr->out_queue_size++; 840 l_ptr->out_queue_size++;
841 if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz)
842 l_ptr->stats.max_queue_sz = l_ptr->out_queue_size;
828} 843}
829 844
830/* 845/*
@@ -867,9 +882,6 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
867 882
868 /* Packet can be queued or sent: */ 883 /* Packet can be queued or sent: */
869 884
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) && 885 if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) &&
874 !link_congested(l_ptr))) { 886 !link_congested(l_ptr))) {
875 link_add_to_outqueue(l_ptr, buf, msg); 887 link_add_to_outqueue(l_ptr, buf, msg);
@@ -1027,12 +1039,12 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1027 * except for total message length. 1039 * except for total message length.
1028 * Returns user data length or errno. 1040 * Returns user data length or errno.
1029 */ 1041 */
1030int tipc_link_send_sections_fast(struct port *sender, 1042int tipc_link_send_sections_fast(struct tipc_port *sender,
1031 struct iovec const *msg_sect, 1043 struct iovec const *msg_sect,
1032 const u32 num_sect, 1044 const u32 num_sect,
1033 u32 destaddr) 1045 u32 destaddr)
1034{ 1046{
1035 struct tipc_msg *hdr = &sender->publ.phdr; 1047 struct tipc_msg *hdr = &sender->phdr;
1036 struct link *l_ptr; 1048 struct link *l_ptr;
1037 struct sk_buff *buf; 1049 struct sk_buff *buf;
1038 struct tipc_node *node; 1050 struct tipc_node *node;
@@ -1045,7 +1057,7 @@ again:
1045 * (Must not hold any locks while building message.) 1057 * (Must not hold any locks while building message.)
1046 */ 1058 */
1047 1059
1048 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt, 1060 res = tipc_msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
1049 !sender->user_port, &buf); 1061 !sender->user_port, &buf);
1050 1062
1051 read_lock_bh(&tipc_net_lock); 1063 read_lock_bh(&tipc_net_lock);
@@ -1056,7 +1068,7 @@ again:
1056 if (likely(l_ptr)) { 1068 if (likely(l_ptr)) {
1057 if (likely(buf)) { 1069 if (likely(buf)) {
1058 res = link_send_buf_fast(l_ptr, buf, 1070 res = link_send_buf_fast(l_ptr, buf,
1059 &sender->publ.max_pkt); 1071 &sender->max_pkt);
1060 if (unlikely(res < 0)) 1072 if (unlikely(res < 0))
1061 buf_discard(buf); 1073 buf_discard(buf);
1062exit: 1074exit:
@@ -1075,7 +1087,7 @@ exit:
1075 if (link_congested(l_ptr) || 1087 if (link_congested(l_ptr) ||
1076 !list_empty(&l_ptr->b_ptr->cong_links)) { 1088 !list_empty(&l_ptr->b_ptr->cong_links)) {
1077 res = link_schedule_port(l_ptr, 1089 res = link_schedule_port(l_ptr,
1078 sender->publ.ref, res); 1090 sender->ref, res);
1079 goto exit; 1091 goto exit;
1080 } 1092 }
1081 1093
@@ -1084,12 +1096,12 @@ exit:
1084 * then re-try fast path or fragment the message 1096 * then re-try fast path or fragment the message
1085 */ 1097 */
1086 1098
1087 sender->publ.max_pkt = l_ptr->max_pkt; 1099 sender->max_pkt = l_ptr->max_pkt;
1088 tipc_node_unlock(node); 1100 tipc_node_unlock(node);
1089 read_unlock_bh(&tipc_net_lock); 1101 read_unlock_bh(&tipc_net_lock);
1090 1102
1091 1103
1092 if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt) 1104 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1093 goto again; 1105 goto again;
1094 1106
1095 return link_send_sections_long(sender, msg_sect, 1107 return link_send_sections_long(sender, msg_sect,
@@ -1123,14 +1135,14 @@ exit:
1123 * 1135 *
1124 * Returns user data length or errno. 1136 * Returns user data length or errno.
1125 */ 1137 */
1126static int link_send_sections_long(struct port *sender, 1138static int link_send_sections_long(struct tipc_port *sender,
1127 struct iovec const *msg_sect, 1139 struct iovec const *msg_sect,
1128 u32 num_sect, 1140 u32 num_sect,
1129 u32 destaddr) 1141 u32 destaddr)
1130{ 1142{
1131 struct link *l_ptr; 1143 struct link *l_ptr;
1132 struct tipc_node *node; 1144 struct tipc_node *node;
1133 struct tipc_msg *hdr = &sender->publ.phdr; 1145 struct tipc_msg *hdr = &sender->phdr;
1134 u32 dsz = msg_data_sz(hdr); 1146 u32 dsz = msg_data_sz(hdr);
1135 u32 max_pkt, fragm_sz, rest; 1147 u32 max_pkt, fragm_sz, rest;
1136 struct tipc_msg fragm_hdr; 1148 struct tipc_msg fragm_hdr;
@@ -1142,7 +1154,7 @@ static int link_send_sections_long(struct port *sender,
1142 1154
1143again: 1155again:
1144 fragm_no = 1; 1156 fragm_no = 1;
1145 max_pkt = sender->publ.max_pkt - INT_H_SIZE; 1157 max_pkt = sender->max_pkt - INT_H_SIZE;
1146 /* leave room for tunnel header in case of link changeover */ 1158 /* leave room for tunnel header in case of link changeover */
1147 fragm_sz = max_pkt - INT_H_SIZE; 1159 fragm_sz = max_pkt - INT_H_SIZE;
1148 /* leave room for fragmentation header in each fragment */ 1160 /* leave room for fragmentation header in each fragment */
@@ -1157,7 +1169,7 @@ again:
1157 1169
1158 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 1170 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1159 INT_H_SIZE, msg_destnode(hdr)); 1171 INT_H_SIZE, msg_destnode(hdr));
1160 msg_set_link_selector(&fragm_hdr, sender->publ.ref); 1172 msg_set_link_selector(&fragm_hdr, sender->ref);
1161 msg_set_size(&fragm_hdr, max_pkt); 1173 msg_set_size(&fragm_hdr, max_pkt);
1162 msg_set_fragm_no(&fragm_hdr, 1); 1174 msg_set_fragm_no(&fragm_hdr, 1);
1163 1175
@@ -1238,13 +1250,13 @@ error:
1238 node = tipc_node_find(destaddr); 1250 node = tipc_node_find(destaddr);
1239 if (likely(node)) { 1251 if (likely(node)) {
1240 tipc_node_lock(node); 1252 tipc_node_lock(node);
1241 l_ptr = node->active_links[sender->publ.ref & 1]; 1253 l_ptr = node->active_links[sender->ref & 1];
1242 if (!l_ptr) { 1254 if (!l_ptr) {
1243 tipc_node_unlock(node); 1255 tipc_node_unlock(node);
1244 goto reject; 1256 goto reject;
1245 } 1257 }
1246 if (l_ptr->max_pkt < max_pkt) { 1258 if (l_ptr->max_pkt < max_pkt) {
1247 sender->publ.max_pkt = l_ptr->max_pkt; 1259 sender->max_pkt = l_ptr->max_pkt;
1248 tipc_node_unlock(node); 1260 tipc_node_unlock(node);
1249 for (; buf_chain; buf_chain = buf) { 1261 for (; buf_chain; buf_chain = buf) {
1250 buf = buf_chain->next; 1262 buf = buf_chain->next;
@@ -1441,7 +1453,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1441 info("Outstanding acks: %lu\n", 1453 info("Outstanding acks: %lu\n",
1442 (unsigned long) TIPC_SKB_CB(buf)->handle); 1454 (unsigned long) TIPC_SKB_CB(buf)->handle);
1443 1455
1444 n_ptr = l_ptr->owner->next; 1456 n_ptr = tipc_bclink_retransmit_to();
1445 tipc_node_lock(n_ptr); 1457 tipc_node_lock(n_ptr);
1446 1458
1447 tipc_addr_string_fill(addr_string, n_ptr->addr); 1459 tipc_addr_string_fill(addr_string, n_ptr->addr);
@@ -1595,11 +1607,10 @@ static int link_recv_buf_validate(struct sk_buff *buf)
1595 * structure (i.e. cannot be NULL), but bearer can be inactive. 1607 * structure (i.e. cannot be NULL), but bearer can be inactive.
1596 */ 1608 */
1597 1609
1598void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) 1610void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1599{ 1611{
1600 read_lock_bh(&tipc_net_lock); 1612 read_lock_bh(&tipc_net_lock);
1601 while (head) { 1613 while (head) {
1602 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1603 struct tipc_node *n_ptr; 1614 struct tipc_node *n_ptr;
1604 struct link *l_ptr; 1615 struct link *l_ptr;
1605 struct sk_buff *crs; 1616 struct sk_buff *crs;
@@ -1735,10 +1746,6 @@ deliver:
1735 tipc_node_unlock(n_ptr); 1746 tipc_node_unlock(n_ptr);
1736 tipc_link_recv_bundle(buf); 1747 tipc_link_recv_bundle(buf);
1737 continue; 1748 continue;
1738 case ROUTE_DISTRIBUTOR:
1739 tipc_node_unlock(n_ptr);
1740 buf_discard(buf);
1741 continue;
1742 case NAME_DISTRIBUTOR: 1749 case NAME_DISTRIBUTOR:
1743 tipc_node_unlock(n_ptr); 1750 tipc_node_unlock(n_ptr);
1744 tipc_named_recv(buf); 1751 tipc_named_recv(buf);
@@ -1765,6 +1772,10 @@ deliver:
1765 goto protocol_check; 1772 goto protocol_check;
1766 } 1773 }
1767 break; 1774 break;
1775 default:
1776 buf_discard(buf);
1777 buf = NULL;
1778 break;
1768 } 1779 }
1769 } 1780 }
1770 tipc_node_unlock(n_ptr); 1781 tipc_node_unlock(n_ptr);
@@ -1900,6 +1911,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
1900 struct sk_buff *buf = NULL; 1911 struct sk_buff *buf = NULL;
1901 struct tipc_msg *msg = l_ptr->pmsg; 1912 struct tipc_msg *msg = l_ptr->pmsg;
1902 u32 msg_size = sizeof(l_ptr->proto_msg); 1913 u32 msg_size = sizeof(l_ptr->proto_msg);
1914 int r_flag;
1903 1915
1904 if (link_blocked(l_ptr)) 1916 if (link_blocked(l_ptr))
1905 return; 1917 return;
@@ -1950,15 +1962,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)); 1962 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1));
1951 msg_set_seq_gap(msg, 0); 1963 msg_set_seq_gap(msg, 0);
1952 msg_set_next_sent(msg, 1); 1964 msg_set_next_sent(msg, 1);
1965 msg_set_probe(msg, 0);
1953 msg_set_link_tolerance(msg, l_ptr->tolerance); 1966 msg_set_link_tolerance(msg, l_ptr->tolerance);
1954 msg_set_linkprio(msg, l_ptr->priority); 1967 msg_set_linkprio(msg, l_ptr->priority);
1955 msg_set_max_pkt(msg, l_ptr->max_pkt_target); 1968 msg_set_max_pkt(msg, l_ptr->max_pkt_target);
1956 } 1969 }
1957 1970
1958 if (tipc_node_has_redundant_links(l_ptr->owner)) 1971 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
1959 msg_set_redundant_link(msg); 1972 msg_set_redundant_link(msg, r_flag);
1960 else
1961 msg_clear_redundant_link(msg);
1962 msg_set_linkprio(msg, l_ptr->priority); 1973 msg_set_linkprio(msg, l_ptr->priority);
1963 1974
1964 /* Ensure sequence number will not fit : */ 1975 /* Ensure sequence number will not fit : */
@@ -1978,7 +1989,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)); 1989 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
1979 return; 1990 return;
1980 } 1991 }
1981 msg_set_timestamp(msg, jiffies_to_msecs(jiffies));
1982 1992
1983 /* Message can be sent */ 1993 /* Message can be sent */
1984 1994
@@ -2066,7 +2076,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); 2076 l_ptr->peer_bearer_id = msg_bearer_id(msg);
2067 2077
2068 /* Synchronize broadcast sequence numbers */ 2078 /* Synchronize broadcast sequence numbers */
2069 if (!tipc_node_has_redundant_links(l_ptr->owner)) 2079 if (!tipc_node_redundant_links(l_ptr->owner))
2070 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); 2080 l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
2071 break; 2081 break;
2072 case STATE_MSG: 2082 case STATE_MSG:
@@ -2413,9 +2423,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2413 else 2423 else
2414 destaddr = msg_destnode(inmsg); 2424 destaddr = msg_destnode(inmsg);
2415 2425
2416 if (msg_routed(inmsg))
2417 msg_set_prevnode(inmsg, tipc_own_addr);
2418
2419 /* Prepare reusable fragment header: */ 2426 /* Prepare reusable fragment header: */
2420 2427
2421 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2428 tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
@@ -2464,7 +2471,7 @@ exit:
2464 * A pending message being re-assembled must store certain values 2471 * A pending message being re-assembled must store certain values
2465 * to handle subsequent fragments correctly. The following functions 2472 * to handle subsequent fragments correctly. The following functions
2466 * help storing these values in unused, available fields in the 2473 * help storing these values in unused, available fields in the
2467 * pending message. This makes dynamic memory allocation unecessary. 2474 * pending message. This makes dynamic memory allocation unnecessary.
2468 */ 2475 */
2469 2476
2470static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) 2477static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
@@ -2618,6 +2625,9 @@ static void link_check_defragm_bufs(struct link *l_ptr)
2618 2625
2619static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) 2626static void link_set_supervision_props(struct link *l_ptr, u32 tolerance)
2620{ 2627{
2628 if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL))
2629 return;
2630
2621 l_ptr->tolerance = tolerance; 2631 l_ptr->tolerance = tolerance;
2622 l_ptr->continuity_interval = 2632 l_ptr->continuity_interval =
2623 ((tolerance / 4) > 500) ? 500 : tolerance / 4; 2633 ((tolerance / 4) > 500) ? 500 : tolerance / 4;
@@ -2658,7 +2668,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) 2668static struct link *link_find_link(const char *name, struct tipc_node **node)
2659{ 2669{
2660 struct link_name link_name_parts; 2670 struct link_name link_name_parts;
2661 struct bearer *b_ptr; 2671 struct tipc_bearer *b_ptr;
2662 struct link *l_ptr; 2672 struct link *l_ptr;
2663 2673
2664 if (!link_name_validate(name, &link_name_parts)) 2674 if (!link_name_validate(name, &link_name_parts))
@@ -2961,7 +2971,7 @@ static void link_print(struct link *l_ptr, const char *str)
2961 2971
2962 tipc_printf(buf, str); 2972 tipc_printf(buf, str);
2963 tipc_printf(buf, "Link %x<%s>:", 2973 tipc_printf(buf, "Link %x<%s>:",
2964 l_ptr->addr, l_ptr->b_ptr->publ.name); 2974 l_ptr->addr, l_ptr->b_ptr->name);
2965 2975
2966#ifdef CONFIG_TIPC_DEBUG 2976#ifdef CONFIG_TIPC_DEBUG
2967 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) 2977 if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr))
@@ -2981,9 +2991,9 @@ static void link_print(struct link *l_ptr, const char *str)
2981 != (l_ptr->out_queue_size - 1)) || 2991 != (l_ptr->out_queue_size - 1)) ||
2982 (l_ptr->last_out->next != NULL)) { 2992 (l_ptr->last_out->next != NULL)) {
2983 tipc_printf(buf, "\nSend queue inconsistency\n"); 2993 tipc_printf(buf, "\nSend queue inconsistency\n");
2984 tipc_printf(buf, "first_out= %x ", l_ptr->first_out); 2994 tipc_printf(buf, "first_out= %p ", l_ptr->first_out);
2985 tipc_printf(buf, "next_out= %x ", l_ptr->next_out); 2995 tipc_printf(buf, "next_out= %p ", l_ptr->next_out);
2986 tipc_printf(buf, "last_out= %x ", l_ptr->last_out); 2996 tipc_printf(buf, "last_out= %p ", l_ptr->last_out);
2987 } 2997 }
2988 } else 2998 } else
2989 tipc_printf(buf, "[]"); 2999 tipc_printf(buf, "[]");
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 70967e637027..e6a30dbe1aaa 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,7 +225,7 @@ 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,
236 u32 destnode); 231 u32 destnode);
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index bb6180c4fcbb..6d92d17e7fb5 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
@@ -192,8 +192,6 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
192 default: 192 default:
193 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg)); 193 tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
194 } 194 }
195 if (msg_routed(msg) && !msg_non_seq(msg))
196 tipc_printf(buf, "ROUT:");
197 if (msg_reroute_cnt(msg)) 195 if (msg_reroute_cnt(msg))
198 tipc_printf(buf, "REROUTED(%u):", 196 tipc_printf(buf, "REROUTED(%u):",
199 msg_reroute_cnt(msg)); 197 msg_reroute_cnt(msg));
@@ -210,8 +208,6 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
210 default: 208 default:
211 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); 209 tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
212 } 210 }
213 if (msg_routed(msg))
214 tipc_printf(buf, "ROUT:");
215 if (msg_reroute_cnt(msg)) 211 if (msg_reroute_cnt(msg))
216 tipc_printf(buf, "REROUTED(%u):", 212 tipc_printf(buf, "REROUTED(%u):",
217 msg_reroute_cnt(msg)); 213 msg_reroute_cnt(msg));
@@ -232,13 +228,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
232 default: 228 default:
233 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); 229 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
234 } 230 }
235 if (msg_routed(msg))
236 tipc_printf(buf, "ROUT:");
237 if (msg_reroute_cnt(msg)) 231 if (msg_reroute_cnt(msg))
238 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg)); 232 tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
239 break; 233 break;
240 case LINK_PROTOCOL: 234 case LINK_PROTOCOL:
241 tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg));
242 switch (msg_type(msg)) { 235 switch (msg_type(msg)) {
243 case STATE_MSG: 236 case STATE_MSG:
244 tipc_printf(buf, "STATE:"); 237 tipc_printf(buf, "STATE:");
@@ -275,33 +268,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)); 268 tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
276 } 269 }
277 break; 270 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: 271 case LINK_CONFIG:
306 tipc_printf(buf, "CFG:"); 272 tipc_printf(buf, "CFG:");
307 switch (msg_type(msg)) { 273 switch (msg_type(msg)) {
@@ -381,20 +347,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)); 347 tipc_printf(buf, ":OPRT(%u):", msg_origport(msg));
382 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg)); 348 tipc_printf(buf, ":DPRT(%u):", msg_destport(msg));
383 } 349 }
384 if (msg_routed(msg) && !msg_non_seq(msg))
385 tipc_printf(buf, ":TSEQN(%u)", msg_transp_seqno(msg));
386 } 350 }
387 if (msg_user(msg) == NAME_DISTRIBUTOR) { 351 if (msg_user(msg) == NAME_DISTRIBUTOR) {
388 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); 352 tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
389 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); 353 tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
390 if (msg_routed(msg))
391 tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg));
392 } 354 }
393 355
394 if (msg_user(msg) == LINK_CONFIG) { 356 if (msg_user(msg) == LINK_CONFIG) {
395 u32 *raw = (u32 *)msg; 357 u32 *raw = (u32 *)msg;
396 struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5]; 358 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)); 359 tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
399 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); 360 tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
400 tipc_media_addr_printf(buf, orig); 361 tipc_media_addr_printf(buf, orig);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 92c4c4fd7b3f..de02339fc175 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
@@ -421,13 +421,6 @@ static inline int msg_is_dest(struct tipc_msg *m, u32 d)
421 return msg_short(m) || (msg_destnode(m) == d); 421 return msg_short(m) || (msg_destnode(m) == d);
422} 422}
423 423
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) 424static inline u32 msg_nametype(struct tipc_msg *m)
432{ 425{
433 return msg_word(m, 8); 426 return msg_word(m, 8);
@@ -438,26 +431,6 @@ static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
438 msg_set_word(m, 8, n); 431 msg_set_word(m, 8, n);
439} 432}
440 433
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) 434static inline u32 msg_nameinst(struct tipc_msg *m)
462{ 435{
463 return msg_word(m, 9); 436 return msg_word(m, 9);
@@ -545,7 +518,6 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
545#define NAME_DISTRIBUTOR 11 518#define NAME_DISTRIBUTOR 11
546#define MSG_FRAGMENTER 12 519#define MSG_FRAGMENTER 12
547#define LINK_CONFIG 13 520#define LINK_CONFIG 13
548#define DSC_H_SIZE 40
549 521
550/* 522/*
551 * Connection management protocol messages 523 * Connection management protocol messages
@@ -577,16 +549,6 @@ static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
577 msg_set_bits(m, 1, 16, 0x1fff, n); 549 msg_set_bits(m, 1, 16, 0x1fff, n);
578} 550}
579 551
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 552
591/* 553/*
592 * Word 2 554 * Word 2
@@ -749,14 +711,9 @@ static inline u32 msg_redundant_link(struct tipc_msg *m)
749 return msg_bits(m, 5, 12, 0x1); 711 return msg_bits(m, 5, 12, 0x1);
750} 712}
751 713
752static inline void msg_set_redundant_link(struct tipc_msg *m) 714static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
753{ 715{
754 msg_set_bits(m, 5, 12, 0x1, 1); 716 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} 717}
761 718
762 719
@@ -805,21 +762,6 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
805} 762}
806 763
807/* 764/*
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 765 * Segmentation message types
824 */ 766 */
825 767
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..6ff78f9c7d65 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/**
@@ -94,7 +80,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
94 struct sk_buff *buf; 80 struct sk_buff *buf;
95 struct sk_buff *ibuf = NULL; 81 struct sk_buff *ibuf = NULL;
96 struct port_list dports = {0, NULL, }; 82 struct port_list dports = {0, NULL, };
97 struct port *oport = tipc_port_deref(ref); 83 struct tipc_port *oport = tipc_port_deref(ref);
98 int ext_targets; 84 int ext_targets;
99 int res; 85 int res;
100 86
@@ -103,7 +89,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
103 89
104 /* Create multicast message */ 90 /* Create multicast message */
105 91
106 hdr = &oport->publ.phdr; 92 hdr = &oport->phdr;
107 msg_set_type(hdr, TIPC_MCAST_MSG); 93 msg_set_type(hdr, TIPC_MCAST_MSG);
108 msg_set_nametype(hdr, seq->type); 94 msg_set_nametype(hdr, seq->type);
109 msg_set_namelower(hdr, seq->lower); 95 msg_set_namelower(hdr, seq->lower);
@@ -211,7 +197,7 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
211 void (*wakeup)(struct tipc_port *), 197 void (*wakeup)(struct tipc_port *),
212 const u32 importance) 198 const u32 importance)
213{ 199{
214 struct port *p_ptr; 200 struct tipc_port *p_ptr;
215 struct tipc_msg *msg; 201 struct tipc_msg *msg;
216 u32 ref; 202 u32 ref;
217 203
@@ -220,21 +206,19 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
220 warn("Port creation failed, no memory\n"); 206 warn("Port creation failed, no memory\n");
221 return NULL; 207 return NULL;
222 } 208 }
223 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 209 ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
224 if (!ref) { 210 if (!ref) {
225 warn("Port creation failed, reference table exhausted\n"); 211 warn("Port creation failed, reference table exhausted\n");
226 kfree(p_ptr); 212 kfree(p_ptr);
227 return NULL; 213 return NULL;
228 } 214 }
229 215
230 p_ptr->publ.usr_handle = usr_handle; 216 p_ptr->usr_handle = usr_handle;
231 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 217 p_ptr->max_pkt = MAX_PKT_DEFAULT;
232 p_ptr->publ.ref = ref; 218 p_ptr->ref = ref;
233 msg = &p_ptr->publ.phdr; 219 msg = &p_ptr->phdr;
234 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 220 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
235 msg_set_origport(msg, ref); 221 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); 222 INIT_LIST_HEAD(&p_ptr->wait_list);
239 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 223 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
240 p_ptr->dispatcher = dispatcher; 224 p_ptr->dispatcher = dispatcher;
@@ -246,12 +230,12 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
246 INIT_LIST_HEAD(&p_ptr->port_list); 230 INIT_LIST_HEAD(&p_ptr->port_list);
247 list_add_tail(&p_ptr->port_list, &ports); 231 list_add_tail(&p_ptr->port_list, &ports);
248 spin_unlock_bh(&tipc_port_list_lock); 232 spin_unlock_bh(&tipc_port_list_lock);
249 return &(p_ptr->publ); 233 return p_ptr;
250} 234}
251 235
252int tipc_deleteport(u32 ref) 236int tipc_deleteport(u32 ref)
253{ 237{
254 struct port *p_ptr; 238 struct tipc_port *p_ptr;
255 struct sk_buff *buf = NULL; 239 struct sk_buff *buf = NULL;
256 240
257 tipc_withdraw(ref, 0, NULL); 241 tipc_withdraw(ref, 0, NULL);
@@ -263,7 +247,7 @@ int tipc_deleteport(u32 ref)
263 tipc_port_unlock(p_ptr); 247 tipc_port_unlock(p_ptr);
264 248
265 k_cancel_timer(&p_ptr->timer); 249 k_cancel_timer(&p_ptr->timer);
266 if (p_ptr->publ.connected) { 250 if (p_ptr->connected) {
267 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 251 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
268 tipc_nodesub_unsubscribe(&p_ptr->subscription); 252 tipc_nodesub_unsubscribe(&p_ptr->subscription);
269 } 253 }
@@ -279,14 +263,14 @@ int tipc_deleteport(u32 ref)
279 return 0; 263 return 0;
280} 264}
281 265
282static int port_unreliable(struct port *p_ptr) 266static int port_unreliable(struct tipc_port *p_ptr)
283{ 267{
284 return msg_src_droppable(&p_ptr->publ.phdr); 268 return msg_src_droppable(&p_ptr->phdr);
285} 269}
286 270
287int tipc_portunreliable(u32 ref, unsigned int *isunreliable) 271int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
288{ 272{
289 struct port *p_ptr; 273 struct tipc_port *p_ptr;
290 274
291 p_ptr = tipc_port_lock(ref); 275 p_ptr = tipc_port_lock(ref);
292 if (!p_ptr) 276 if (!p_ptr)
@@ -298,24 +282,24 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
298 282
299int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 283int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
300{ 284{
301 struct port *p_ptr; 285 struct tipc_port *p_ptr;
302 286
303 p_ptr = tipc_port_lock(ref); 287 p_ptr = tipc_port_lock(ref);
304 if (!p_ptr) 288 if (!p_ptr)
305 return -EINVAL; 289 return -EINVAL;
306 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 290 msg_set_src_droppable(&p_ptr->phdr, (isunreliable != 0));
307 tipc_port_unlock(p_ptr); 291 tipc_port_unlock(p_ptr);
308 return 0; 292 return 0;
309} 293}
310 294
311static int port_unreturnable(struct port *p_ptr) 295static int port_unreturnable(struct tipc_port *p_ptr)
312{ 296{
313 return msg_dest_droppable(&p_ptr->publ.phdr); 297 return msg_dest_droppable(&p_ptr->phdr);
314} 298}
315 299
316int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) 300int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
317{ 301{
318 struct port *p_ptr; 302 struct tipc_port *p_ptr;
319 303
320 p_ptr = tipc_port_lock(ref); 304 p_ptr = tipc_port_lock(ref);
321 if (!p_ptr) 305 if (!p_ptr)
@@ -327,12 +311,12 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
327 311
328int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 312int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
329{ 313{
330 struct port *p_ptr; 314 struct tipc_port *p_ptr;
331 315
332 p_ptr = tipc_port_lock(ref); 316 p_ptr = tipc_port_lock(ref);
333 if (!p_ptr) 317 if (!p_ptr)
334 return -EINVAL; 318 return -EINVAL;
335 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 319 msg_set_dest_droppable(&p_ptr->phdr, (isunrejectable != 0));
336 tipc_port_unlock(p_ptr); 320 tipc_port_unlock(p_ptr);
337 return 0; 321 return 0;
338} 322}
@@ -345,7 +329,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
345static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, 329static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
346 u32 origport, u32 orignode, 330 u32 origport, u32 orignode,
347 u32 usr, u32 type, u32 err, 331 u32 usr, u32 type, u32 err,
348 u32 seqno, u32 ack) 332 u32 ack)
349{ 333{
350 struct sk_buff *buf; 334 struct sk_buff *buf;
351 struct tipc_msg *msg; 335 struct tipc_msg *msg;
@@ -358,7 +342,6 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
358 msg_set_destport(msg, destport); 342 msg_set_destport(msg, destport);
359 msg_set_origport(msg, origport); 343 msg_set_origport(msg, origport);
360 msg_set_orignode(msg, orignode); 344 msg_set_orignode(msg, orignode);
361 msg_set_transp_seqno(msg, seqno);
362 msg_set_msgcnt(msg, ack); 345 msg_set_msgcnt(msg, ack);
363 } 346 }
364 return buf; 347 return buf;
@@ -413,10 +396,10 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
413 /* send self-abort message when rejecting on a connected port */ 396 /* send self-abort message when rejecting on a connected port */
414 if (msg_connected(msg)) { 397 if (msg_connected(msg)) {
415 struct sk_buff *abuf = NULL; 398 struct sk_buff *abuf = NULL;
416 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 399 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
417 400
418 if (p_ptr) { 401 if (p_ptr) {
419 if (p_ptr->publ.connected) 402 if (p_ptr->connected)
420 abuf = port_build_self_abort_msg(p_ptr, err); 403 abuf = port_build_self_abort_msg(p_ptr, err);
421 tipc_port_unlock(p_ptr); 404 tipc_port_unlock(p_ptr);
422 } 405 }
@@ -429,7 +412,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
429 return data_sz; 412 return data_sz;
430} 413}
431 414
432int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 415int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
433 struct iovec const *msg_sect, u32 num_sect, 416 struct iovec const *msg_sect, u32 num_sect,
434 int err) 417 int err)
435{ 418{
@@ -446,13 +429,13 @@ int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
446 429
447static void port_timeout(unsigned long ref) 430static void port_timeout(unsigned long ref)
448{ 431{
449 struct port *p_ptr = tipc_port_lock(ref); 432 struct tipc_port *p_ptr = tipc_port_lock(ref);
450 struct sk_buff *buf = NULL; 433 struct sk_buff *buf = NULL;
451 434
452 if (!p_ptr) 435 if (!p_ptr)
453 return; 436 return;
454 437
455 if (!p_ptr->publ.connected) { 438 if (!p_ptr->connected) {
456 tipc_port_unlock(p_ptr); 439 tipc_port_unlock(p_ptr);
457 return; 440 return;
458 } 441 }
@@ -463,14 +446,12 @@ static void port_timeout(unsigned long ref)
463 } else { 446 } else {
464 buf = port_build_proto_msg(port_peerport(p_ptr), 447 buf = port_build_proto_msg(port_peerport(p_ptr),
465 port_peernode(p_ptr), 448 port_peernode(p_ptr),
466 p_ptr->publ.ref, 449 p_ptr->ref,
467 tipc_own_addr, 450 tipc_own_addr,
468 CONN_MANAGER, 451 CONN_MANAGER,
469 CONN_PROBE, 452 CONN_PROBE,
470 TIPC_OK, 453 TIPC_OK,
471 port_out_seqno(p_ptr),
472 0); 454 0);
473 port_incr_out_seqno(p_ptr);
474 p_ptr->probing_state = PROBING; 455 p_ptr->probing_state = PROBING;
475 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 456 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
476 } 457 }
@@ -481,7 +462,7 @@ static void port_timeout(unsigned long ref)
481 462
482static void port_handle_node_down(unsigned long ref) 463static void port_handle_node_down(unsigned long ref)
483{ 464{
484 struct port *p_ptr = tipc_port_lock(ref); 465 struct tipc_port *p_ptr = tipc_port_lock(ref);
485 struct sk_buff *buf = NULL; 466 struct sk_buff *buf = NULL;
486 467
487 if (!p_ptr) 468 if (!p_ptr)
@@ -492,73 +473,71 @@ static void port_handle_node_down(unsigned long ref)
492} 473}
493 474
494 475
495static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err) 476static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
496{ 477{
497 u32 imp = msg_importance(&p_ptr->publ.phdr); 478 u32 imp = msg_importance(&p_ptr->phdr);
498 479
499 if (!p_ptr->publ.connected) 480 if (!p_ptr->connected)
500 return NULL; 481 return NULL;
501 if (imp < TIPC_CRITICAL_IMPORTANCE) 482 if (imp < TIPC_CRITICAL_IMPORTANCE)
502 imp++; 483 imp++;
503 return port_build_proto_msg(p_ptr->publ.ref, 484 return port_build_proto_msg(p_ptr->ref,
504 tipc_own_addr, 485 tipc_own_addr,
505 port_peerport(p_ptr), 486 port_peerport(p_ptr),
506 port_peernode(p_ptr), 487 port_peernode(p_ptr),
507 imp, 488 imp,
508 TIPC_CONN_MSG, 489 TIPC_CONN_MSG,
509 err, 490 err,
510 p_ptr->last_in_seqno + 1,
511 0); 491 0);
512} 492}
513 493
514 494
515static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err) 495static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
516{ 496{
517 u32 imp = msg_importance(&p_ptr->publ.phdr); 497 u32 imp = msg_importance(&p_ptr->phdr);
518 498
519 if (!p_ptr->publ.connected) 499 if (!p_ptr->connected)
520 return NULL; 500 return NULL;
521 if (imp < TIPC_CRITICAL_IMPORTANCE) 501 if (imp < TIPC_CRITICAL_IMPORTANCE)
522 imp++; 502 imp++;
523 return port_build_proto_msg(port_peerport(p_ptr), 503 return port_build_proto_msg(port_peerport(p_ptr),
524 port_peernode(p_ptr), 504 port_peernode(p_ptr),
525 p_ptr->publ.ref, 505 p_ptr->ref,
526 tipc_own_addr, 506 tipc_own_addr,
527 imp, 507 imp,
528 TIPC_CONN_MSG, 508 TIPC_CONN_MSG,
529 err, 509 err,
530 port_out_seqno(p_ptr),
531 0); 510 0);
532} 511}
533 512
534void tipc_port_recv_proto_msg(struct sk_buff *buf) 513void tipc_port_recv_proto_msg(struct sk_buff *buf)
535{ 514{
536 struct tipc_msg *msg = buf_msg(buf); 515 struct tipc_msg *msg = buf_msg(buf);
537 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 516 struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
538 u32 err = TIPC_OK; 517 u32 err = TIPC_OK;
539 struct sk_buff *r_buf = NULL; 518 struct sk_buff *r_buf = NULL;
540 struct sk_buff *abort_buf = NULL; 519 struct sk_buff *abort_buf = NULL;
541 520
542 if (!p_ptr) { 521 if (!p_ptr) {
543 err = TIPC_ERR_NO_PORT; 522 err = TIPC_ERR_NO_PORT;
544 } else if (p_ptr->publ.connected) { 523 } else if (p_ptr->connected) {
545 if ((port_peernode(p_ptr) != msg_orignode(msg)) || 524 if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
546 (port_peerport(p_ptr) != msg_origport(msg))) { 525 (port_peerport(p_ptr) != msg_origport(msg))) {
547 err = TIPC_ERR_NO_PORT; 526 err = TIPC_ERR_NO_PORT;
548 } else if (msg_type(msg) == CONN_ACK) { 527 } else if (msg_type(msg) == CONN_ACK) {
549 int wakeup = tipc_port_congested(p_ptr) && 528 int wakeup = tipc_port_congested(p_ptr) &&
550 p_ptr->publ.congested && 529 p_ptr->congested &&
551 p_ptr->wakeup; 530 p_ptr->wakeup;
552 p_ptr->acked += msg_msgcnt(msg); 531 p_ptr->acked += msg_msgcnt(msg);
553 if (tipc_port_congested(p_ptr)) 532 if (tipc_port_congested(p_ptr))
554 goto exit; 533 goto exit;
555 p_ptr->publ.congested = 0; 534 p_ptr->congested = 0;
556 if (!wakeup) 535 if (!wakeup)
557 goto exit; 536 goto exit;
558 p_ptr->wakeup(&p_ptr->publ); 537 p_ptr->wakeup(p_ptr);
559 goto exit; 538 goto exit;
560 } 539 }
561 } else if (p_ptr->publ.published) { 540 } else if (p_ptr->published) {
562 err = TIPC_ERR_NO_PORT; 541 err = TIPC_ERR_NO_PORT;
563 } 542 }
564 if (err) { 543 if (err) {
@@ -569,7 +548,6 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
569 TIPC_HIGH_IMPORTANCE, 548 TIPC_HIGH_IMPORTANCE,
570 TIPC_CONN_MSG, 549 TIPC_CONN_MSG,
571 err, 550 err,
572 0,
573 0); 551 0);
574 goto exit; 552 goto exit;
575 } 553 }
@@ -583,11 +561,9 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf)
583 CONN_MANAGER, 561 CONN_MANAGER,
584 CONN_PROBE_REPLY, 562 CONN_PROBE_REPLY,
585 TIPC_OK, 563 TIPC_OK,
586 port_out_seqno(p_ptr),
587 0); 564 0);
588 } 565 }
589 p_ptr->probing_state = CONFIRMED; 566 p_ptr->probing_state = CONFIRMED;
590 port_incr_out_seqno(p_ptr);
591exit: 567exit:
592 if (p_ptr) 568 if (p_ptr)
593 tipc_port_unlock(p_ptr); 569 tipc_port_unlock(p_ptr);
@@ -596,29 +572,29 @@ exit:
596 buf_discard(buf); 572 buf_discard(buf);
597} 573}
598 574
599static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) 575static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id)
600{ 576{
601 struct publication *publ; 577 struct publication *publ;
602 578
603 if (full_id) 579 if (full_id)
604 tipc_printf(buf, "<%u.%u.%u:%u>:", 580 tipc_printf(buf, "<%u.%u.%u:%u>:",
605 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 581 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
606 tipc_node(tipc_own_addr), p_ptr->publ.ref); 582 tipc_node(tipc_own_addr), p_ptr->ref);
607 else 583 else
608 tipc_printf(buf, "%-10u:", p_ptr->publ.ref); 584 tipc_printf(buf, "%-10u:", p_ptr->ref);
609 585
610 if (p_ptr->publ.connected) { 586 if (p_ptr->connected) {
611 u32 dport = port_peerport(p_ptr); 587 u32 dport = port_peerport(p_ptr);
612 u32 destnode = port_peernode(p_ptr); 588 u32 destnode = port_peernode(p_ptr);
613 589
614 tipc_printf(buf, " connected to <%u.%u.%u:%u>", 590 tipc_printf(buf, " connected to <%u.%u.%u:%u>",
615 tipc_zone(destnode), tipc_cluster(destnode), 591 tipc_zone(destnode), tipc_cluster(destnode),
616 tipc_node(destnode), dport); 592 tipc_node(destnode), dport);
617 if (p_ptr->publ.conn_type != 0) 593 if (p_ptr->conn_type != 0)
618 tipc_printf(buf, " via {%u,%u}", 594 tipc_printf(buf, " via {%u,%u}",
619 p_ptr->publ.conn_type, 595 p_ptr->conn_type,
620 p_ptr->publ.conn_instance); 596 p_ptr->conn_instance);
621 } else if (p_ptr->publ.published) { 597 } else if (p_ptr->published) {
622 tipc_printf(buf, " bound to"); 598 tipc_printf(buf, " bound to");
623 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 599 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
624 if (publ->lower == publ->upper) 600 if (publ->lower == publ->upper)
@@ -639,7 +615,7 @@ struct sk_buff *tipc_port_get_ports(void)
639 struct sk_buff *buf; 615 struct sk_buff *buf;
640 struct tlv_desc *rep_tlv; 616 struct tlv_desc *rep_tlv;
641 struct print_buf pb; 617 struct print_buf pb;
642 struct port *p_ptr; 618 struct tipc_port *p_ptr;
643 int str_len; 619 int str_len;
644 620
645 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); 621 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
@@ -650,9 +626,9 @@ struct sk_buff *tipc_port_get_ports(void)
650 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); 626 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
651 spin_lock_bh(&tipc_port_list_lock); 627 spin_lock_bh(&tipc_port_list_lock);
652 list_for_each_entry(p_ptr, &ports, port_list) { 628 list_for_each_entry(p_ptr, &ports, port_list) {
653 spin_lock_bh(p_ptr->publ.lock); 629 spin_lock_bh(p_ptr->lock);
654 port_print(p_ptr, &pb, 0); 630 port_print(p_ptr, &pb, 0);
655 spin_unlock_bh(p_ptr->publ.lock); 631 spin_unlock_bh(p_ptr->lock);
656 } 632 }
657 spin_unlock_bh(&tipc_port_list_lock); 633 spin_unlock_bh(&tipc_port_list_lock);
658 str_len = tipc_printbuf_validate(&pb); 634 str_len = tipc_printbuf_validate(&pb);
@@ -665,12 +641,12 @@ struct sk_buff *tipc_port_get_ports(void)
665 641
666void tipc_port_reinit(void) 642void tipc_port_reinit(void)
667{ 643{
668 struct port *p_ptr; 644 struct tipc_port *p_ptr;
669 struct tipc_msg *msg; 645 struct tipc_msg *msg;
670 646
671 spin_lock_bh(&tipc_port_list_lock); 647 spin_lock_bh(&tipc_port_list_lock);
672 list_for_each_entry(p_ptr, &ports, port_list) { 648 list_for_each_entry(p_ptr, &ports, port_list) {
673 msg = &p_ptr->publ.phdr; 649 msg = &p_ptr->phdr;
674 if (msg_orignode(msg) == tipc_own_addr) 650 if (msg_orignode(msg) == tipc_own_addr)
675 break; 651 break;
676 msg_set_prevnode(msg, tipc_own_addr); 652 msg_set_prevnode(msg, tipc_own_addr);
@@ -695,7 +671,7 @@ static void port_dispatcher_sigh(void *dummy)
695 spin_unlock_bh(&queue_lock); 671 spin_unlock_bh(&queue_lock);
696 672
697 while (buf) { 673 while (buf) {
698 struct port *p_ptr; 674 struct tipc_port *p_ptr;
699 struct user_port *up_ptr; 675 struct user_port *up_ptr;
700 struct tipc_portid orig; 676 struct tipc_portid orig;
701 struct tipc_name_seq dseq; 677 struct tipc_name_seq dseq;
@@ -720,8 +696,8 @@ static void port_dispatcher_sigh(void *dummy)
720 orig.node = msg_orignode(msg); 696 orig.node = msg_orignode(msg);
721 up_ptr = p_ptr->user_port; 697 up_ptr = p_ptr->user_port;
722 usr_handle = up_ptr->usr_handle; 698 usr_handle = up_ptr->usr_handle;
723 connected = p_ptr->publ.connected; 699 connected = p_ptr->connected;
724 published = p_ptr->publ.published; 700 published = p_ptr->published;
725 701
726 if (unlikely(msg_errcode(msg))) 702 if (unlikely(msg_errcode(msg)))
727 goto err; 703 goto err;
@@ -732,6 +708,7 @@ static void port_dispatcher_sigh(void *dummy)
732 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 708 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
733 u32 peer_port = port_peerport(p_ptr); 709 u32 peer_port = port_peerport(p_ptr);
734 u32 peer_node = port_peernode(p_ptr); 710 u32 peer_node = port_peernode(p_ptr);
711 u32 dsz;
735 712
736 tipc_port_unlock(p_ptr); 713 tipc_port_unlock(p_ptr);
737 if (unlikely(!cb)) 714 if (unlikely(!cb))
@@ -742,13 +719,14 @@ static void port_dispatcher_sigh(void *dummy)
742 } else if ((msg_origport(msg) != peer_port) || 719 } else if ((msg_origport(msg) != peer_port) ||
743 (msg_orignode(msg) != peer_node)) 720 (msg_orignode(msg) != peer_node))
744 goto reject; 721 goto reject;
745 if (unlikely(++p_ptr->publ.conn_unacked >= 722 dsz = msg_data_sz(msg);
746 TIPC_FLOW_CONTROL_WIN)) 723 if (unlikely(dsz &&
724 (++p_ptr->conn_unacked >=
725 TIPC_FLOW_CONTROL_WIN)))
747 tipc_acknowledge(dref, 726 tipc_acknowledge(dref,
748 p_ptr->publ.conn_unacked); 727 p_ptr->conn_unacked);
749 skb_pull(buf, msg_hdr_sz(msg)); 728 skb_pull(buf, msg_hdr_sz(msg));
750 cb(usr_handle, dref, &buf, msg_data(msg), 729 cb(usr_handle, dref, &buf, msg_data(msg), dsz);
751 msg_data_sz(msg));
752 break; 730 break;
753 } 731 }
754 case TIPC_DIRECT_MSG:{ 732 case TIPC_DIRECT_MSG:{
@@ -872,7 +850,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
872 850
873static void port_wakeup_sh(unsigned long ref) 851static void port_wakeup_sh(unsigned long ref)
874{ 852{
875 struct port *p_ptr; 853 struct tipc_port *p_ptr;
876 struct user_port *up_ptr; 854 struct user_port *up_ptr;
877 tipc_continue_event cb = NULL; 855 tipc_continue_event cb = NULL;
878 void *uh = NULL; 856 void *uh = NULL;
@@ -898,14 +876,14 @@ static void port_wakeup(struct tipc_port *p_ptr)
898 876
899void tipc_acknowledge(u32 ref, u32 ack) 877void tipc_acknowledge(u32 ref, u32 ack)
900{ 878{
901 struct port *p_ptr; 879 struct tipc_port *p_ptr;
902 struct sk_buff *buf = NULL; 880 struct sk_buff *buf = NULL;
903 881
904 p_ptr = tipc_port_lock(ref); 882 p_ptr = tipc_port_lock(ref);
905 if (!p_ptr) 883 if (!p_ptr)
906 return; 884 return;
907 if (p_ptr->publ.connected) { 885 if (p_ptr->connected) {
908 p_ptr->publ.conn_unacked -= ack; 886 p_ptr->conn_unacked -= ack;
909 buf = port_build_proto_msg(port_peerport(p_ptr), 887 buf = port_build_proto_msg(port_peerport(p_ptr),
910 port_peernode(p_ptr), 888 port_peernode(p_ptr),
911 ref, 889 ref,
@@ -913,7 +891,6 @@ void tipc_acknowledge(u32 ref, u32 ack)
913 CONN_MANAGER, 891 CONN_MANAGER,
914 CONN_ACK, 892 CONN_ACK,
915 TIPC_OK, 893 TIPC_OK,
916 port_out_seqno(p_ptr),
917 ack); 894 ack);
918 } 895 }
919 tipc_port_unlock(p_ptr); 896 tipc_port_unlock(p_ptr);
@@ -936,14 +913,14 @@ int tipc_createport(void *usr_handle,
936 u32 *portref) 913 u32 *portref)
937{ 914{
938 struct user_port *up_ptr; 915 struct user_port *up_ptr;
939 struct port *p_ptr; 916 struct tipc_port *p_ptr;
940 917
941 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 918 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
942 if (!up_ptr) { 919 if (!up_ptr) {
943 warn("Port creation failed, no memory\n"); 920 warn("Port creation failed, no memory\n");
944 return -ENOMEM; 921 return -ENOMEM;
945 } 922 }
946 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, 923 p_ptr = (struct tipc_port *)tipc_createport_raw(NULL, port_dispatcher,
947 port_wakeup, importance); 924 port_wakeup, importance);
948 if (!p_ptr) { 925 if (!p_ptr) {
949 kfree(up_ptr); 926 kfree(up_ptr);
@@ -952,7 +929,7 @@ int tipc_createport(void *usr_handle,
952 929
953 p_ptr->user_port = up_ptr; 930 p_ptr->user_port = up_ptr;
954 up_ptr->usr_handle = usr_handle; 931 up_ptr->usr_handle = usr_handle;
955 up_ptr->ref = p_ptr->publ.ref; 932 up_ptr->ref = p_ptr->ref;
956 up_ptr->err_cb = error_cb; 933 up_ptr->err_cb = error_cb;
957 up_ptr->named_err_cb = named_error_cb; 934 up_ptr->named_err_cb = named_error_cb;
958 up_ptr->conn_err_cb = conn_error_cb; 935 up_ptr->conn_err_cb = conn_error_cb;
@@ -960,26 +937,26 @@ int tipc_createport(void *usr_handle,
960 up_ptr->named_msg_cb = named_msg_cb; 937 up_ptr->named_msg_cb = named_msg_cb;
961 up_ptr->conn_msg_cb = conn_msg_cb; 938 up_ptr->conn_msg_cb = conn_msg_cb;
962 up_ptr->continue_event_cb = continue_event_cb; 939 up_ptr->continue_event_cb = continue_event_cb;
963 *portref = p_ptr->publ.ref; 940 *portref = p_ptr->ref;
964 tipc_port_unlock(p_ptr); 941 tipc_port_unlock(p_ptr);
965 return 0; 942 return 0;
966} 943}
967 944
968int tipc_portimportance(u32 ref, unsigned int *importance) 945int tipc_portimportance(u32 ref, unsigned int *importance)
969{ 946{
970 struct port *p_ptr; 947 struct tipc_port *p_ptr;
971 948
972 p_ptr = tipc_port_lock(ref); 949 p_ptr = tipc_port_lock(ref);
973 if (!p_ptr) 950 if (!p_ptr)
974 return -EINVAL; 951 return -EINVAL;
975 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 952 *importance = (unsigned int)msg_importance(&p_ptr->phdr);
976 tipc_port_unlock(p_ptr); 953 tipc_port_unlock(p_ptr);
977 return 0; 954 return 0;
978} 955}
979 956
980int tipc_set_portimportance(u32 ref, unsigned int imp) 957int tipc_set_portimportance(u32 ref, unsigned int imp)
981{ 958{
982 struct port *p_ptr; 959 struct tipc_port *p_ptr;
983 960
984 if (imp > TIPC_CRITICAL_IMPORTANCE) 961 if (imp > TIPC_CRITICAL_IMPORTANCE)
985 return -EINVAL; 962 return -EINVAL;
@@ -987,7 +964,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
987 p_ptr = tipc_port_lock(ref); 964 p_ptr = tipc_port_lock(ref);
988 if (!p_ptr) 965 if (!p_ptr)
989 return -EINVAL; 966 return -EINVAL;
990 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 967 msg_set_importance(&p_ptr->phdr, (u32)imp);
991 tipc_port_unlock(p_ptr); 968 tipc_port_unlock(p_ptr);
992 return 0; 969 return 0;
993} 970}
@@ -995,7 +972,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
995 972
996int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 973int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
997{ 974{
998 struct port *p_ptr; 975 struct tipc_port *p_ptr;
999 struct publication *publ; 976 struct publication *publ;
1000 u32 key; 977 u32 key;
1001 int res = -EINVAL; 978 int res = -EINVAL;
@@ -1004,7 +981,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1004 if (!p_ptr) 981 if (!p_ptr)
1005 return -EINVAL; 982 return -EINVAL;
1006 983
1007 if (p_ptr->publ.connected) 984 if (p_ptr->connected)
1008 goto exit; 985 goto exit;
1009 if (seq->lower > seq->upper) 986 if (seq->lower > seq->upper)
1010 goto exit; 987 goto exit;
@@ -1016,11 +993,11 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1016 goto exit; 993 goto exit;
1017 } 994 }
1018 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 995 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
1019 scope, p_ptr->publ.ref, key); 996 scope, p_ptr->ref, key);
1020 if (publ) { 997 if (publ) {
1021 list_add(&publ->pport_list, &p_ptr->publications); 998 list_add(&publ->pport_list, &p_ptr->publications);
1022 p_ptr->pub_count++; 999 p_ptr->pub_count++;
1023 p_ptr->publ.published = 1; 1000 p_ptr->published = 1;
1024 res = 0; 1001 res = 0;
1025 } 1002 }
1026exit: 1003exit:
@@ -1030,7 +1007,7 @@ exit:
1030 1007
1031int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 1008int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1032{ 1009{
1033 struct port *p_ptr; 1010 struct tipc_port *p_ptr;
1034 struct publication *publ; 1011 struct publication *publ;
1035 struct publication *tpubl; 1012 struct publication *tpubl;
1036 int res = -EINVAL; 1013 int res = -EINVAL;
@@ -1063,37 +1040,36 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1063 } 1040 }
1064 } 1041 }
1065 if (list_empty(&p_ptr->publications)) 1042 if (list_empty(&p_ptr->publications))
1066 p_ptr->publ.published = 0; 1043 p_ptr->published = 0;
1067 tipc_port_unlock(p_ptr); 1044 tipc_port_unlock(p_ptr);
1068 return res; 1045 return res;
1069} 1046}
1070 1047
1071int tipc_connect2port(u32 ref, struct tipc_portid const *peer) 1048int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1072{ 1049{
1073 struct port *p_ptr; 1050 struct tipc_port *p_ptr;
1074 struct tipc_msg *msg; 1051 struct tipc_msg *msg;
1075 int res = -EINVAL; 1052 int res = -EINVAL;
1076 1053
1077 p_ptr = tipc_port_lock(ref); 1054 p_ptr = tipc_port_lock(ref);
1078 if (!p_ptr) 1055 if (!p_ptr)
1079 return -EINVAL; 1056 return -EINVAL;
1080 if (p_ptr->publ.published || p_ptr->publ.connected) 1057 if (p_ptr->published || p_ptr->connected)
1081 goto exit; 1058 goto exit;
1082 if (!peer->ref) 1059 if (!peer->ref)
1083 goto exit; 1060 goto exit;
1084 1061
1085 msg = &p_ptr->publ.phdr; 1062 msg = &p_ptr->phdr;
1086 msg_set_destnode(msg, peer->node); 1063 msg_set_destnode(msg, peer->node);
1087 msg_set_destport(msg, peer->ref); 1064 msg_set_destport(msg, peer->ref);
1088 msg_set_orignode(msg, tipc_own_addr); 1065 msg_set_orignode(msg, tipc_own_addr);
1089 msg_set_origport(msg, p_ptr->publ.ref); 1066 msg_set_origport(msg, p_ptr->ref);
1090 msg_set_transp_seqno(msg, 42);
1091 msg_set_type(msg, TIPC_CONN_MSG); 1067 msg_set_type(msg, TIPC_CONN_MSG);
1092 msg_set_hdr_sz(msg, SHORT_H_SIZE); 1068 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1093 1069
1094 p_ptr->probing_interval = PROBING_INTERVAL; 1070 p_ptr->probing_interval = PROBING_INTERVAL;
1095 p_ptr->probing_state = CONFIRMED; 1071 p_ptr->probing_state = CONFIRMED;
1096 p_ptr->publ.connected = 1; 1072 p_ptr->connected = 1;
1097 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 1073 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
1098 1074
1099 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node, 1075 tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
@@ -1102,7 +1078,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1102 res = 0; 1078 res = 0;
1103exit: 1079exit:
1104 tipc_port_unlock(p_ptr); 1080 tipc_port_unlock(p_ptr);
1105 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1081 p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
1106 return res; 1082 return res;
1107} 1083}
1108 1084
@@ -1120,7 +1096,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1120 tp_ptr->connected = 0; 1096 tp_ptr->connected = 0;
1121 /* let timer expire on it's own to avoid deadlock! */ 1097 /* let timer expire on it's own to avoid deadlock! */
1122 tipc_nodesub_unsubscribe( 1098 tipc_nodesub_unsubscribe(
1123 &((struct port *)tp_ptr)->subscription); 1099 &((struct tipc_port *)tp_ptr)->subscription);
1124 res = 0; 1100 res = 0;
1125 } else { 1101 } else {
1126 res = -ENOTCONN; 1102 res = -ENOTCONN;
@@ -1135,7 +1111,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1135 1111
1136int tipc_disconnect(u32 ref) 1112int tipc_disconnect(u32 ref)
1137{ 1113{
1138 struct port *p_ptr; 1114 struct tipc_port *p_ptr;
1139 int res; 1115 int res;
1140 1116
1141 p_ptr = tipc_port_lock(ref); 1117 p_ptr = tipc_port_lock(ref);
@@ -1151,15 +1127,15 @@ int tipc_disconnect(u32 ref)
1151 */ 1127 */
1152int tipc_shutdown(u32 ref) 1128int tipc_shutdown(u32 ref)
1153{ 1129{
1154 struct port *p_ptr; 1130 struct tipc_port *p_ptr;
1155 struct sk_buff *buf = NULL; 1131 struct sk_buff *buf = NULL;
1156 1132
1157 p_ptr = tipc_port_lock(ref); 1133 p_ptr = tipc_port_lock(ref);
1158 if (!p_ptr) 1134 if (!p_ptr)
1159 return -EINVAL; 1135 return -EINVAL;
1160 1136
1161 if (p_ptr->publ.connected) { 1137 if (p_ptr->connected) {
1162 u32 imp = msg_importance(&p_ptr->publ.phdr); 1138 u32 imp = msg_importance(&p_ptr->phdr);
1163 if (imp < TIPC_CRITICAL_IMPORTANCE) 1139 if (imp < TIPC_CRITICAL_IMPORTANCE)
1164 imp++; 1140 imp++;
1165 buf = port_build_proto_msg(port_peerport(p_ptr), 1141 buf = port_build_proto_msg(port_peerport(p_ptr),
@@ -1169,7 +1145,6 @@ int tipc_shutdown(u32 ref)
1169 imp, 1145 imp,
1170 TIPC_CONN_MSG, 1146 TIPC_CONN_MSG,
1171 TIPC_CONN_SHUTDOWN, 1147 TIPC_CONN_SHUTDOWN,
1172 port_out_seqno(p_ptr),
1173 0); 1148 0);
1174 } 1149 }
1175 tipc_port_unlock(p_ptr); 1150 tipc_port_unlock(p_ptr);
@@ -1182,13 +1157,13 @@ int tipc_shutdown(u32 ref)
1182 * message for this node. 1157 * message for this node.
1183 */ 1158 */
1184 1159
1185static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, 1160static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect,
1186 struct iovec const *msg_sect) 1161 struct iovec const *msg_sect)
1187{ 1162{
1188 struct sk_buff *buf; 1163 struct sk_buff *buf;
1189 int res; 1164 int res;
1190 1165
1191 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect, 1166 res = tipc_msg_build(&sender->phdr, msg_sect, num_sect,
1192 MAX_MSG_SIZE, !sender->user_port, &buf); 1167 MAX_MSG_SIZE, !sender->user_port, &buf);
1193 if (likely(buf)) 1168 if (likely(buf))
1194 tipc_port_recv_msg(buf); 1169 tipc_port_recv_msg(buf);
@@ -1201,15 +1176,15 @@ static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
1201 1176
1202int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) 1177int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1203{ 1178{
1204 struct port *p_ptr; 1179 struct tipc_port *p_ptr;
1205 u32 destnode; 1180 u32 destnode;
1206 int res; 1181 int res;
1207 1182
1208 p_ptr = tipc_port_deref(ref); 1183 p_ptr = tipc_port_deref(ref);
1209 if (!p_ptr || !p_ptr->publ.connected) 1184 if (!p_ptr || !p_ptr->connected)
1210 return -EINVAL; 1185 return -EINVAL;
1211 1186
1212 p_ptr->publ.congested = 1; 1187 p_ptr->congested = 1;
1213 if (!tipc_port_congested(p_ptr)) { 1188 if (!tipc_port_congested(p_ptr)) {
1214 destnode = port_peernode(p_ptr); 1189 destnode = port_peernode(p_ptr);
1215 if (likely(destnode != tipc_own_addr)) 1190 if (likely(destnode != tipc_own_addr))
@@ -1219,14 +1194,14 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1219 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1194 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1220 1195
1221 if (likely(res != -ELINKCONG)) { 1196 if (likely(res != -ELINKCONG)) {
1222 port_incr_out_seqno(p_ptr); 1197 p_ptr->congested = 0;
1223 p_ptr->publ.congested = 0; 1198 if (res > 0)
1224 p_ptr->sent++; 1199 p_ptr->sent++;
1225 return res; 1200 return res;
1226 } 1201 }
1227 } 1202 }
1228 if (port_unreliable(p_ptr)) { 1203 if (port_unreliable(p_ptr)) {
1229 p_ptr->publ.congested = 0; 1204 p_ptr->congested = 0;
1230 /* Just calculate msg length and return */ 1205 /* Just calculate msg length and return */
1231 return tipc_msg_calc_data_size(msg_sect, num_sect); 1206 return tipc_msg_calc_data_size(msg_sect, num_sect);
1232 } 1207 }
@@ -1240,17 +1215,17 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1240int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, 1215int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1241 unsigned int num_sect, struct iovec const *msg_sect) 1216 unsigned int num_sect, struct iovec const *msg_sect)
1242{ 1217{
1243 struct port *p_ptr; 1218 struct tipc_port *p_ptr;
1244 struct tipc_msg *msg; 1219 struct tipc_msg *msg;
1245 u32 destnode = domain; 1220 u32 destnode = domain;
1246 u32 destport; 1221 u32 destport;
1247 int res; 1222 int res;
1248 1223
1249 p_ptr = tipc_port_deref(ref); 1224 p_ptr = tipc_port_deref(ref);
1250 if (!p_ptr || p_ptr->publ.connected) 1225 if (!p_ptr || p_ptr->connected)
1251 return -EINVAL; 1226 return -EINVAL;
1252 1227
1253 msg = &p_ptr->publ.phdr; 1228 msg = &p_ptr->phdr;
1254 msg_set_type(msg, TIPC_NAMED_MSG); 1229 msg_set_type(msg, TIPC_NAMED_MSG);
1255 msg_set_orignode(msg, tipc_own_addr); 1230 msg_set_orignode(msg, tipc_own_addr);
1256 msg_set_origport(msg, ref); 1231 msg_set_origport(msg, ref);
@@ -1263,13 +1238,17 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1263 msg_set_destport(msg, destport); 1238 msg_set_destport(msg, destport);
1264 1239
1265 if (likely(destport)) { 1240 if (likely(destport)) {
1266 p_ptr->sent++;
1267 if (likely(destnode == tipc_own_addr)) 1241 if (likely(destnode == tipc_own_addr))
1268 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1242 res = tipc_port_recv_sections(p_ptr, num_sect,
1269 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1243 msg_sect);
1270 destnode); 1244 else
1271 if (likely(res != -ELINKCONG)) 1245 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
1246 num_sect, destnode);
1247 if (likely(res != -ELINKCONG)) {
1248 if (res > 0)
1249 p_ptr->sent++;
1272 return res; 1250 return res;
1251 }
1273 if (port_unreliable(p_ptr)) { 1252 if (port_unreliable(p_ptr)) {
1274 /* Just calculate msg length and return */ 1253 /* Just calculate msg length and return */
1275 return tipc_msg_calc_data_size(msg_sect, num_sect); 1254 return tipc_msg_calc_data_size(msg_sect, num_sect);
@@ -1287,27 +1266,32 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1287int tipc_send2port(u32 ref, struct tipc_portid const *dest, 1266int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1288 unsigned int num_sect, struct iovec const *msg_sect) 1267 unsigned int num_sect, struct iovec const *msg_sect)
1289{ 1268{
1290 struct port *p_ptr; 1269 struct tipc_port *p_ptr;
1291 struct tipc_msg *msg; 1270 struct tipc_msg *msg;
1292 int res; 1271 int res;
1293 1272
1294 p_ptr = tipc_port_deref(ref); 1273 p_ptr = tipc_port_deref(ref);
1295 if (!p_ptr || p_ptr->publ.connected) 1274 if (!p_ptr || p_ptr->connected)
1296 return -EINVAL; 1275 return -EINVAL;
1297 1276
1298 msg = &p_ptr->publ.phdr; 1277 msg = &p_ptr->phdr;
1299 msg_set_type(msg, TIPC_DIRECT_MSG); 1278 msg_set_type(msg, TIPC_DIRECT_MSG);
1300 msg_set_orignode(msg, tipc_own_addr); 1279 msg_set_orignode(msg, tipc_own_addr);
1301 msg_set_origport(msg, ref); 1280 msg_set_origport(msg, ref);
1302 msg_set_destnode(msg, dest->node); 1281 msg_set_destnode(msg, dest->node);
1303 msg_set_destport(msg, dest->ref); 1282 msg_set_destport(msg, dest->ref);
1304 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1283 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1305 p_ptr->sent++; 1284
1306 if (dest->node == tipc_own_addr) 1285 if (dest->node == tipc_own_addr)
1307 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1286 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); 1287 else
1309 if (likely(res != -ELINKCONG)) 1288 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1289 dest->node);
1290 if (likely(res != -ELINKCONG)) {
1291 if (res > 0)
1292 p_ptr->sent++;
1310 return res; 1293 return res;
1294 }
1311 if (port_unreliable(p_ptr)) { 1295 if (port_unreliable(p_ptr)) {
1312 /* Just calculate msg length and return */ 1296 /* Just calculate msg length and return */
1313 return tipc_msg_calc_data_size(msg_sect, num_sect); 1297 return tipc_msg_calc_data_size(msg_sect, num_sect);
@@ -1322,15 +1306,15 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1322int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, 1306int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1323 struct sk_buff *buf, unsigned int dsz) 1307 struct sk_buff *buf, unsigned int dsz)
1324{ 1308{
1325 struct port *p_ptr; 1309 struct tipc_port *p_ptr;
1326 struct tipc_msg *msg; 1310 struct tipc_msg *msg;
1327 int res; 1311 int res;
1328 1312
1329 p_ptr = (struct port *)tipc_ref_deref(ref); 1313 p_ptr = (struct tipc_port *)tipc_ref_deref(ref);
1330 if (!p_ptr || p_ptr->publ.connected) 1314 if (!p_ptr || p_ptr->connected)
1331 return -EINVAL; 1315 return -EINVAL;
1332 1316
1333 msg = &p_ptr->publ.phdr; 1317 msg = &p_ptr->phdr;
1334 msg_set_type(msg, TIPC_DIRECT_MSG); 1318 msg_set_type(msg, TIPC_DIRECT_MSG);
1335 msg_set_orignode(msg, tipc_own_addr); 1319 msg_set_orignode(msg, tipc_own_addr);
1336 msg_set_origport(msg, ref); 1320 msg_set_origport(msg, ref);
@@ -1343,12 +1327,16 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1343 1327
1344 skb_push(buf, DIR_MSG_H_SIZE); 1328 skb_push(buf, DIR_MSG_H_SIZE);
1345 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1329 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1346 p_ptr->sent++; 1330
1347 if (dest->node == tipc_own_addr) 1331 if (dest->node == tipc_own_addr)
1348 return tipc_port_recv_msg(buf); 1332 res = tipc_port_recv_msg(buf);
1349 res = tipc_send_buf_fast(buf, dest->node); 1333 else
1350 if (likely(res != -ELINKCONG)) 1334 res = tipc_send_buf_fast(buf, dest->node);
1335 if (likely(res != -ELINKCONG)) {
1336 if (res > 0)
1337 p_ptr->sent++;
1351 return res; 1338 return res;
1339 }
1352 if (port_unreliable(p_ptr)) 1340 if (port_unreliable(p_ptr))
1353 return dsz; 1341 return dsz;
1354 return -ELINKCONG; 1342 return -ELINKCONG;
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 8e84b989949c..87b9424ae0ec 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};
@@ -230,7 +219,7 @@ int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
230int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, 219int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
231 unsigned int section_count, struct iovec const *msg); 220 unsigned int section_count, struct iovec const *msg);
232 221
233int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 222int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
234 struct iovec const *msg_sect, u32 num_sect, 223 struct iovec const *msg_sect, u32 num_sect,
235 int err); 224 int err);
236struct sk_buff *tipc_port_get_ports(void); 225struct sk_buff *tipc_port_get_ports(void);
@@ -242,9 +231,9 @@ void tipc_port_reinit(void);
242 * tipc_port_lock - lock port instance referred to and return its pointer 231 * tipc_port_lock - lock port instance referred to and return its pointer
243 */ 232 */
244 233
245static inline struct port *tipc_port_lock(u32 ref) 234static inline struct tipc_port *tipc_port_lock(u32 ref)
246{ 235{
247 return (struct port *)tipc_ref_lock(ref); 236 return (struct tipc_port *)tipc_ref_lock(ref);
248} 237}
249 238
250/** 239/**
@@ -253,27 +242,27 @@ static inline struct port *tipc_port_lock(u32 ref)
253 * Can use pointer instead of tipc_ref_unlock() since port is already locked. 242 * Can use pointer instead of tipc_ref_unlock() since port is already locked.
254 */ 243 */
255 244
256static inline void tipc_port_unlock(struct port *p_ptr) 245static inline void tipc_port_unlock(struct tipc_port *p_ptr)
257{ 246{
258 spin_unlock_bh(p_ptr->publ.lock); 247 spin_unlock_bh(p_ptr->lock);
259} 248}
260 249
261static inline struct port *tipc_port_deref(u32 ref) 250static inline struct tipc_port *tipc_port_deref(u32 ref)
262{ 251{
263 return (struct port *)tipc_ref_deref(ref); 252 return (struct tipc_port *)tipc_ref_deref(ref);
264} 253}
265 254
266static inline u32 tipc_peer_port(struct port *p_ptr) 255static inline u32 tipc_peer_port(struct tipc_port *p_ptr)
267{ 256{
268 return msg_destport(&p_ptr->publ.phdr); 257 return msg_destport(&p_ptr->phdr);
269} 258}
270 259
271static inline u32 tipc_peer_node(struct port *p_ptr) 260static inline u32 tipc_peer_node(struct tipc_port *p_ptr)
272{ 261{
273 return msg_destnode(&p_ptr->publ.phdr); 262 return msg_destnode(&p_ptr->phdr);
274} 263}
275 264
276static inline int tipc_port_congested(struct port *p_ptr) 265static inline int tipc_port_congested(struct tipc_port *p_ptr)
277{ 266{
278 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); 267 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
279} 268}
@@ -284,7 +273,7 @@ static inline int tipc_port_congested(struct port *p_ptr)
284 273
285static inline int tipc_port_recv_msg(struct sk_buff *buf) 274static inline int tipc_port_recv_msg(struct sk_buff *buf)
286{ 275{
287 struct port *p_ptr; 276 struct tipc_port *p_ptr;
288 struct tipc_msg *msg = buf_msg(buf); 277 struct tipc_msg *msg = buf_msg(buf);
289 u32 destport = msg_destport(msg); 278 u32 destport = msg_destport(msg);
290 u32 dsz = msg_data_sz(msg); 279 u32 dsz = msg_data_sz(msg);
@@ -299,7 +288,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
299 /* validate destination & pass to port, otherwise reject message */ 288 /* validate destination & pass to port, otherwise reject message */
300 p_ptr = tipc_port_lock(destport); 289 p_ptr = tipc_port_lock(destport);
301 if (likely(p_ptr)) { 290 if (likely(p_ptr)) {
302 if (likely(p_ptr->publ.connected)) { 291 if (likely(p_ptr->connected)) {
303 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) || 292 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
304 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) || 293 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
305 (unlikely(!msg_connected(msg)))) { 294 (unlikely(!msg_connected(msg)))) {
@@ -308,7 +297,7 @@ static inline int tipc_port_recv_msg(struct sk_buff *buf)
308 goto reject; 297 goto reject;
309 } 298 }
310 } 299 }
311 err = p_ptr->dispatcher(&p_ptr->publ, buf); 300 err = p_ptr->dispatcher(p_ptr, buf);
312 tipc_port_unlock(p_ptr); 301 tipc_port_unlock(p_ptr);
313 if (likely(!err)) 302 if (likely(!err))
314 return dsz; 303 return dsz;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 2b02a3a80313..29d94d53198d 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)))
@@ -911,15 +914,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
911 struct tipc_port *tport = tipc_sk_port(sk); 914 struct tipc_port *tport = tipc_sk_port(sk);
912 struct sk_buff *buf; 915 struct sk_buff *buf;
913 struct tipc_msg *msg; 916 struct tipc_msg *msg;
917 long timeout;
914 unsigned int sz; 918 unsigned int sz;
915 u32 err; 919 u32 err;
916 int res; 920 int res;
917 921
918 /* Catch invalid receive requests */ 922 /* Catch invalid receive requests */
919 923
920 if (m->msg_iovlen != 1)
921 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
922
923 if (unlikely(!buf_len)) 924 if (unlikely(!buf_len))
924 return -EINVAL; 925 return -EINVAL;
925 926
@@ -930,6 +931,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
930 goto exit; 931 goto exit;
931 } 932 }
932 933
934 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
933restart: 935restart:
934 936
935 /* Look for a message in receive queue; wait if necessary */ 937 /* Look for a message in receive queue; wait if necessary */
@@ -939,17 +941,15 @@ restart:
939 res = -ENOTCONN; 941 res = -ENOTCONN;
940 goto exit; 942 goto exit;
941 } 943 }
942 if (flags & MSG_DONTWAIT) { 944 if (timeout <= 0L) {
943 res = -EWOULDBLOCK; 945 res = timeout ? timeout : -EWOULDBLOCK;
944 goto exit; 946 goto exit;
945 } 947 }
946 release_sock(sk); 948 release_sock(sk);
947 res = wait_event_interruptible(*sk_sleep(sk), 949 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
948 (!skb_queue_empty(&sk->sk_receive_queue) || 950 tipc_rx_ready(sock),
949 (sock->state == SS_DISCONNECTING))); 951 timeout);
950 lock_sock(sk); 952 lock_sock(sk);
951 if (res)
952 goto exit;
953 } 953 }
954 954
955 /* Look at first message in receive queue */ 955 /* Look at first message in receive queue */
@@ -991,11 +991,10 @@ restart:
991 sz = buf_len; 991 sz = buf_len;
992 m->msg_flags |= MSG_TRUNC; 992 m->msg_flags |= MSG_TRUNC;
993 } 993 }
994 if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), 994 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
995 sz))) { 995 m->msg_iov, sz);
996 res = -EFAULT; 996 if (res)
997 goto exit; 997 goto exit;
998 }
999 res = sz; 998 res = sz;
1000 } else { 999 } else {
1001 if ((sock->state == SS_READY) || 1000 if ((sock->state == SS_READY) ||
@@ -1038,19 +1037,15 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1038 struct tipc_port *tport = tipc_sk_port(sk); 1037 struct tipc_port *tport = tipc_sk_port(sk);
1039 struct sk_buff *buf; 1038 struct sk_buff *buf;
1040 struct tipc_msg *msg; 1039 struct tipc_msg *msg;
1040 long timeout;
1041 unsigned int sz; 1041 unsigned int sz;
1042 int sz_to_copy, target, needed; 1042 int sz_to_copy, target, needed;
1043 int sz_copied = 0; 1043 int sz_copied = 0;
1044 char __user *crs = m->msg_iov->iov_base;
1045 unsigned char *buf_crs;
1046 u32 err; 1044 u32 err;
1047 int res = 0; 1045 int res = 0;
1048 1046
1049 /* Catch invalid receive attempts */ 1047 /* Catch invalid receive attempts */
1050 1048
1051 if (m->msg_iovlen != 1)
1052 return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */
1053
1054 if (unlikely(!buf_len)) 1049 if (unlikely(!buf_len))
1055 return -EINVAL; 1050 return -EINVAL;
1056 1051
@@ -1063,7 +1058,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1063 } 1058 }
1064 1059
1065 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1060 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1066 1061 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1067restart: 1062restart:
1068 1063
1069 /* Look for a message in receive queue; wait if necessary */ 1064 /* Look for a message in receive queue; wait if necessary */
@@ -1073,17 +1068,15 @@ restart:
1073 res = -ENOTCONN; 1068 res = -ENOTCONN;
1074 goto exit; 1069 goto exit;
1075 } 1070 }
1076 if (flags & MSG_DONTWAIT) { 1071 if (timeout <= 0L) {
1077 res = -EWOULDBLOCK; 1072 res = timeout ? timeout : -EWOULDBLOCK;
1078 goto exit; 1073 goto exit;
1079 } 1074 }
1080 release_sock(sk); 1075 release_sock(sk);
1081 res = wait_event_interruptible(*sk_sleep(sk), 1076 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1082 (!skb_queue_empty(&sk->sk_receive_queue) || 1077 tipc_rx_ready(sock),
1083 (sock->state == SS_DISCONNECTING))); 1078 timeout);
1084 lock_sock(sk); 1079 lock_sock(sk);
1085 if (res)
1086 goto exit;
1087 } 1080 }
1088 1081
1089 /* Look at first message in receive queue */ 1082 /* Look at first message in receive queue */
@@ -1112,24 +1105,25 @@ restart:
1112 /* Capture message data (if valid) & compute return value (always) */ 1105 /* Capture message data (if valid) & compute return value (always) */
1113 1106
1114 if (!err) { 1107 if (!err) {
1115 buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); 1108 u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
1116 sz = (unsigned char *)msg + msg_size(msg) - buf_crs;
1117 1109
1110 sz -= offset;
1118 needed = (buf_len - sz_copied); 1111 needed = (buf_len - sz_copied);
1119 sz_to_copy = (sz <= needed) ? sz : needed; 1112 sz_to_copy = (sz <= needed) ? sz : needed;
1120 if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { 1113
1121 res = -EFAULT; 1114 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
1115 m->msg_iov, sz_to_copy);
1116 if (res)
1122 goto exit; 1117 goto exit;
1123 } 1118
1124 sz_copied += sz_to_copy; 1119 sz_copied += sz_to_copy;
1125 1120
1126 if (sz_to_copy < sz) { 1121 if (sz_to_copy < sz) {
1127 if (!(flags & MSG_PEEK)) 1122 if (!(flags & MSG_PEEK))
1128 TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; 1123 TIPC_SKB_CB(buf)->handle =
1124 (void *)(unsigned long)(offset + sz_to_copy);
1129 goto exit; 1125 goto exit;
1130 } 1126 }
1131
1132 crs += sz_to_copy;
1133 } else { 1127 } else {
1134 if (sz_copied != 0) 1128 if (sz_copied != 0)
1135 goto exit; /* can't add error msg to valid data */ 1129 goto exit; /* can't add error msg to valid data */
@@ -1256,7 +1250,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1256 1250
1257 /* Enqueue message (finally!) */ 1251 /* Enqueue message (finally!) */
1258 1252
1259 TIPC_SKB_CB(buf)->handle = msg_data(msg); 1253 TIPC_SKB_CB(buf)->handle = 0;
1260 atomic_inc(&tipc_queue_size); 1254 atomic_inc(&tipc_queue_size);
1261 __skb_queue_tail(&sk->sk_receive_queue, buf); 1255 __skb_queue_tail(&sk->sk_receive_queue, buf);
1262 1256
@@ -1608,7 +1602,7 @@ restart:
1608 buf = __skb_dequeue(&sk->sk_receive_queue); 1602 buf = __skb_dequeue(&sk->sk_receive_queue);
1609 if (buf) { 1603 if (buf) {
1610 atomic_dec(&tipc_queue_size); 1604 atomic_dec(&tipc_queue_size);
1611 if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { 1605 if (TIPC_SKB_CB(buf)->handle != 0) {
1612 buf_discard(buf); 1606 buf_discard(buf);
1613 goto restart; 1607 goto restart;
1614 } 1608 }
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index ca04479c3d42..aae9eae13404 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
@@ -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);
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