aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c14
-rw-r--r--net/tipc/bearer.c8
-rw-r--r--net/tipc/cluster.c4
-rw-r--r--net/tipc/config.c11
-rw-r--r--net/tipc/core.c13
-rw-r--r--net/tipc/core.h126
-rw-r--r--net/tipc/dbg.c231
-rw-r--r--net/tipc/dbg.h12
-rw-r--r--net/tipc/discover.c14
-rw-r--r--net/tipc/discover.h2
-rw-r--r--net/tipc/eth_media.c10
-rw-r--r--net/tipc/link.c98
-rw-r--r--net/tipc/msg.c13
-rw-r--r--net/tipc/msg.h42
-rw-r--r--net/tipc/name_distr.c6
-rw-r--r--net/tipc/name_table.c55
-rw-r--r--net/tipc/net.c14
-rw-r--r--net/tipc/net.h2
-rw-r--r--net/tipc/netlink.c16
-rw-r--r--net/tipc/node.c55
-rw-r--r--net/tipc/port.c115
-rw-r--r--net/tipc/ref.c14
-rw-r--r--net/tipc/socket.c62
-rw-r--r--net/tipc/subscr.c249
-rw-r--r--net/tipc/subscr.h34
-rw-r--r--net/tipc/user_reg.c14
26 files changed, 687 insertions, 547 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index e7880172ef19..b1ff16aa4bdb 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -276,7 +276,7 @@ static void bclink_send_nack(struct node *n_ptr)
276 if (buf) { 276 if (buf) {
277 msg = buf_msg(buf); 277 msg = buf_msg(buf);
278 msg_init(msg, BCAST_PROTOCOL, STATE_MSG, 278 msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
279 TIPC_OK, INT_H_SIZE, n_ptr->addr); 279 INT_H_SIZE, n_ptr->addr);
280 msg_set_mc_netid(msg, tipc_net_id); 280 msg_set_mc_netid(msg, tipc_net_id);
281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); 281 msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
282 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); 282 msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
@@ -571,7 +571,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf,
571 assert(tipc_cltr_bcast_nodes.count != 0); 571 assert(tipc_cltr_bcast_nodes.count != 0);
572 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count); 572 bcbuf_set_acks(buf, tipc_cltr_bcast_nodes.count);
573 msg = buf_msg(buf); 573 msg = buf_msg(buf);
574 msg_set_non_seq(msg); 574 msg_set_non_seq(msg, 1);
575 msg_set_mc_netid(msg, tipc_net_id); 575 msg_set_mc_netid(msg, tipc_net_id);
576 } 576 }
577 577
@@ -611,7 +611,7 @@ swap:
611 bcbearer->bpairs[bp_index].secondary = p; 611 bcbearer->bpairs[bp_index].secondary = p;
612update: 612update:
613 if (bcbearer->remains_new.count == 0) 613 if (bcbearer->remains_new.count == 0)
614 return TIPC_OK; 614 return 0;
615 615
616 bcbearer->remains = bcbearer->remains_new; 616 bcbearer->remains = bcbearer->remains_new;
617 } 617 }
@@ -620,7 +620,7 @@ update:
620 620
621 bcbearer->bearer.publ.blocked = 1; 621 bcbearer->bearer.publ.blocked = 1;
622 bcl->stats.bearer_congs++; 622 bcl->stats.bearer_congs++;
623 return ~TIPC_OK; 623 return 1;
624} 624}
625 625
626/** 626/**
@@ -756,7 +756,7 @@ int tipc_bclink_reset_stats(void)
756 spin_lock_bh(&bc_lock); 756 spin_lock_bh(&bc_lock);
757 memset(&bcl->stats, 0, sizeof(bcl->stats)); 757 memset(&bcl->stats, 0, sizeof(bcl->stats));
758 spin_unlock_bh(&bc_lock); 758 spin_unlock_bh(&bc_lock);
759 return TIPC_OK; 759 return 0;
760} 760}
761 761
762int tipc_bclink_set_queue_limits(u32 limit) 762int tipc_bclink_set_queue_limits(u32 limit)
@@ -769,7 +769,7 @@ int tipc_bclink_set_queue_limits(u32 limit)
769 spin_lock_bh(&bc_lock); 769 spin_lock_bh(&bc_lock);
770 tipc_link_set_queue_limits(bcl, limit); 770 tipc_link_set_queue_limits(bcl, limit);
771 spin_unlock_bh(&bc_lock); 771 spin_unlock_bh(&bc_lock);
772 return TIPC_OK; 772 return 0;
773} 773}
774 774
775int tipc_bclink_init(void) 775int tipc_bclink_init(void)
@@ -810,7 +810,7 @@ int tipc_bclink_init(void)
810 tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); 810 tipc_printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE);
811 } 811 }
812 812
813 return TIPC_OK; 813 return 0;
814} 814}
815 815
816void tipc_bclink_stop(void) 816void tipc_bclink_stop(void)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 271a375b49b7..6a9aba3edd08 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -370,7 +370,7 @@ void tipc_bearer_remove_dest(struct bearer *b_ptr, u32 dest)
370 */ 370 */
371static int bearer_push(struct bearer *b_ptr) 371static int bearer_push(struct bearer *b_ptr)
372{ 372{
373 u32 res = TIPC_OK; 373 u32 res = 0;
374 struct link *ln, *tln; 374 struct link *ln, *tln;
375 375
376 if (b_ptr->publ.blocked) 376 if (b_ptr->publ.blocked)
@@ -607,7 +607,7 @@ int tipc_block_bearer(const char *name)
607 } 607 }
608 spin_unlock_bh(&b_ptr->publ.lock); 608 spin_unlock_bh(&b_ptr->publ.lock);
609 read_unlock_bh(&tipc_net_lock); 609 read_unlock_bh(&tipc_net_lock);
610 return TIPC_OK; 610 return 0;
611} 611}
612 612
613/** 613/**
@@ -645,7 +645,7 @@ static int bearer_disable(const char *name)
645 } 645 }
646 spin_unlock_bh(&b_ptr->publ.lock); 646 spin_unlock_bh(&b_ptr->publ.lock);
647 memset(b_ptr, 0, sizeof(struct bearer)); 647 memset(b_ptr, 0, sizeof(struct bearer));
648 return TIPC_OK; 648 return 0;
649} 649}
650 650
651int tipc_disable_bearer(const char *name) 651int tipc_disable_bearer(const char *name)
@@ -668,7 +668,7 @@ int tipc_bearer_init(void)
668 tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); 668 tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC);
669 media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); 669 media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC);
670 if (tipc_bearers && media_list) { 670 if (tipc_bearers && media_list) {
671 res = TIPC_OK; 671 res = 0;
672 } else { 672 } else {
673 kfree(tipc_bearers); 673 kfree(tipc_bearers);
674 kfree(media_list); 674 kfree(media_list);
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index 4bb3404f610b..46ee6c58532d 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -238,7 +238,7 @@ static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest)
238 if (buf) { 238 if (buf) {
239 msg = buf_msg(buf); 239 msg = buf_msg(buf);
240 memset((char *)msg, 0, size); 240 memset((char *)msg, 0, size);
241 msg_init(msg, ROUTE_DISTRIBUTOR, 0, TIPC_OK, INT_H_SIZE, dest); 241 msg_init(msg, ROUTE_DISTRIBUTOR, 0, INT_H_SIZE, dest);
242 } 242 }
243 return buf; 243 return buf;
244} 244}
@@ -571,6 +571,6 @@ exit:
571int tipc_cltr_init(void) 571int tipc_cltr_init(void)
572{ 572{
573 tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; 573 tipc_highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves;
574 return tipc_cltr_create(tipc_own_addr) ? TIPC_OK : -ENOMEM; 574 return tipc_cltr_create(tipc_own_addr) ? 0 : -ENOMEM;
575} 575}
576 576
diff --git a/net/tipc/config.c b/net/tipc/config.c
index c71337a22d33..ca3544d030c7 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-2006, Wind River Systems 5 * Copyright (c) 2004-2007, 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
@@ -293,7 +293,6 @@ static struct sk_buff *cfg_set_own_addr(void)
293 if (tipc_mode == TIPC_NET_MODE) 293 if (tipc_mode == TIPC_NET_MODE)
294 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 294 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
295 " (cannot change node address once assigned)"); 295 " (cannot change node address once assigned)");
296 tipc_own_addr = addr;
297 296
298 /* 297 /*
299 * Must release all spinlocks before calling start_net() because 298 * Must release all spinlocks before calling start_net() because
@@ -306,7 +305,7 @@ static struct sk_buff *cfg_set_own_addr(void)
306 */ 305 */
307 306
308 spin_unlock_bh(&config_lock); 307 spin_unlock_bh(&config_lock);
309 tipc_core_start_net(); 308 tipc_core_start_net(addr);
310 spin_lock_bh(&config_lock); 309 spin_lock_bh(&config_lock);
311 return tipc_cfg_reply_none(); 310 return tipc_cfg_reply_none();
312} 311}
@@ -529,7 +528,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
529 break; 528 break;
530#endif 529#endif
531 case TIPC_CMD_SET_LOG_SIZE: 530 case TIPC_CMD_SET_LOG_SIZE:
532 rep_tlv_buf = tipc_log_resize(req_tlv_area, req_tlv_space); 531 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
533 break; 532 break;
534 case TIPC_CMD_DUMP_LOG: 533 case TIPC_CMD_DUMP_LOG:
535 rep_tlv_buf = tipc_log_dump(); 534 rep_tlv_buf = tipc_log_dump();
@@ -602,6 +601,10 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
602 case TIPC_CMD_GET_NETID: 601 case TIPC_CMD_GET_NETID:
603 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 602 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
604 break; 603 break;
604 case TIPC_CMD_NOT_NET_ADMIN:
605 rep_tlv_buf =
606 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
607 break;
605 default: 608 default:
606 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 609 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
607 " (unknown command)"); 610 " (unknown command)");
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 740aac5cdfb6..3256bd7d398f 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -49,7 +49,7 @@
49#include "config.h" 49#include "config.h"
50 50
51 51
52#define TIPC_MOD_VER "1.6.3" 52#define TIPC_MOD_VER "1.6.4"
53 53
54#ifndef CONFIG_TIPC_ZONES 54#ifndef CONFIG_TIPC_ZONES
55#define CONFIG_TIPC_ZONES 3 55#define CONFIG_TIPC_ZONES 3
@@ -117,11 +117,11 @@ void tipc_core_stop_net(void)
117 * start_net - start TIPC networking sub-systems 117 * start_net - start TIPC networking sub-systems
118 */ 118 */
119 119
120int tipc_core_start_net(void) 120int tipc_core_start_net(unsigned long addr)
121{ 121{
122 int res; 122 int res;
123 123
124 if ((res = tipc_net_start()) || 124 if ((res = tipc_net_start(addr)) ||
125 (res = tipc_eth_media_start())) { 125 (res = tipc_eth_media_start())) {
126 tipc_core_stop_net(); 126 tipc_core_stop_net();
127 } 127 }
@@ -164,8 +164,7 @@ int tipc_core_start(void)
164 tipc_mode = TIPC_NODE_MODE; 164 tipc_mode = TIPC_NODE_MODE;
165 165
166 if ((res = tipc_handler_start()) || 166 if ((res = tipc_handler_start()) ||
167 (res = tipc_ref_table_init(tipc_max_ports + tipc_max_subscriptions, 167 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) ||
168 tipc_random)) ||
169 (res = tipc_reg_start()) || 168 (res = tipc_reg_start()) ||
170 (res = tipc_nametbl_init()) || 169 (res = tipc_nametbl_init()) ||
171 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || 170 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) ||
@@ -182,7 +181,7 @@ static int __init tipc_init(void)
182{ 181{
183 int res; 182 int res;
184 183
185 tipc_log_reinit(CONFIG_TIPC_LOG); 184 tipc_log_resize(CONFIG_TIPC_LOG);
186 info("Activated (version " TIPC_MOD_VER 185 info("Activated (version " TIPC_MOD_VER
187 " compiled " __DATE__ " " __TIME__ ")\n"); 186 " compiled " __DATE__ " " __TIME__ ")\n");
188 187
@@ -209,7 +208,7 @@ static void __exit tipc_exit(void)
209 tipc_core_stop_net(); 208 tipc_core_stop_net();
210 tipc_core_stop(); 209 tipc_core_stop();
211 info("Deactivated\n"); 210 info("Deactivated\n");
212 tipc_log_stop(); 211 tipc_log_resize(0);
213} 212}
214 213
215module_init(tipc_init); 214module_init(tipc_init);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 5a0e4878d3b7..a881f92a8537 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-2006, Wind River Systems 5 * Copyright (c) 2005-2007, 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,84 +59,108 @@
59#include <linux/vmalloc.h> 59#include <linux/vmalloc.h>
60 60
61/* 61/*
62 * TIPC debugging code 62 * TIPC sanity test macros
63 */ 63 */
64 64
65#define assert(i) BUG_ON(!(i)) 65#define assert(i) BUG_ON(!(i))
66 66
67struct tipc_msg;
68extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG;
69extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
70void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
71void tipc_printf(struct print_buf *, const char *fmt, ...);
72void tipc_dump(struct print_buf*,const char *fmt, ...);
73
74#ifdef CONFIG_TIPC_DEBUG
75
76/* 67/*
77 * TIPC debug support included: 68 * TIPC system monitoring code
78 * - system messages are printed to TIPC_OUTPUT print buffer
79 * - debug messages are printed to DBG_OUTPUT print buffer
80 */ 69 */
81 70
82#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_ERR "TIPC: " fmt, ## arg) 71/*
83#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) 72 * TIPC's print buffer subsystem supports the following print buffers:
84#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) 73 *
74 * TIPC_NULL : null buffer (i.e. print nowhere)
75 * TIPC_CONS : system console
76 * TIPC_LOG : TIPC log buffer
77 * &buf : user-defined buffer (struct print_buf *)
78 *
79 * Note: TIPC_LOG is configured to echo its output to the system console;
80 * user-defined buffers can be configured to do the same thing.
81 */
85 82
86#define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) 83extern struct print_buf *const TIPC_NULL;
87#define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) 84extern struct print_buf *const TIPC_CONS;
88#define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) 85extern struct print_buf *const TIPC_LOG;
89 86
87void tipc_printf(struct print_buf *, const char *fmt, ...);
90 88
91/* 89/*
92 * By default, TIPC_OUTPUT is defined to be system console and TIPC log buffer, 90 * TIPC_OUTPUT is the destination print buffer for system messages.
93 * while DBG_OUTPUT is the null print buffer. These defaults can be changed
94 * here, or on a per .c file basis, by redefining these symbols. The following
95 * print buffer options are available:
96 *
97 * TIPC_NULL : null buffer (i.e. print nowhere)
98 * TIPC_CONS : system console
99 * TIPC_LOG : TIPC log buffer
100 * &buf : user-defined buffer (struct print_buf *)
101 * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG))
102 */ 91 */
103 92
104#ifndef TIPC_OUTPUT 93#ifndef TIPC_OUTPUT
105#define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG) 94#define TIPC_OUTPUT TIPC_LOG
106#endif
107
108#ifndef DBG_OUTPUT
109#define DBG_OUTPUT TIPC_NULL
110#endif 95#endif
111 96
112#else
113
114/* 97/*
115 * TIPC debug support not included: 98 * TIPC can be configured to send system messages to TIPC_OUTPUT
116 * - system messages are printed to system console 99 * or to the system console only.
117 * - debug messages are not printed
118 */ 100 */
119 101
102#ifdef CONFIG_TIPC_DEBUG
103
104#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
105 KERN_ERR "TIPC: " fmt, ## arg)
106#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
107 KERN_WARNING "TIPC: " fmt, ## arg)
108#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, \
109 KERN_NOTICE "TIPC: " fmt, ## arg)
110
111#else
112
120#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) 113#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg)
121#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) 114#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg)
122#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) 115#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg)
123 116
124#define dbg(fmt, arg...) do {} while (0) 117#endif
125#define msg_dbg(msg,txt) do {} while (0)
126#define dump(fmt,arg...) do {} while (0)
127 118
119/*
120 * DBG_OUTPUT is the destination print buffer for debug messages.
121 * It defaults to the the null print buffer, but can be redefined
122 * (typically in the individual .c files being debugged) to allow
123 * selected debug messages to be generated where needed.
124 */
125
126#ifndef DBG_OUTPUT
127#define DBG_OUTPUT TIPC_NULL
128#endif
128 129
129/* 130/*
130 * TIPC_OUTPUT is defined to be the system console, while DBG_OUTPUT is 131 * TIPC can be configured to send debug messages to the specified print buffer
131 * the null print buffer. Thes ensures that any system or debug messages 132 * (typically DBG_OUTPUT) or to suppress them entirely.
132 * that are generated without using the above macros are handled correctly.
133 */ 133 */
134 134
135#undef TIPC_OUTPUT 135#ifdef CONFIG_TIPC_DEBUG
136#define TIPC_OUTPUT TIPC_CONS
137 136
138#undef DBG_OUTPUT 137#define dbg(fmt, arg...) \
139#define DBG_OUTPUT TIPC_NULL 138 do { \
139 if (DBG_OUTPUT != TIPC_NULL) \
140 tipc_printf(DBG_OUTPUT, fmt, ## arg); \
141 } while (0)
142#define msg_dbg(msg, txt) \
143 do { \
144 if (DBG_OUTPUT != TIPC_NULL) \
145 tipc_msg_dbg(DBG_OUTPUT, msg, txt); \
146 } while (0)
147#define dump(fmt, arg...) \
148 do { \
149 if (DBG_OUTPUT != TIPC_NULL) \
150 tipc_dump_dbg(DBG_OUTPUT, fmt, ##arg); \
151 } while (0)
152
153void tipc_msg_dbg(struct print_buf *, struct tipc_msg *, const char *);
154void tipc_dump_dbg(struct print_buf *, const char *fmt, ...);
155
156#else
157
158#define dbg(fmt, arg...) do {} while (0)
159#define msg_dbg(msg, txt) do {} while (0)
160#define dump(fmt, arg...) do {} while (0)
161
162#define tipc_msg_dbg(...) do {} while (0)
163#define tipc_dump_dbg(...) do {} while (0)
140 164
141#endif 165#endif
142 166
@@ -178,7 +202,7 @@ extern atomic_t tipc_user_count;
178 202
179extern int tipc_core_start(void); 203extern int tipc_core_start(void);
180extern void tipc_core_stop(void); 204extern void tipc_core_stop(void);
181extern int tipc_core_start_net(void); 205extern int tipc_core_start_net(unsigned long addr);
182extern void tipc_core_stop_net(void); 206extern void tipc_core_stop_net(void);
183extern int tipc_handler_start(void); 207extern int tipc_handler_start(void);
184extern void tipc_handler_stop(void); 208extern void tipc_handler_stop(void);
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index e809d2a2ce06..29ecae851668 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -2,7 +2,7 @@
2 * net/tipc/dbg.c: TIPC print buffer routines for debugging 2 * net/tipc/dbg.c: TIPC print buffer routines for debugging
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2007, 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
@@ -38,17 +38,43 @@
38#include "config.h" 38#include "config.h"
39#include "dbg.h" 39#include "dbg.h"
40 40
41static char print_string[TIPC_PB_MAX_STR]; 41/*
42static DEFINE_SPINLOCK(print_lock); 42 * TIPC pre-defines the following print buffers:
43 *
44 * TIPC_NULL : null buffer (i.e. print nowhere)
45 * TIPC_CONS : system console
46 * TIPC_LOG : TIPC log buffer
47 *
48 * Additional user-defined print buffers are also permitted.
49 */
43 50
44static struct print_buf null_buf = { NULL, 0, NULL, NULL }; 51static struct print_buf null_buf = { NULL, 0, NULL, 0 };
45struct print_buf *TIPC_NULL = &null_buf; 52struct print_buf *const TIPC_NULL = &null_buf;
46 53
47static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; 54static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
48struct print_buf *TIPC_CONS = &cons_buf; 55struct print_buf *const TIPC_CONS = &cons_buf;
49 56
50static struct print_buf log_buf = { NULL, 0, NULL, NULL }; 57static struct print_buf log_buf = { NULL, 0, NULL, 1 };
51struct print_buf *TIPC_LOG = &log_buf; 58struct print_buf *const TIPC_LOG = &log_buf;
59
60/*
61 * Locking policy when using print buffers.
62 *
63 * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to
64 * 'print_string' when writing to a print buffer. This also protects against
65 * concurrent writes to the print buffer being written to.
66 *
67 * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned
68 * use of 'print_lock' to protect against all types of concurrent operations
69 * on their associated print buffer (not just write operations).
70 *
71 * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely
72 * on the caller to prevent simultaneous use of the print buffer(s) being
73 * manipulated.
74 */
75
76static char print_string[TIPC_PB_MAX_STR];
77static DEFINE_SPINLOCK(print_lock);
52 78
53 79
54#define FORMAT(PTR,LEN,FMT) \ 80#define FORMAT(PTR,LEN,FMT) \
@@ -60,27 +86,14 @@ struct print_buf *TIPC_LOG = &log_buf;
60 *(PTR + LEN) = '\0';\ 86 *(PTR + LEN) = '\0';\
61} 87}
62 88
63/*
64 * Locking policy when using print buffers.
65 *
66 * The following routines use 'print_lock' for protection:
67 * 1) tipc_printf() - to protect its print buffer(s) and 'print_string'
68 * 2) TIPC_TEE() - to protect its print buffer(s)
69 * 3) tipc_dump() - to protect its print buffer(s) and 'print_string'
70 * 4) tipc_log_XXX() - to protect TIPC_LOG
71 *
72 * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent
73 * simultaneous use of the print buffer(s) being manipulated.
74 */
75
76/** 89/**
77 * tipc_printbuf_init - initialize print buffer to empty 90 * tipc_printbuf_init - initialize print buffer to empty
78 * @pb: pointer to print buffer structure 91 * @pb: pointer to print buffer structure
79 * @raw: pointer to character array used by print buffer 92 * @raw: pointer to character array used by print buffer
80 * @size: size of character array 93 * @size: size of character array
81 * 94 *
82 * Makes the print buffer a null device that discards anything written to it 95 * Note: If the character array is too small (or absent), the print buffer
83 * if the character array is too small (or absent). 96 * becomes a null device that discards anything written to it.
84 */ 97 */
85 98
86void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) 99void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
@@ -88,13 +101,13 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
88 pb->buf = raw; 101 pb->buf = raw;
89 pb->crs = raw; 102 pb->crs = raw;
90 pb->size = size; 103 pb->size = size;
91 pb->next = NULL; 104 pb->echo = 0;
92 105
93 if (size < TIPC_PB_MIN_SIZE) { 106 if (size < TIPC_PB_MIN_SIZE) {
94 pb->buf = NULL; 107 pb->buf = NULL;
95 } else if (raw) { 108 } else if (raw) {
96 pb->buf[0] = 0; 109 pb->buf[0] = 0;
97 pb->buf[size-1] = ~0; 110 pb->buf[size - 1] = ~0;
98 } 111 }
99} 112}
100 113
@@ -105,7 +118,11 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
105 118
106void tipc_printbuf_reset(struct print_buf *pb) 119void tipc_printbuf_reset(struct print_buf *pb)
107{ 120{
108 tipc_printbuf_init(pb, pb->buf, pb->size); 121 if (pb->buf) {
122 pb->crs = pb->buf;
123 pb->buf[0] = 0;
124 pb->buf[pb->size - 1] = ~0;
125 }
109} 126}
110 127
111/** 128/**
@@ -141,7 +158,7 @@ int tipc_printbuf_validate(struct print_buf *pb)
141 158
142 if (pb->buf[pb->size - 1] == 0) { 159 if (pb->buf[pb->size - 1] == 0) {
143 cp_buf = kmalloc(pb->size, GFP_ATOMIC); 160 cp_buf = kmalloc(pb->size, GFP_ATOMIC);
144 if (cp_buf != NULL){ 161 if (cp_buf) {
145 tipc_printbuf_init(&cb, cp_buf, pb->size); 162 tipc_printbuf_init(&cb, cp_buf, pb->size);
146 tipc_printbuf_move(&cb, pb); 163 tipc_printbuf_move(&cb, pb);
147 tipc_printbuf_move(pb, &cb); 164 tipc_printbuf_move(pb, &cb);
@@ -179,15 +196,16 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
179 } 196 }
180 197
181 if (pb_to->size < pb_from->size) { 198 if (pb_to->size < pb_from->size) {
182 tipc_printbuf_reset(pb_to); 199 strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***");
183 tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); 200 pb_to->buf[pb_to->size - 1] = ~0;
201 pb_to->crs = strchr(pb_to->buf, 0);
184 return; 202 return;
185 } 203 }
186 204
187 /* Copy data from char after cursor to end (if used) */ 205 /* Copy data from char after cursor to end (if used) */
188 206
189 len = pb_from->buf + pb_from->size - pb_from->crs - 2; 207 len = pb_from->buf + pb_from->size - pb_from->crs - 2;
190 if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { 208 if ((pb_from->buf[pb_from->size - 1] == 0) && (len > 0)) {
191 strcpy(pb_to->buf, pb_from->crs + 1); 209 strcpy(pb_to->buf, pb_from->crs + 1);
192 pb_to->crs = pb_to->buf + len; 210 pb_to->crs = pb_to->buf + len;
193 } else 211 } else
@@ -203,8 +221,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
203} 221}
204 222
205/** 223/**
206 * tipc_printf - append formatted output to print buffer chain 224 * tipc_printf - append formatted output to print buffer
207 * @pb: pointer to chain of print buffers (may be NULL) 225 * @pb: pointer to print buffer
208 * @fmt: formatted info to be printed 226 * @fmt: formatted info to be printed
209 */ 227 */
210 228
@@ -213,68 +231,40 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
213 int chars_to_add; 231 int chars_to_add;
214 int chars_left; 232 int chars_left;
215 char save_char; 233 char save_char;
216 struct print_buf *pb_next;
217 234
218 spin_lock_bh(&print_lock); 235 spin_lock_bh(&print_lock);
236
219 FORMAT(print_string, chars_to_add, fmt); 237 FORMAT(print_string, chars_to_add, fmt);
220 if (chars_to_add >= TIPC_PB_MAX_STR) 238 if (chars_to_add >= TIPC_PB_MAX_STR)
221 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); 239 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***");
222 240
223 while (pb) { 241 if (pb->buf) {
224 if (pb == TIPC_CONS) 242 chars_left = pb->buf + pb->size - pb->crs - 1;
225 printk(print_string); 243 if (chars_to_add <= chars_left) {
226 else if (pb->buf) { 244 strcpy(pb->crs, print_string);
227 chars_left = pb->buf + pb->size - pb->crs - 1; 245 pb->crs += chars_to_add;
228 if (chars_to_add <= chars_left) { 246 } else if (chars_to_add >= (pb->size - 1)) {
229 strcpy(pb->crs, print_string); 247 strcpy(pb->buf, print_string + chars_to_add + 1
230 pb->crs += chars_to_add; 248 - pb->size);
231 } else if (chars_to_add >= (pb->size - 1)) { 249 pb->crs = pb->buf + pb->size - 1;
232 strcpy(pb->buf, print_string + chars_to_add + 1 250 } else {
233 - pb->size); 251 strcpy(pb->buf, print_string + chars_left);
234 pb->crs = pb->buf + pb->size - 1; 252 save_char = print_string[chars_left];
235 } else { 253 print_string[chars_left] = 0;
236 strcpy(pb->buf, print_string + chars_left); 254 strcpy(pb->crs, print_string);
237 save_char = print_string[chars_left]; 255 print_string[chars_left] = save_char;
238 print_string[chars_left] = 0; 256 pb->crs = pb->buf + chars_to_add - chars_left;
239 strcpy(pb->crs, print_string);
240 print_string[chars_left] = save_char;
241 pb->crs = pb->buf + chars_to_add - chars_left;
242 }
243 } 257 }
244 pb_next = pb->next;
245 pb->next = NULL;
246 pb = pb_next;
247 } 258 }
248 spin_unlock_bh(&print_lock);
249}
250 259
251/** 260 if (pb->echo)
252 * TIPC_TEE - perform next output operation on both print buffers 261 printk(print_string);
253 * @b0: pointer to chain of print buffers (may be NULL)
254 * @b1: pointer to print buffer to add to chain
255 *
256 * Returns pointer to print buffer chain.
257 */
258 262
259struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
260{
261 struct print_buf *pb = b0;
262
263 if (!b0 || (b0 == b1))
264 return b1;
265
266 spin_lock_bh(&print_lock);
267 while (pb->next) {
268 if ((pb->next == b1) || (pb->next == b0))
269 pb->next = pb->next->next;
270 else
271 pb = pb->next;
272 }
273 pb->next = b1;
274 spin_unlock_bh(&print_lock); 263 spin_unlock_bh(&print_lock);
275 return b0;
276} 264}
277 265
266#ifdef CONFIG_TIPC_DEBUG
267
278/** 268/**
279 * print_to_console - write string of bytes to console in multiple chunks 269 * print_to_console - write string of bytes to console in multiple chunks
280 */ 270 */
@@ -321,72 +311,66 @@ static void printbuf_dump(struct print_buf *pb)
321} 311}
322 312
323/** 313/**
324 * tipc_dump - dump non-console print buffer(s) to console 314 * tipc_dump_dbg - dump (non-console) print buffer to console
325 * @pb: pointer to chain of print buffers 315 * @pb: pointer to print buffer
326 */ 316 */
327 317
328void tipc_dump(struct print_buf *pb, const char *fmt, ...) 318void tipc_dump_dbg(struct print_buf *pb, const char *fmt, ...)
329{ 319{
330 struct print_buf *pb_next;
331 int len; 320 int len;
332 321
322 if (pb == TIPC_CONS)
323 return;
324
333 spin_lock_bh(&print_lock); 325 spin_lock_bh(&print_lock);
326
334 FORMAT(print_string, len, fmt); 327 FORMAT(print_string, len, fmt);
335 printk(print_string); 328 printk(print_string);
336 329
337 for (; pb; pb = pb->next) { 330 printk("\n---- Start of %s log dump ----\n\n",
338 if (pb != TIPC_CONS) { 331 (pb == TIPC_LOG) ? "global" : "local");
339 printk("\n---- Start of %s log dump ----\n\n", 332 printbuf_dump(pb);
340 (pb == TIPC_LOG) ? "global" : "local"); 333 tipc_printbuf_reset(pb);
341 printbuf_dump(pb); 334 printk("\n---- End of dump ----\n");
342 tipc_printbuf_reset(pb); 335
343 printk("\n---- End of dump ----\n");
344 }
345 pb_next = pb->next;
346 pb->next = NULL;
347 pb = pb_next;
348 }
349 spin_unlock_bh(&print_lock); 336 spin_unlock_bh(&print_lock);
350} 337}
351 338
339#endif
340
352/** 341/**
353 * tipc_log_stop - free up TIPC log print buffer 342 * tipc_log_resize - change the size of the TIPC log buffer
343 * @log_size: print buffer size to use
354 */ 344 */
355 345
356void tipc_log_stop(void) 346int tipc_log_resize(int log_size)
357{ 347{
348 int res = 0;
349
358 spin_lock_bh(&print_lock); 350 spin_lock_bh(&print_lock);
359 if (TIPC_LOG->buf) { 351 if (TIPC_LOG->buf) {
360 kfree(TIPC_LOG->buf); 352 kfree(TIPC_LOG->buf);
361 TIPC_LOG->buf = NULL; 353 TIPC_LOG->buf = NULL;
362 } 354 }
363 spin_unlock_bh(&print_lock);
364}
365
366/**
367 * tipc_log_reinit - (re)initialize TIPC log print buffer
368 * @log_size: print buffer size to use
369 */
370
371void tipc_log_reinit(int log_size)
372{
373 tipc_log_stop();
374
375 if (log_size) { 355 if (log_size) {
376 if (log_size < TIPC_PB_MIN_SIZE) 356 if (log_size < TIPC_PB_MIN_SIZE)
377 log_size = TIPC_PB_MIN_SIZE; 357 log_size = TIPC_PB_MIN_SIZE;
378 spin_lock_bh(&print_lock); 358 res = TIPC_LOG->echo;
379 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), 359 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC),
380 log_size); 360 log_size);
381 spin_unlock_bh(&print_lock); 361 TIPC_LOG->echo = res;
362 res = !TIPC_LOG->buf;
382 } 363 }
364 spin_unlock_bh(&print_lock);
365
366 return res;
383} 367}
384 368
385/** 369/**
386 * tipc_log_resize - reconfigure size of TIPC log buffer 370 * tipc_log_resize_cmd - reconfigure size of TIPC log buffer
387 */ 371 */
388 372
389struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space) 373struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area, int req_tlv_space)
390{ 374{
391 u32 value; 375 u32 value;
392 376
@@ -397,7 +381,9 @@ struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space)
397 if (value != delimit(value, 0, 32768)) 381 if (value != delimit(value, 0, 32768))
398 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 382 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
399 " (log size must be 0-32768)"); 383 " (log size must be 0-32768)");
400 tipc_log_reinit(value); 384 if (tipc_log_resize(value))
385 return tipc_cfg_reply_error_string(
386 "unable to create specified log (log size is now 0)");
401 return tipc_cfg_reply_none(); 387 return tipc_cfg_reply_none();
402} 388}
403 389
@@ -410,27 +396,32 @@ struct sk_buff *tipc_log_dump(void)
410 struct sk_buff *reply; 396 struct sk_buff *reply;
411 397
412 spin_lock_bh(&print_lock); 398 spin_lock_bh(&print_lock);
413 if (!TIPC_LOG->buf) 399 if (!TIPC_LOG->buf) {
400 spin_unlock_bh(&print_lock);
414 reply = tipc_cfg_reply_ultra_string("log not activated\n"); 401 reply = tipc_cfg_reply_ultra_string("log not activated\n");
415 else if (tipc_printbuf_empty(TIPC_LOG)) 402 } else if (tipc_printbuf_empty(TIPC_LOG)) {
403 spin_unlock_bh(&print_lock);
416 reply = tipc_cfg_reply_ultra_string("log is empty\n"); 404 reply = tipc_cfg_reply_ultra_string("log is empty\n");
405 }
417 else { 406 else {
418 struct tlv_desc *rep_tlv; 407 struct tlv_desc *rep_tlv;
419 struct print_buf pb; 408 struct print_buf pb;
420 int str_len; 409 int str_len;
421 410
422 str_len = min(TIPC_LOG->size, 32768u); 411 str_len = min(TIPC_LOG->size, 32768u);
412 spin_unlock_bh(&print_lock);
423 reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len)); 413 reply = tipc_cfg_reply_alloc(TLV_SPACE(str_len));
424 if (reply) { 414 if (reply) {
425 rep_tlv = (struct tlv_desc *)reply->data; 415 rep_tlv = (struct tlv_desc *)reply->data;
426 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); 416 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), str_len);
417 spin_lock_bh(&print_lock);
427 tipc_printbuf_move(&pb, TIPC_LOG); 418 tipc_printbuf_move(&pb, TIPC_LOG);
419 spin_unlock_bh(&print_lock);
428 str_len = strlen(TLV_DATA(rep_tlv)) + 1; 420 str_len = strlen(TLV_DATA(rep_tlv)) + 1;
429 skb_put(reply, TLV_SPACE(str_len)); 421 skb_put(reply, TLV_SPACE(str_len));
430 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 422 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
431 } 423 }
432 } 424 }
433 spin_unlock_bh(&print_lock);
434 return reply; 425 return reply;
435} 426}
436 427
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h
index c01b085000e0..5ef1bc8f64ef 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/dbg.h
@@ -2,7 +2,7 @@
2 * net/tipc/dbg.h: Include file for TIPC print buffer routines 2 * net/tipc/dbg.h: Include file for TIPC print buffer routines
3 * 3 *
4 * Copyright (c) 1997-2006, Ericsson AB 4 * Copyright (c) 1997-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2007, 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
@@ -42,14 +42,14 @@
42 * @buf: pointer to character array containing print buffer contents 42 * @buf: pointer to character array containing print buffer contents
43 * @size: size of character array 43 * @size: size of character array
44 * @crs: pointer to first unused space in character array (i.e. final NUL) 44 * @crs: pointer to first unused space in character array (i.e. final NUL)
45 * @next: used to link print buffers when printing to more than one at a time 45 * @echo: echo output to system console if non-zero
46 */ 46 */
47 47
48struct print_buf { 48struct print_buf {
49 char *buf; 49 char *buf;
50 u32 size; 50 u32 size;
51 char *crs; 51 char *crs;
52 struct print_buf *next; 52 int echo;
53}; 53};
54 54
55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ 55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */
@@ -61,10 +61,10 @@ int tipc_printbuf_empty(struct print_buf *pb);
61int tipc_printbuf_validate(struct print_buf *pb); 61int tipc_printbuf_validate(struct print_buf *pb);
62void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); 62void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from);
63 63
64void tipc_log_reinit(int log_size); 64int tipc_log_resize(int log_size);
65void tipc_log_stop(void);
66 65
67struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space); 66struct sk_buff *tipc_log_resize_cmd(const void *req_tlv_area,
67 int req_tlv_space);
68struct sk_buff *tipc_log_dump(void); 68struct sk_buff *tipc_log_dump(void);
69 69
70#endif 70#endif
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 5d643e5721eb..1657f0e795ff 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -120,9 +120,8 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
120 120
121 if (buf) { 121 if (buf) {
122 msg = buf_msg(buf); 122 msg = buf_msg(buf);
123 msg_init(msg, LINK_CONFIG, type, TIPC_OK, DSC_H_SIZE, 123 msg_init(msg, LINK_CONFIG, type, DSC_H_SIZE, dest_domain);
124 dest_domain); 124 msg_set_non_seq(msg, 1);
125 msg_set_non_seq(msg);
126 msg_set_req_links(msg, req_links); 125 msg_set_req_links(msg, req_links);
127 msg_set_dest_domain(msg, dest_domain); 126 msg_set_dest_domain(msg, dest_domain);
128 msg_set_bc_netid(msg, tipc_net_id); 127 msg_set_bc_netid(msg, tipc_net_id);
@@ -156,11 +155,11 @@ static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
156/** 155/**
157 * tipc_disc_recv_msg - handle incoming link setup message (request or response) 156 * tipc_disc_recv_msg - handle incoming link setup message (request or response)
158 * @buf: buffer containing message 157 * @buf: buffer containing message
158 * @b_ptr: bearer that message arrived on
159 */ 159 */
160 160
161void tipc_disc_recv_msg(struct sk_buff *buf) 161void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
162{ 162{
163 struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle;
164 struct link *link; 163 struct link *link;
165 struct tipc_media_addr media_addr; 164 struct tipc_media_addr media_addr;
166 struct tipc_msg *msg = buf_msg(buf); 165 struct tipc_msg *msg = buf_msg(buf);
@@ -200,9 +199,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
200 dbg(" in own cluster\n"); 199 dbg(" in own cluster\n");
201 if (n_ptr == NULL) { 200 if (n_ptr == NULL) {
202 n_ptr = tipc_node_create(orig); 201 n_ptr = tipc_node_create(orig);
203 } 202 if (!n_ptr)
204 if (n_ptr == NULL) { 203 return;
205 return;
206 } 204 }
207 spin_lock_bh(&n_ptr->lock); 205 spin_lock_bh(&n_ptr->lock);
208 link = n_ptr->links[b_ptr->identity]; 206 link = n_ptr->links[b_ptr->identity];
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index 9fd7587b143a..c36eaeb7d5d0 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -48,7 +48,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
48void tipc_disc_update_link_req(struct link_req *req); 48void tipc_disc_update_link_req(struct link_req *req);
49void tipc_disc_stop_link_req(struct link_req *req); 49void tipc_disc_stop_link_req(struct link_req *req);
50 50
51void tipc_disc_recv_msg(struct sk_buff *buf); 51void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr);
52 52
53void tipc_disc_link_event(u32 addr, char *name, int up); 53void tipc_disc_link_event(u32 addr, char *name, int up);
54#if 0 54#if 0
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 9cd35eec3e7f..fe43ef7dd7e3 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -82,7 +82,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
82 dev->dev_addr, clone->len); 82 dev->dev_addr, clone->len);
83 dev_queue_xmit(clone); 83 dev_queue_xmit(clone);
84 } 84 }
85 return TIPC_OK; 85 return 0;
86} 86}
87 87
88/** 88/**
@@ -101,7 +101,7 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
101 struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; 101 struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
102 u32 size; 102 u32 size;
103 103
104 if (dev_net(dev) != &init_net) { 104 if (!net_eq(dev_net(dev), &init_net)) {
105 kfree_skb(buf); 105 kfree_skb(buf);
106 return 0; 106 return 0;
107 } 107 }
@@ -113,12 +113,12 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
113 if (likely(buf->len == size)) { 113 if (likely(buf->len == size)) {
114 buf->next = NULL; 114 buf->next = NULL;
115 tipc_recv_msg(buf, eb_ptr->bearer); 115 tipc_recv_msg(buf, eb_ptr->bearer);
116 return TIPC_OK; 116 return 0;
117 } 117 }
118 } 118 }
119 } 119 }
120 kfree_skb(buf); 120 kfree_skb(buf);
121 return TIPC_OK; 121 return 0;
122} 122}
123 123
124/** 124/**
@@ -198,7 +198,7 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
198 struct eth_bearer *eb_ptr = &eth_bearers[0]; 198 struct eth_bearer *eb_ptr = &eth_bearers[0];
199 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS]; 199 struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
200 200
201 if (dev_net(dev) != &init_net) 201 if (!net_eq(dev_net(dev), &init_net))
202 return NOTIFY_DONE; 202 return NOTIFY_DONE;
203 203
204 while ((eb_ptr->dev != dev)) { 204 while ((eb_ptr->dev != dev)) {
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2a26a16e269f..d60113ba4b1b 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -51,6 +51,12 @@
51 51
52 52
53/* 53/*
54 * Out-of-range value for link session numbers
55 */
56
57#define INVALID_SESSION 0x10000
58
59/*
54 * Limit for deferred reception queue: 60 * Limit for deferred reception queue:
55 */ 61 */
56 62
@@ -147,9 +153,21 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
147 153
148#define LINK_LOG_BUF_SIZE 0 154#define LINK_LOG_BUF_SIZE 0
149 155
150#define dbg_link(fmt, arg...) do {if (LINK_LOG_BUF_SIZE) tipc_printf(&l_ptr->print_buf, fmt, ## arg); } while(0) 156#define dbg_link(fmt, arg...) \
151#define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) tipc_msg_print(&l_ptr->print_buf, msg, txt); } while(0) 157 do { \
152#define dbg_link_state(txt) do {if (LINK_LOG_BUF_SIZE) link_print(l_ptr, &l_ptr->print_buf, txt); } while(0) 158 if (LINK_LOG_BUF_SIZE) \
159 tipc_printf(&l_ptr->print_buf, fmt, ## arg); \
160 } while (0)
161#define dbg_link_msg(msg, txt) \
162 do { \
163 if (LINK_LOG_BUF_SIZE) \
164 tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \
165 } while (0)
166#define dbg_link_state(txt) \
167 do { \
168 if (LINK_LOG_BUF_SIZE) \
169 link_print(l_ptr, &l_ptr->print_buf, txt); \
170 } while (0)
153#define dbg_link_dump() do { \ 171#define dbg_link_dump() do { \
154 if (LINK_LOG_BUF_SIZE) { \ 172 if (LINK_LOG_BUF_SIZE) { \
155 tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ 173 tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \
@@ -450,9 +468,9 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
450 468
451 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; 469 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
452 msg = l_ptr->pmsg; 470 msg = l_ptr->pmsg;
453 msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 471 msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr);
454 msg_set_size(msg, sizeof(l_ptr->proto_msg)); 472 msg_set_size(msg, sizeof(l_ptr->proto_msg));
455 msg_set_session(msg, tipc_random); 473 msg_set_session(msg, (tipc_random & 0xffff));
456 msg_set_bearer_id(msg, b_ptr->identity); 474 msg_set_bearer_id(msg, b_ptr->identity);
457 strcpy((char *)msg_data(msg), if_name); 475 strcpy((char *)msg_data(msg), if_name);
458 476
@@ -693,10 +711,10 @@ void tipc_link_reset(struct link *l_ptr)
693 u32 checkpoint = l_ptr->next_in_no; 711 u32 checkpoint = l_ptr->next_in_no;
694 int was_active_link = tipc_link_is_active(l_ptr); 712 int was_active_link = tipc_link_is_active(l_ptr);
695 713
696 msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); 714 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
697 715
698 /* Link is down, accept any session: */ 716 /* Link is down, accept any session */
699 l_ptr->peer_session = 0; 717 l_ptr->peer_session = INVALID_SESSION;
700 718
701 /* Prepare for max packet size negotiation */ 719 /* Prepare for max packet size negotiation */
702 link_init_max_pkt(l_ptr); 720 link_init_max_pkt(l_ptr);
@@ -1110,7 +1128,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1110 1128
1111 if (bundler) { 1129 if (bundler) {
1112 msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, 1130 msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG,
1113 TIPC_OK, INT_H_SIZE, l_ptr->addr); 1131 INT_H_SIZE, l_ptr->addr);
1114 skb_copy_to_linear_data(bundler, &bundler_hdr, 1132 skb_copy_to_linear_data(bundler, &bundler_hdr,
1115 INT_H_SIZE); 1133 INT_H_SIZE);
1116 skb_trim(bundler, INT_H_SIZE); 1134 skb_trim(bundler, INT_H_SIZE);
@@ -1374,7 +1392,7 @@ again:
1374 1392
1375 msg_dbg(hdr, ">FRAGMENTING>"); 1393 msg_dbg(hdr, ">FRAGMENTING>");
1376 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 1394 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
1377 TIPC_OK, INT_H_SIZE, msg_destnode(hdr)); 1395 INT_H_SIZE, msg_destnode(hdr));
1378 msg_set_link_selector(&fragm_hdr, sender->publ.ref); 1396 msg_set_link_selector(&fragm_hdr, sender->publ.ref);
1379 msg_set_size(&fragm_hdr, max_pkt); 1397 msg_set_size(&fragm_hdr, max_pkt);
1380 msg_set_fragm_no(&fragm_hdr, 1); 1398 msg_set_fragm_no(&fragm_hdr, 1);
@@ -1543,7 +1561,7 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1543 l_ptr->retransm_queue_head = mod(++r_q_head); 1561 l_ptr->retransm_queue_head = mod(++r_q_head);
1544 l_ptr->retransm_queue_size = --r_q_size; 1562 l_ptr->retransm_queue_size = --r_q_size;
1545 l_ptr->stats.retransmitted++; 1563 l_ptr->stats.retransmitted++;
1546 return TIPC_OK; 1564 return 0;
1547 } else { 1565 } else {
1548 l_ptr->stats.bearer_congs++; 1566 l_ptr->stats.bearer_congs++;
1549 msg_dbg(buf_msg(buf), "|>DEF-RETR>"); 1567 msg_dbg(buf_msg(buf), "|>DEF-RETR>");
@@ -1562,7 +1580,7 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1562 l_ptr->unacked_window = 0; 1580 l_ptr->unacked_window = 0;
1563 buf_discard(buf); 1581 buf_discard(buf);
1564 l_ptr->proto_msg_queue = NULL; 1582 l_ptr->proto_msg_queue = NULL;
1565 return TIPC_OK; 1583 return 0;
1566 } else { 1584 } else {
1567 msg_dbg(buf_msg(buf), "|>DEF-PROT>"); 1585 msg_dbg(buf_msg(buf), "|>DEF-PROT>");
1568 l_ptr->stats.bearer_congs++; 1586 l_ptr->stats.bearer_congs++;
@@ -1586,7 +1604,7 @@ u32 tipc_link_push_packet(struct link *l_ptr)
1586 msg_set_type(msg, CLOSED_MSG); 1604 msg_set_type(msg, CLOSED_MSG);
1587 msg_dbg(msg, ">PUSH-DATA>"); 1605 msg_dbg(msg, ">PUSH-DATA>");
1588 l_ptr->next_out = buf->next; 1606 l_ptr->next_out = buf->next;
1589 return TIPC_OK; 1607 return 0;
1590 } else { 1608 } else {
1591 msg_dbg(msg, "|PUSH-DATA|"); 1609 msg_dbg(msg, "|PUSH-DATA|");
1592 l_ptr->stats.bearer_congs++; 1610 l_ptr->stats.bearer_congs++;
@@ -1610,8 +1628,8 @@ void tipc_link_push_queue(struct link *l_ptr)
1610 1628
1611 do { 1629 do {
1612 res = tipc_link_push_packet(l_ptr); 1630 res = tipc_link_push_packet(l_ptr);
1613 } 1631 } while (!res);
1614 while (res == TIPC_OK); 1632
1615 if (res == PUSH_FAILED) 1633 if (res == PUSH_FAILED)
1616 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 1634 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
1617} 1635}
@@ -1651,7 +1669,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1651 struct tipc_msg *msg = buf_msg(buf); 1669 struct tipc_msg *msg = buf_msg(buf);
1652 1670
1653 warn("Retransmission failure on link <%s>\n", l_ptr->name); 1671 warn("Retransmission failure on link <%s>\n", l_ptr->name);
1654 tipc_msg_print(TIPC_OUTPUT, msg, ">RETR-FAIL>"); 1672 tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>");
1655 1673
1656 if (l_ptr->addr) { 1674 if (l_ptr->addr) {
1657 1675
@@ -1748,21 +1766,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1748 l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; 1766 l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0;
1749} 1767}
1750 1768
1751/*
1752 * link_recv_non_seq: Receive packets which are outside
1753 * the link sequence flow
1754 */
1755
1756static void link_recv_non_seq(struct sk_buff *buf)
1757{
1758 struct tipc_msg *msg = buf_msg(buf);
1759
1760 if (msg_user(msg) == LINK_CONFIG)
1761 tipc_disc_recv_msg(buf);
1762 else
1763 tipc_bclink_recv_pkt(buf);
1764}
1765
1766/** 1769/**
1767 * link_insert_deferred_queue - insert deferred messages back into receive chain 1770 * link_insert_deferred_queue - insert deferred messages back into receive chain
1768 */ 1771 */
@@ -1839,7 +1842,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1839{ 1842{
1840 read_lock_bh(&tipc_net_lock); 1843 read_lock_bh(&tipc_net_lock);
1841 while (head) { 1844 while (head) {
1842 struct bearer *b_ptr; 1845 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1843 struct node *n_ptr; 1846 struct node *n_ptr;
1844 struct link *l_ptr; 1847 struct link *l_ptr;
1845 struct sk_buff *crs; 1848 struct sk_buff *crs;
@@ -1850,9 +1853,6 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1850 u32 released = 0; 1853 u32 released = 0;
1851 int type; 1854 int type;
1852 1855
1853 b_ptr = (struct bearer *)tb_ptr;
1854 TIPC_SKB_CB(buf)->handle = b_ptr;
1855
1856 head = head->next; 1856 head = head->next;
1857 1857
1858 /* Ensure message is well-formed */ 1858 /* Ensure message is well-formed */
@@ -1871,7 +1871,10 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1871 msg = buf_msg(buf); 1871 msg = buf_msg(buf);
1872 1872
1873 if (unlikely(msg_non_seq(msg))) { 1873 if (unlikely(msg_non_seq(msg))) {
1874 link_recv_non_seq(buf); 1874 if (msg_user(msg) == LINK_CONFIG)
1875 tipc_disc_recv_msg(buf, b_ptr);
1876 else
1877 tipc_bclink_recv_pkt(buf);
1875 continue; 1878 continue;
1876 } 1879 }
1877 1880
@@ -1978,8 +1981,6 @@ deliver:
1978 if (link_recv_changeover_msg(&l_ptr, &buf)) { 1981 if (link_recv_changeover_msg(&l_ptr, &buf)) {
1979 msg = buf_msg(buf); 1982 msg = buf_msg(buf);
1980 seq_no = msg_seqno(msg); 1983 seq_no = msg_seqno(msg);
1981 TIPC_SKB_CB(buf)->handle
1982 = b_ptr;
1983 if (type == ORIGINAL_MSG) 1984 if (type == ORIGINAL_MSG)
1984 goto deliver; 1985 goto deliver;
1985 goto protocol_check; 1986 goto protocol_check;
@@ -2263,7 +2264,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2263 switch (msg_type(msg)) { 2264 switch (msg_type(msg)) {
2264 2265
2265 case RESET_MSG: 2266 case RESET_MSG:
2266 if (!link_working_unknown(l_ptr) && l_ptr->peer_session) { 2267 if (!link_working_unknown(l_ptr) &&
2268 (l_ptr->peer_session != INVALID_SESSION)) {
2267 if (msg_session(msg) == l_ptr->peer_session) { 2269 if (msg_session(msg) == l_ptr->peer_session) {
2268 dbg("Duplicate RESET: %u<->%u\n", 2270 dbg("Duplicate RESET: %u<->%u\n",
2269 msg_session(msg), l_ptr->peer_session); 2271 msg_session(msg), l_ptr->peer_session);
@@ -2424,7 +2426,7 @@ void tipc_link_changeover(struct link *l_ptr)
2424 } 2426 }
2425 2427
2426 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2428 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2427 ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 2429 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
2428 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2430 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2429 msg_set_msgcnt(&tunnel_hdr, msgcount); 2431 msg_set_msgcnt(&tunnel_hdr, msgcount);
2430 dbg("Link changeover requires %u tunnel messages\n", msgcount); 2432 dbg("Link changeover requires %u tunnel messages\n", msgcount);
@@ -2479,7 +2481,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2479 struct tipc_msg tunnel_hdr; 2481 struct tipc_msg tunnel_hdr;
2480 2482
2481 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2483 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2482 DUPLICATE_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 2484 DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr);
2483 msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); 2485 msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size);
2484 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2486 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2485 iter = l_ptr->first_out; 2487 iter = l_ptr->first_out;
@@ -2672,10 +2674,12 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2672 u32 pack_sz = link_max_pkt(l_ptr); 2674 u32 pack_sz = link_max_pkt(l_ptr);
2673 u32 fragm_sz = pack_sz - INT_H_SIZE; 2675 u32 fragm_sz = pack_sz - INT_H_SIZE;
2674 u32 fragm_no = 1; 2676 u32 fragm_no = 1;
2675 u32 destaddr = msg_destnode(inmsg); 2677 u32 destaddr;
2676 2678
2677 if (msg_short(inmsg)) 2679 if (msg_short(inmsg))
2678 destaddr = l_ptr->addr; 2680 destaddr = l_ptr->addr;
2681 else
2682 destaddr = msg_destnode(inmsg);
2679 2683
2680 if (msg_routed(inmsg)) 2684 if (msg_routed(inmsg))
2681 msg_set_prevnode(inmsg, tipc_own_addr); 2685 msg_set_prevnode(inmsg, tipc_own_addr);
@@ -2683,7 +2687,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2683 /* Prepare reusable fragment header: */ 2687 /* Prepare reusable fragment header: */
2684 2688
2685 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, 2689 msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
2686 TIPC_OK, INT_H_SIZE, destaddr); 2690 INT_H_SIZE, destaddr);
2687 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); 2691 msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg));
2688 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); 2692 msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++));
2689 msg_set_fragm_no(&fragm_hdr, fragm_no); 2693 msg_set_fragm_no(&fragm_hdr, fragm_no);
@@ -2994,7 +2998,7 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space
2994 link_set_supervision_props(l_ptr, new_value); 2998 link_set_supervision_props(l_ptr, new_value);
2995 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 2999 tipc_link_send_proto_msg(l_ptr, STATE_MSG,
2996 0, 0, new_value, 0, 0); 3000 0, 0, new_value, 0, 0);
2997 res = TIPC_OK; 3001 res = 0;
2998 } 3002 }
2999 break; 3003 break;
3000 case TIPC_CMD_SET_LINK_PRI: 3004 case TIPC_CMD_SET_LINK_PRI:
@@ -3003,14 +3007,14 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space
3003 l_ptr->priority = new_value; 3007 l_ptr->priority = new_value;
3004 tipc_link_send_proto_msg(l_ptr, STATE_MSG, 3008 tipc_link_send_proto_msg(l_ptr, STATE_MSG,
3005 0, 0, 0, new_value, 0); 3009 0, 0, 0, new_value, 0);
3006 res = TIPC_OK; 3010 res = 0;
3007 } 3011 }
3008 break; 3012 break;
3009 case TIPC_CMD_SET_LINK_WINDOW: 3013 case TIPC_CMD_SET_LINK_WINDOW:
3010 if ((new_value >= TIPC_MIN_LINK_WIN) && 3014 if ((new_value >= TIPC_MIN_LINK_WIN) &&
3011 (new_value <= TIPC_MAX_LINK_WIN)) { 3015 (new_value <= TIPC_MAX_LINK_WIN)) {
3012 tipc_link_set_queue_limits(l_ptr, new_value); 3016 tipc_link_set_queue_limits(l_ptr, new_value);
3013 res = TIPC_OK; 3017 res = 0;
3014 } 3018 }
3015 break; 3019 break;
3016 } 3020 }
@@ -3226,7 +3230,7 @@ int link_control(const char *name, u32 op, u32 val)
3226 if (op == TIPC_CMD_UNBLOCK_LINK) { 3230 if (op == TIPC_CMD_UNBLOCK_LINK) {
3227 l_ptr->blocked = 0; 3231 l_ptr->blocked = 0;
3228 } 3232 }
3229 res = TIPC_OK; 3233 res = 0;
3230 } 3234 }
3231 tipc_node_unlock(node); 3235 tipc_node_unlock(node);
3232 } 3236 }
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 696a8633df75..73dcd00d674e 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -41,7 +41,9 @@
41#include "bearer.h" 41#include "bearer.h"
42 42
43 43
44void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str) 44#ifdef CONFIG_TIPC_DEBUG
45
46void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
45{ 47{
46 u32 usr = msg_user(msg); 48 u32 usr = msg_user(msg);
47 tipc_printf(buf, str); 49 tipc_printf(buf, str);
@@ -228,13 +230,10 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str
228 230
229 switch (usr) { 231 switch (usr) {
230 case CONN_MANAGER: 232 case CONN_MANAGER:
231 case NAME_DISTRIBUTOR:
232 case TIPC_LOW_IMPORTANCE: 233 case TIPC_LOW_IMPORTANCE:
233 case TIPC_MEDIUM_IMPORTANCE: 234 case TIPC_MEDIUM_IMPORTANCE:
234 case TIPC_HIGH_IMPORTANCE: 235 case TIPC_HIGH_IMPORTANCE:
235 case TIPC_CRITICAL_IMPORTANCE: 236 case TIPC_CRITICAL_IMPORTANCE:
236 if (msg_short(msg))
237 break; /* No error */
238 switch (msg_errcode(msg)) { 237 switch (msg_errcode(msg)) {
239 case TIPC_OK: 238 case TIPC_OK:
240 break; 239 break;
@@ -315,9 +314,11 @@ void tipc_msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str
315 } 314 }
316 tipc_printf(buf, "\n"); 315 tipc_printf(buf, "\n");
317 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { 316 if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) {
318 tipc_msg_print(buf,msg_get_wrapped(msg)," /"); 317 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
319 } 318 }
320 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { 319 if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) {
321 tipc_msg_print(buf,msg_get_wrapped(msg)," /"); 320 tipc_msg_dbg(buf, msg_get_wrapped(msg), " /");
322 } 321 }
323} 322}
323
324#endif
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index ad487e8abcc2..7ee6ae238147 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-2007, Wind River Systems 5 * Copyright (c) 2005-2008, 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
@@ -75,6 +75,14 @@ static inline void msg_set_bits(struct tipc_msg *m, u32 w,
75 m->hdr[w] |= htonl(val); 75 m->hdr[w] |= htonl(val);
76} 76}
77 77
78static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b)
79{
80 u32 temp = msg->hdr[a];
81
82 msg->hdr[a] = msg->hdr[b];
83 msg->hdr[b] = temp;
84}
85
78/* 86/*
79 * Word 0 87 * Word 0
80 */ 88 */
@@ -119,9 +127,9 @@ static inline int msg_non_seq(struct tipc_msg *m)
119 return msg_bits(m, 0, 20, 1); 127 return msg_bits(m, 0, 20, 1);
120} 128}
121 129
122static inline void msg_set_non_seq(struct tipc_msg *m) 130static inline void msg_set_non_seq(struct tipc_msg *m, u32 n)
123{ 131{
124 msg_set_bits(m, 0, 20, 1, 1); 132 msg_set_bits(m, 0, 20, 1, n);
125} 133}
126 134
127static inline int msg_dest_droppable(struct tipc_msg *m) 135static inline int msg_dest_droppable(struct tipc_msg *m)
@@ -224,6 +232,25 @@ static inline void msg_set_seqno(struct tipc_msg *m, u32 n)
224 msg_set_bits(m, 2, 0, 0xffff, n); 232 msg_set_bits(m, 2, 0, 0xffff, n);
225} 233}
226 234
235/*
236 * TIPC may utilize the "link ack #" and "link seq #" fields of a short
237 * message header to hold the destination node for the message, since the
238 * normal "dest node" field isn't present. This cache is only referenced
239 * when required, so populating the cache of a longer message header is
240 * harmless (as long as the header has the two link sequence fields present).
241 *
242 * Note: Host byte order is OK here, since the info never goes off-card.
243 */
244
245static inline u32 msg_destnode_cache(struct tipc_msg *m)
246{
247 return m->hdr[2];
248}
249
250static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
251{
252 m->hdr[2] = dnode;
253}
227 254
228/* 255/*
229 * Words 3-10 256 * Words 3-10
@@ -325,7 +352,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
325 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
326 w0:|vers |msg usr|hdr sz |n|resrv| packet size | 353 w0:|vers |msg usr|hdr sz |n|resrv| packet size |
327 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
328 w1:|m typ|rsv=0| sequence gap | broadcast ack no | 355 w1:|m typ| sequence gap | broadcast ack no |
329 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 356 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
330 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | 357 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to |
331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 358 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -388,12 +415,12 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
388 415
389static inline u32 msg_seq_gap(struct tipc_msg *m) 416static inline u32 msg_seq_gap(struct tipc_msg *m)
390{ 417{
391 return msg_bits(m, 1, 16, 0xff); 418 return msg_bits(m, 1, 16, 0x1fff);
392} 419}
393 420
394static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) 421static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
395{ 422{
396 msg_set_bits(m, 1, 16, 0xff, n); 423 msg_set_bits(m, 1, 16, 0x1fff, n);
397} 424}
398 425
399static inline u32 msg_req_links(struct tipc_msg *m) 426static inline u32 msg_req_links(struct tipc_msg *m)
@@ -696,7 +723,7 @@ static inline u32 msg_tot_importance(struct tipc_msg *m)
696 723
697 724
698static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, 725static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
699 u32 err, u32 hsize, u32 destnode) 726 u32 hsize, u32 destnode)
700{ 727{
701 memset(m, 0, hsize); 728 memset(m, 0, hsize);
702 msg_set_version(m); 729 msg_set_version(m);
@@ -705,7 +732,6 @@ static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
705 msg_set_size(m, hsize); 732 msg_set_size(m, hsize);
706 msg_set_prevnode(m, tipc_own_addr); 733 msg_set_prevnode(m, tipc_own_addr);
707 msg_set_type(m, type); 734 msg_set_type(m, type);
708 msg_set_errcode(m, err);
709 if (!msg_short(m)) { 735 if (!msg_short(m)) {
710 msg_set_orignode(m, tipc_own_addr); 736 msg_set_orignode(m, tipc_own_addr);
711 msg_set_destnode(m, destnode); 737 msg_set_destnode(m, destnode);
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 39fd1619febf..10a69894e2fd 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -41,9 +41,6 @@
41#include "msg.h" 41#include "msg.h"
42#include "name_distr.h" 42#include "name_distr.h"
43 43
44#undef DBG_OUTPUT
45#define DBG_OUTPUT NULL
46
47#define ITEM_SIZE sizeof(struct distr_item) 44#define ITEM_SIZE sizeof(struct distr_item)
48 45
49/** 46/**
@@ -106,8 +103,7 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
106 103
107 if (buf != NULL) { 104 if (buf != NULL) {
108 msg = buf_msg(buf); 105 msg = buf_msg(buf);
109 msg_init(msg, NAME_DISTRIBUTOR, type, TIPC_OK, 106 msg_init(msg, NAME_DISTRIBUTOR, type, LONG_H_SIZE, dest);
110 LONG_H_SIZE, dest);
111 msg_set_size(msg, LONG_H_SIZE + size); 107 msg_set_size(msg, LONG_H_SIZE + size);
112 } 108 }
113 return buf; 109 return buf;
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index ac7dfdda7973..cd72e22b132b 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -2,7 +2,7 @@
2 * net/tipc/name_table.c: TIPC name table code 2 * net/tipc/name_table.c: TIPC name table code
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-2008, 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
@@ -52,9 +52,16 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */
52 * struct sub_seq - container for all published instances of a name sequence 52 * struct sub_seq - container for all published instances of a name sequence
53 * @lower: name sequence lower bound 53 * @lower: name sequence lower bound
54 * @upper: name sequence upper bound 54 * @upper: name sequence upper bound
55 * @node_list: circular list of matching publications with >= node scope 55 * @node_list: circular list of publications made by own node
56 * @cluster_list: circular list of matching publications with >= cluster scope 56 * @cluster_list: circular list of publications made by own cluster
57 * @zone_list: circular list of matching publications with >= zone scope 57 * @zone_list: circular list of publications made by own zone
58 * @node_list_size: number of entries in "node_list"
59 * @cluster_list_size: number of entries in "cluster_list"
60 * @zone_list_size: number of entries in "zone_list"
61 *
62 * Note: The zone list always contains at least one entry, since all
63 * publications of the associated name sequence belong to it.
64 * (The cluster and node lists may be empty.)
58 */ 65 */
59 66
60struct sub_seq { 67struct sub_seq {
@@ -63,6 +70,9 @@ struct sub_seq {
63 struct publication *node_list; 70 struct publication *node_list;
64 struct publication *cluster_list; 71 struct publication *cluster_list;
65 struct publication *zone_list; 72 struct publication *zone_list;
73 u32 node_list_size;
74 u32 cluster_list_size;
75 u32 zone_list_size;
66}; 76};
67 77
68/** 78/**
@@ -74,7 +84,7 @@ struct sub_seq {
74 * @first_free: array index of first unused sub-sequence entry 84 * @first_free: array index of first unused sub-sequence entry
75 * @ns_list: links to adjacent name sequences in hash chain 85 * @ns_list: links to adjacent name sequences in hash chain
76 * @subscriptions: list of subscriptions for this 'type' 86 * @subscriptions: list of subscriptions for this 'type'
77 * @lock: spinlock controlling access to name sequence structure 87 * @lock: spinlock controlling access to publication lists of all sub-sequences
78 */ 88 */
79 89
80struct name_seq { 90struct name_seq {
@@ -317,6 +327,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
317 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", 327 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n",
318 publ, node, publ->node, publ->subscr.node); 328 publ, node, publ->node, publ->subscr.node);
319 329
330 sseq->zone_list_size++;
320 if (!sseq->zone_list) 331 if (!sseq->zone_list)
321 sseq->zone_list = publ->zone_list_next = publ; 332 sseq->zone_list = publ->zone_list_next = publ;
322 else { 333 else {
@@ -325,6 +336,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
325 } 336 }
326 337
327 if (in_own_cluster(node)) { 338 if (in_own_cluster(node)) {
339 sseq->cluster_list_size++;
328 if (!sseq->cluster_list) 340 if (!sseq->cluster_list)
329 sseq->cluster_list = publ->cluster_list_next = publ; 341 sseq->cluster_list = publ->cluster_list_next = publ;
330 else { 342 else {
@@ -335,6 +347,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
335 } 347 }
336 348
337 if (node == tipc_own_addr) { 349 if (node == tipc_own_addr) {
350 sseq->node_list_size++;
338 if (!sseq->node_list) 351 if (!sseq->node_list)
339 sseq->node_list = publ->node_list_next = publ; 352 sseq->node_list = publ->node_list_next = publ;
340 else { 353 else {
@@ -411,6 +424,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
411 } else { 424 } else {
412 sseq->zone_list = NULL; 425 sseq->zone_list = NULL;
413 } 426 }
427 sseq->zone_list_size--;
414 428
415 /* Remove publication from cluster scope list, if present */ 429 /* Remove publication from cluster scope list, if present */
416 430
@@ -439,6 +453,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
439 } else { 453 } else {
440 sseq->cluster_list = NULL; 454 sseq->cluster_list = NULL;
441 } 455 }
456 sseq->cluster_list_size--;
442 } 457 }
443end_cluster: 458end_cluster:
444 459
@@ -469,6 +484,7 @@ end_cluster:
469 } else { 484 } else {
470 sseq->node_list = NULL; 485 sseq->node_list = NULL;
471 } 486 }
487 sseq->node_list_size--;
472 } 488 }
473end_node: 489end_node:
474 490
@@ -709,15 +725,18 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
709 725
710 if (sseq->lower > upper) 726 if (sseq->lower > upper)
711 break; 727 break;
712 publ = sseq->cluster_list; 728
713 if (publ && (publ->scope <= limit)) 729 publ = sseq->node_list;
730 if (publ) {
714 do { 731 do {
715 if (publ->node == tipc_own_addr) 732 if (publ->scope <= limit)
716 tipc_port_list_add(dports, publ->ref); 733 tipc_port_list_add(dports, publ->ref);
717 else 734 publ = publ->node_list_next;
718 res = 1; 735 } while (publ != sseq->node_list);
719 publ = publ->cluster_list_next; 736 }
720 } while (publ != sseq->cluster_list); 737
738 if (sseq->cluster_list_size != sseq->node_list_size)
739 res = 1;
721 } 740 }
722 741
723 spin_unlock_bh(&seq->lock); 742 spin_unlock_bh(&seq->lock);
@@ -905,6 +924,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
905 struct sub_seq *sseq; 924 struct sub_seq *sseq;
906 char typearea[11]; 925 char typearea[11];
907 926
927 if (seq->first_free == 0)
928 return;
929
908 sprintf(typearea, "%-10u", seq->type); 930 sprintf(typearea, "%-10u", seq->type);
909 931
910 if (depth == 1) { 932 if (depth == 1) {
@@ -915,7 +937,9 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
915 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { 937 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) {
916 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { 938 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) {
917 tipc_printf(buf, "%s ", typearea); 939 tipc_printf(buf, "%s ", typearea);
940 spin_lock_bh(&seq->lock);
918 subseq_list(sseq, buf, depth, index); 941 subseq_list(sseq, buf, depth, index);
942 spin_unlock_bh(&seq->lock);
919 sprintf(typearea, "%10s", " "); 943 sprintf(typearea, "%10s", " ");
920 } 944 }
921 } 945 }
@@ -1050,15 +1074,12 @@ void tipc_nametbl_dump(void)
1050 1074
1051int tipc_nametbl_init(void) 1075int tipc_nametbl_init(void)
1052{ 1076{
1053 int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; 1077 table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
1054 1078 GFP_ATOMIC);
1055 table.types = kzalloc(array_size, GFP_ATOMIC);
1056 if (!table.types) 1079 if (!table.types)
1057 return -ENOMEM; 1080 return -ENOMEM;
1058 1081
1059 write_lock_bh(&tipc_nametbl_lock);
1060 table.local_publ_count = 0; 1082 table.local_publ_count = 0;
1061 write_unlock_bh(&tipc_nametbl_lock);
1062 return 0; 1083 return 0;
1063} 1084}
1064 1085
diff --git a/net/tipc/net.c b/net/tipc/net.c
index c39c76201e8e..ec7b04fbdc43 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -165,7 +165,7 @@ static int net_init(void)
165 if (!tipc_net.zones) { 165 if (!tipc_net.zones) {
166 return -ENOMEM; 166 return -ENOMEM;
167 } 167 }
168 return TIPC_OK; 168 return 0;
169} 169}
170 170
171static void net_stop(void) 171static void net_stop(void)
@@ -266,7 +266,7 @@ void tipc_net_route_msg(struct sk_buff *buf)
266 tipc_link_send(buf, dnode, msg_link_selector(msg)); 266 tipc_link_send(buf, dnode, msg_link_selector(msg));
267} 267}
268 268
269int tipc_net_start(void) 269int tipc_net_start(u32 addr)
270{ 270{
271 char addr_string[16]; 271 char addr_string[16];
272 int res; 272 int res;
@@ -274,6 +274,10 @@ int tipc_net_start(void)
274 if (tipc_mode != TIPC_NODE_MODE) 274 if (tipc_mode != TIPC_NODE_MODE)
275 return -ENOPROTOOPT; 275 return -ENOPROTOOPT;
276 276
277 tipc_subscr_stop();
278 tipc_cfg_stop();
279
280 tipc_own_addr = addr;
277 tipc_mode = TIPC_NET_MODE; 281 tipc_mode = TIPC_NET_MODE;
278 tipc_named_reinit(); 282 tipc_named_reinit();
279 tipc_port_reinit(); 283 tipc_port_reinit();
@@ -284,14 +288,14 @@ int tipc_net_start(void)
284 (res = tipc_bclink_init())) { 288 (res = tipc_bclink_init())) {
285 return res; 289 return res;
286 } 290 }
287 tipc_subscr_stop(); 291
288 tipc_cfg_stop();
289 tipc_k_signal((Handler)tipc_subscr_start, 0); 292 tipc_k_signal((Handler)tipc_subscr_start, 0);
290 tipc_k_signal((Handler)tipc_cfg_init, 0); 293 tipc_k_signal((Handler)tipc_cfg_init, 0);
294
291 info("Started in network mode\n"); 295 info("Started in network mode\n");
292 info("Own node address %s, network identity %u\n", 296 info("Own node address %s, network identity %u\n",
293 addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); 297 addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
294 return TIPC_OK; 298 return 0;
295} 299}
296 300
297void tipc_net_stop(void) 301void tipc_net_stop(void)
diff --git a/net/tipc/net.h b/net/tipc/net.h
index a6a0e9976ac9..d154ac2bda9a 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -58,7 +58,7 @@ void tipc_net_route_msg(struct sk_buff *buf);
58struct node *tipc_net_select_remote_node(u32 addr, u32 ref); 58struct node *tipc_net_select_remote_node(u32 addr, u32 ref);
59u32 tipc_net_select_router(u32 addr, u32 ref); 59u32 tipc_net_select_router(u32 addr, u32 ref);
60 60
61int tipc_net_start(void); 61int tipc_net_start(u32 addr);
62void tipc_net_stop(void); 62void tipc_net_stop(void);
63 63
64#endif 64#endif
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 6a7f7b4c2595..c387217bb230 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -2,7 +2,7 @@
2 * net/tipc/netlink.c: TIPC configuration handling 2 * net/tipc/netlink.c: TIPC configuration handling
3 * 3 *
4 * Copyright (c) 2005-2006, Ericsson AB 4 * Copyright (c) 2005-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems 5 * Copyright (c) 2005-2007, 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
@@ -45,15 +45,17 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
45 struct nlmsghdr *req_nlh = info->nlhdr; 45 struct nlmsghdr *req_nlh = info->nlhdr;
46 struct tipc_genlmsghdr *req_userhdr = info->userhdr; 46 struct tipc_genlmsghdr *req_userhdr = info->userhdr;
47 int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); 47 int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
48 u16 cmd;
48 49
49 if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) 50 if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
50 rep_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); 51 cmd = TIPC_CMD_NOT_NET_ADMIN;
51 else 52 else
52 rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, 53 cmd = req_userhdr->cmd;
53 req_userhdr->cmd, 54
54 NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, 55 rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd,
55 NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), 56 NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
56 hdr_space); 57 NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
58 hdr_space);
57 59
58 if (rep_buf) { 60 if (rep_buf) {
59 skb_push(rep_buf, hdr_space); 61 skb_push(rep_buf, hdr_space);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 598f4d3a0098..ee952ad60218 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -52,16 +52,40 @@ static void node_established_contact(struct node *n_ptr);
52 52
53struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ 53struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */
54 54
55static DEFINE_SPINLOCK(node_create_lock);
56
55u32 tipc_own_tag = 0; 57u32 tipc_own_tag = 0;
56 58
59/**
60 * tipc_node_create - create neighboring node
61 *
62 * Currently, this routine is called by neighbor discovery code, which holds
63 * net_lock for reading only. We must take node_create_lock to ensure a node
64 * isn't created twice if two different bearers discover the node at the same
65 * time. (It would be preferable to switch to holding net_lock in write mode,
66 * but this is a non-trivial change.)
67 */
68
57struct node *tipc_node_create(u32 addr) 69struct node *tipc_node_create(u32 addr)
58{ 70{
59 struct cluster *c_ptr; 71 struct cluster *c_ptr;
60 struct node *n_ptr; 72 struct node *n_ptr;
61 struct node **curr_node; 73 struct node **curr_node;
62 74
75 spin_lock_bh(&node_create_lock);
76
77 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
78 if (addr < n_ptr->addr)
79 break;
80 if (addr == n_ptr->addr) {
81 spin_unlock_bh(&node_create_lock);
82 return n_ptr;
83 }
84 }
85
63 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC); 86 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC);
64 if (!n_ptr) { 87 if (!n_ptr) {
88 spin_unlock_bh(&node_create_lock);
65 warn("Node creation failed, no memory\n"); 89 warn("Node creation failed, no memory\n");
66 return NULL; 90 return NULL;
67 } 91 }
@@ -71,6 +95,7 @@ struct node *tipc_node_create(u32 addr)
71 c_ptr = tipc_cltr_create(addr); 95 c_ptr = tipc_cltr_create(addr);
72 } 96 }
73 if (!c_ptr) { 97 if (!c_ptr) {
98 spin_unlock_bh(&node_create_lock);
74 kfree(n_ptr); 99 kfree(n_ptr);
75 return NULL; 100 return NULL;
76 } 101 }
@@ -91,6 +116,7 @@ struct node *tipc_node_create(u32 addr)
91 } 116 }
92 } 117 }
93 (*curr_node) = n_ptr; 118 (*curr_node) = n_ptr;
119 spin_unlock_bh(&node_create_lock);
94 return n_ptr; 120 return n_ptr;
95} 121}
96 122
@@ -574,12 +600,14 @@ u32 tipc_available_nodes(const u32 domain)
574 struct node *n_ptr; 600 struct node *n_ptr;
575 u32 cnt = 0; 601 u32 cnt = 0;
576 602
603 read_lock_bh(&tipc_net_lock);
577 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { 604 for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) {
578 if (!in_scope(domain, n_ptr->addr)) 605 if (!in_scope(domain, n_ptr->addr))
579 continue; 606 continue;
580 if (tipc_node_is_up(n_ptr)) 607 if (tipc_node_is_up(n_ptr))
581 cnt++; 608 cnt++;
582 } 609 }
610 read_unlock_bh(&tipc_net_lock);
583 return cnt; 611 return cnt;
584} 612}
585 613
@@ -599,19 +627,26 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
599 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 627 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
600 " (network address)"); 628 " (network address)");
601 629
602 if (!tipc_nodes) 630 read_lock_bh(&tipc_net_lock);
631 if (!tipc_nodes) {
632 read_unlock_bh(&tipc_net_lock);
603 return tipc_cfg_reply_none(); 633 return tipc_cfg_reply_none();
634 }
604 635
605 /* For now, get space for all other nodes 636 /* For now, get space for all other nodes
606 (will need to modify this when slave nodes are supported */ 637 (will need to modify this when slave nodes are supported */
607 638
608 payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1); 639 payload_size = TLV_SPACE(sizeof(node_info)) * (tipc_max_nodes - 1);
609 if (payload_size > 32768u) 640 if (payload_size > 32768u) {
641 read_unlock_bh(&tipc_net_lock);
610 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 642 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
611 " (too many nodes)"); 643 " (too many nodes)");
644 }
612 buf = tipc_cfg_reply_alloc(payload_size); 645 buf = tipc_cfg_reply_alloc(payload_size);
613 if (!buf) 646 if (!buf) {
647 read_unlock_bh(&tipc_net_lock);
614 return NULL; 648 return NULL;
649 }
615 650
616 /* Add TLVs for all nodes in scope */ 651 /* Add TLVs for all nodes in scope */
617 652
@@ -624,6 +659,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
624 &node_info, sizeof(node_info)); 659 &node_info, sizeof(node_info));
625 } 660 }
626 661
662 read_unlock_bh(&tipc_net_lock);
627 return buf; 663 return buf;
628} 664}
629 665
@@ -646,16 +682,22 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
646 if (tipc_mode != TIPC_NET_MODE) 682 if (tipc_mode != TIPC_NET_MODE)
647 return tipc_cfg_reply_none(); 683 return tipc_cfg_reply_none();
648 684
685 read_lock_bh(&tipc_net_lock);
686
649 /* Get space for all unicast links + multicast link */ 687 /* Get space for all unicast links + multicast link */
650 688
651 payload_size = TLV_SPACE(sizeof(link_info)) * 689 payload_size = TLV_SPACE(sizeof(link_info)) *
652 (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1); 690 (tipc_net.zones[tipc_zone(tipc_own_addr)]->links + 1);
653 if (payload_size > 32768u) 691 if (payload_size > 32768u) {
692 read_unlock_bh(&tipc_net_lock);
654 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 693 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
655 " (too many links)"); 694 " (too many links)");
695 }
656 buf = tipc_cfg_reply_alloc(payload_size); 696 buf = tipc_cfg_reply_alloc(payload_size);
657 if (!buf) 697 if (!buf) {
698 read_unlock_bh(&tipc_net_lock);
658 return NULL; 699 return NULL;
700 }
659 701
660 /* Add TLV for broadcast link */ 702 /* Add TLV for broadcast link */
661 703
@@ -671,6 +713,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
671 713
672 if (!in_scope(domain, n_ptr->addr)) 714 if (!in_scope(domain, n_ptr->addr))
673 continue; 715 continue;
716 tipc_node_lock(n_ptr);
674 for (i = 0; i < MAX_BEARERS; i++) { 717 for (i = 0; i < MAX_BEARERS; i++) {
675 if (!n_ptr->links[i]) 718 if (!n_ptr->links[i])
676 continue; 719 continue;
@@ -680,7 +723,9 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
680 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, 723 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO,
681 &link_info, sizeof(link_info)); 724 &link_info, sizeof(link_info));
682 } 725 }
726 tipc_node_unlock(n_ptr);
683 } 727 }
684 728
729 read_unlock_bh(&tipc_net_lock);
685 return buf; 730 return buf;
686} 731}
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 2f5806410c64..e70d27ea6578 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-2007, Wind River Systems 5 * Copyright (c) 2004-2008, 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
@@ -211,12 +211,12 @@ exit:
211} 211}
212 212
213/** 213/**
214 * tipc_createport_raw - create a native TIPC port 214 * tipc_createport_raw - create a generic TIPC port
215 * 215 *
216 * Returns local port reference 216 * Returns pointer to (locked) TIPC port, or NULL if unable to create it
217 */ 217 */
218 218
219u32 tipc_createport_raw(void *usr_handle, 219struct tipc_port *tipc_createport_raw(void *usr_handle,
220 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 220 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
221 void (*wakeup)(struct tipc_port *), 221 void (*wakeup)(struct tipc_port *),
222 const u32 importance) 222 const u32 importance)
@@ -228,26 +228,21 @@ u32 tipc_createport_raw(void *usr_handle,
228 p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); 228 p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC);
229 if (!p_ptr) { 229 if (!p_ptr) {
230 warn("Port creation failed, no memory\n"); 230 warn("Port creation failed, no memory\n");
231 return 0; 231 return NULL;
232 } 232 }
233 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 233 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock);
234 if (!ref) { 234 if (!ref) {
235 warn("Port creation failed, reference table exhausted\n"); 235 warn("Port creation failed, reference table exhausted\n");
236 kfree(p_ptr); 236 kfree(p_ptr);
237 return 0; 237 return NULL;
238 } 238 }
239 239
240 tipc_port_lock(ref);
241 p_ptr->publ.usr_handle = usr_handle; 240 p_ptr->publ.usr_handle = usr_handle;
242 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 241 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
243 p_ptr->publ.ref = ref; 242 p_ptr->publ.ref = ref;
244 msg = &p_ptr->publ.phdr; 243 msg = &p_ptr->publ.phdr;
245 msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 244 msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
246 0);
247 msg_set_orignode(msg, tipc_own_addr);
248 msg_set_prevnode(msg, tipc_own_addr);
249 msg_set_origport(msg, ref); 245 msg_set_origport(msg, ref);
250 msg_set_importance(msg,importance);
251 p_ptr->last_in_seqno = 41; 246 p_ptr->last_in_seqno = 41;
252 p_ptr->sent = 1; 247 p_ptr->sent = 1;
253 INIT_LIST_HEAD(&p_ptr->wait_list); 248 INIT_LIST_HEAD(&p_ptr->wait_list);
@@ -262,8 +257,7 @@ u32 tipc_createport_raw(void *usr_handle,
262 INIT_LIST_HEAD(&p_ptr->port_list); 257 INIT_LIST_HEAD(&p_ptr->port_list);
263 list_add_tail(&p_ptr->port_list, &ports); 258 list_add_tail(&p_ptr->port_list, &ports);
264 spin_unlock_bh(&tipc_port_list_lock); 259 spin_unlock_bh(&tipc_port_list_lock);
265 tipc_port_unlock(p_ptr); 260 return &(p_ptr->publ);
266 return ref;
267} 261}
268 262
269int tipc_deleteport(u32 ref) 263int tipc_deleteport(u32 ref)
@@ -297,7 +291,7 @@ int tipc_deleteport(u32 ref)
297 kfree(p_ptr); 291 kfree(p_ptr);
298 dbg("Deleted port %u\n", ref); 292 dbg("Deleted port %u\n", ref);
299 tipc_net_route_msg(buf); 293 tipc_net_route_msg(buf);
300 return TIPC_OK; 294 return 0;
301} 295}
302 296
303/** 297/**
@@ -342,7 +336,7 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
342 return -EINVAL; 336 return -EINVAL;
343 *isunreliable = port_unreliable(p_ptr); 337 *isunreliable = port_unreliable(p_ptr);
344 tipc_port_unlock(p_ptr); 338 tipc_port_unlock(p_ptr);
345 return TIPC_OK; 339 return 0;
346} 340}
347 341
348int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 342int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
@@ -354,7 +348,7 @@ int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
354 return -EINVAL; 348 return -EINVAL;
355 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 349 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0));
356 tipc_port_unlock(p_ptr); 350 tipc_port_unlock(p_ptr);
357 return TIPC_OK; 351 return 0;
358} 352}
359 353
360static int port_unreturnable(struct port *p_ptr) 354static int port_unreturnable(struct port *p_ptr)
@@ -371,7 +365,7 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
371 return -EINVAL; 365 return -EINVAL;
372 *isunrejectable = port_unreturnable(p_ptr); 366 *isunrejectable = port_unreturnable(p_ptr);
373 tipc_port_unlock(p_ptr); 367 tipc_port_unlock(p_ptr);
374 return TIPC_OK; 368 return 0;
375} 369}
376 370
377int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 371int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
@@ -383,7 +377,7 @@ int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
383 return -EINVAL; 377 return -EINVAL;
384 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 378 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0));
385 tipc_port_unlock(p_ptr); 379 tipc_port_unlock(p_ptr);
386 return TIPC_OK; 380 return 0;
387} 381}
388 382
389/* 383/*
@@ -402,10 +396,10 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
402 buf = buf_acquire(LONG_H_SIZE); 396 buf = buf_acquire(LONG_H_SIZE);
403 if (buf) { 397 if (buf) {
404 msg = buf_msg(buf); 398 msg = buf_msg(buf);
405 msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); 399 msg_init(msg, usr, type, LONG_H_SIZE, destnode);
400 msg_set_errcode(msg, err);
406 msg_set_destport(msg, destport); 401 msg_set_destport(msg, destport);
407 msg_set_origport(msg, origport); 402 msg_set_origport(msg, origport);
408 msg_set_destnode(msg, destnode);
409 msg_set_orignode(msg, orignode); 403 msg_set_orignode(msg, orignode);
410 msg_set_transp_seqno(msg, seqno); 404 msg_set_transp_seqno(msg, seqno);
411 msg_set_msgcnt(msg, ack); 405 msg_set_msgcnt(msg, ack);
@@ -446,17 +440,19 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
446 return data_sz; 440 return data_sz;
447 } 441 }
448 rmsg = buf_msg(rbuf); 442 rmsg = buf_msg(rbuf);
449 msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); 443 msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg));
444 msg_set_errcode(rmsg, err);
450 msg_set_destport(rmsg, msg_origport(msg)); 445 msg_set_destport(rmsg, msg_origport(msg));
451 msg_set_prevnode(rmsg, tipc_own_addr);
452 msg_set_origport(rmsg, msg_destport(msg)); 446 msg_set_origport(rmsg, msg_destport(msg));
453 if (msg_short(msg)) 447 if (msg_short(msg)) {
454 msg_set_orignode(rmsg, tipc_own_addr); 448 msg_set_orignode(rmsg, tipc_own_addr);
455 else 449 /* leave name type & instance as zeroes */
450 } else {
456 msg_set_orignode(rmsg, msg_destnode(msg)); 451 msg_set_orignode(rmsg, msg_destnode(msg));
452 msg_set_nametype(rmsg, msg_nametype(msg));
453 msg_set_nameinst(rmsg, msg_nameinst(msg));
454 }
457 msg_set_size(rmsg, data_sz + hdr_sz); 455 msg_set_size(rmsg, data_sz + hdr_sz);
458 msg_set_nametype(rmsg, msg_nametype(msg));
459 msg_set_nameinst(rmsg, msg_nameinst(msg));
460 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); 456 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz);
461 457
462 /* send self-abort message when rejecting on a connected port */ 458 /* send self-abort message when rejecting on a connected port */
@@ -778,6 +774,7 @@ void tipc_port_reinit(void)
778 msg = &p_ptr->publ.phdr; 774 msg = &p_ptr->publ.phdr;
779 if (msg_orignode(msg) == tipc_own_addr) 775 if (msg_orignode(msg) == tipc_own_addr)
780 break; 776 break;
777 msg_set_prevnode(msg, tipc_own_addr);
781 msg_set_orignode(msg, tipc_own_addr); 778 msg_set_orignode(msg, tipc_own_addr);
782 } 779 }
783 spin_unlock_bh(&tipc_port_list_lock); 780 spin_unlock_bh(&tipc_port_list_lock);
@@ -838,16 +835,13 @@ static void port_dispatcher_sigh(void *dummy)
838 u32 peer_node = port_peernode(p_ptr); 835 u32 peer_node = port_peernode(p_ptr);
839 836
840 tipc_port_unlock(p_ptr); 837 tipc_port_unlock(p_ptr);
838 if (unlikely(!cb))
839 goto reject;
841 if (unlikely(!connected)) { 840 if (unlikely(!connected)) {
842 if (unlikely(published)) 841 if (tipc_connect2port(dref, &orig))
843 goto reject; 842 goto reject;
844 tipc_connect2port(dref,&orig); 843 } else if ((msg_origport(msg) != peer_port) ||
845 } 844 (msg_orignode(msg) != peer_node))
846 if (unlikely(msg_origport(msg) != peer_port))
847 goto reject;
848 if (unlikely(msg_orignode(msg) != peer_node))
849 goto reject;
850 if (unlikely(!cb))
851 goto reject; 845 goto reject;
852 if (unlikely(++p_ptr->publ.conn_unacked >= 846 if (unlikely(++p_ptr->publ.conn_unacked >=
853 TIPC_FLOW_CONTROL_WIN)) 847 TIPC_FLOW_CONTROL_WIN))
@@ -862,9 +856,7 @@ static void port_dispatcher_sigh(void *dummy)
862 tipc_msg_event cb = up_ptr->msg_cb; 856 tipc_msg_event cb = up_ptr->msg_cb;
863 857
864 tipc_port_unlock(p_ptr); 858 tipc_port_unlock(p_ptr);
865 if (unlikely(connected)) 859 if (unlikely(!cb || connected))
866 goto reject;
867 if (unlikely(!cb))
868 goto reject; 860 goto reject;
869 skb_pull(buf, msg_hdr_sz(msg)); 861 skb_pull(buf, msg_hdr_sz(msg));
870 cb(usr_handle, dref, &buf, msg_data(msg), 862 cb(usr_handle, dref, &buf, msg_data(msg),
@@ -877,11 +869,7 @@ static void port_dispatcher_sigh(void *dummy)
877 tipc_named_msg_event cb = up_ptr->named_msg_cb; 869 tipc_named_msg_event cb = up_ptr->named_msg_cb;
878 870
879 tipc_port_unlock(p_ptr); 871 tipc_port_unlock(p_ptr);
880 if (unlikely(connected)) 872 if (unlikely(!cb || connected || !published))
881 goto reject;
882 if (unlikely(!cb))
883 goto reject;
884 if (unlikely(!published))
885 goto reject; 873 goto reject;
886 dseq.type = msg_nametype(msg); 874 dseq.type = msg_nametype(msg);
887 dseq.lower = msg_nameinst(msg); 875 dseq.lower = msg_nameinst(msg);
@@ -908,11 +896,10 @@ err:
908 u32 peer_node = port_peernode(p_ptr); 896 u32 peer_node = port_peernode(p_ptr);
909 897
910 tipc_port_unlock(p_ptr); 898 tipc_port_unlock(p_ptr);
911 if (!connected || !cb) 899 if (!cb || !connected)
912 break;
913 if (msg_origport(msg) != peer_port)
914 break; 900 break;
915 if (msg_orignode(msg) != peer_node) 901 if ((msg_origport(msg) != peer_port) ||
902 (msg_orignode(msg) != peer_node))
916 break; 903 break;
917 tipc_disconnect(dref); 904 tipc_disconnect(dref);
918 skb_pull(buf, msg_hdr_sz(msg)); 905 skb_pull(buf, msg_hdr_sz(msg));
@@ -924,7 +911,7 @@ err:
924 tipc_msg_err_event cb = up_ptr->err_cb; 911 tipc_msg_err_event cb = up_ptr->err_cb;
925 912
926 tipc_port_unlock(p_ptr); 913 tipc_port_unlock(p_ptr);
927 if (connected || !cb) 914 if (!cb || connected)
928 break; 915 break;
929 skb_pull(buf, msg_hdr_sz(msg)); 916 skb_pull(buf, msg_hdr_sz(msg));
930 cb(usr_handle, dref, &buf, msg_data(msg), 917 cb(usr_handle, dref, &buf, msg_data(msg),
@@ -937,7 +924,7 @@ err:
937 up_ptr->named_err_cb; 924 up_ptr->named_err_cb;
938 925
939 tipc_port_unlock(p_ptr); 926 tipc_port_unlock(p_ptr);
940 if (connected || !cb) 927 if (!cb || connected)
941 break; 928 break;
942 dseq.type = msg_nametype(msg); 929 dseq.type = msg_nametype(msg);
943 dseq.lower = msg_nameinst(msg); 930 dseq.lower = msg_nameinst(msg);
@@ -976,7 +963,7 @@ static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
976 tipc_k_signal((Handler)port_dispatcher_sigh, 0); 963 tipc_k_signal((Handler)port_dispatcher_sigh, 0);
977 } 964 }
978 spin_unlock_bh(&queue_lock); 965 spin_unlock_bh(&queue_lock);
979 return TIPC_OK; 966 return 0;
980} 967}
981 968
982/* 969/*
@@ -1053,15 +1040,14 @@ int tipc_createport(u32 user_ref,
1053{ 1040{
1054 struct user_port *up_ptr; 1041 struct user_port *up_ptr;
1055 struct port *p_ptr; 1042 struct port *p_ptr;
1056 u32 ref;
1057 1043
1058 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 1044 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
1059 if (!up_ptr) { 1045 if (!up_ptr) {
1060 warn("Port creation failed, no memory\n"); 1046 warn("Port creation failed, no memory\n");
1061 return -ENOMEM; 1047 return -ENOMEM;
1062 } 1048 }
1063 ref = tipc_createport_raw(NULL, port_dispatcher, port_wakeup, importance); 1049 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher,
1064 p_ptr = tipc_port_lock(ref); 1050 port_wakeup, importance);
1065 if (!p_ptr) { 1051 if (!p_ptr) {
1066 kfree(up_ptr); 1052 kfree(up_ptr);
1067 return -ENOMEM; 1053 return -ENOMEM;
@@ -1081,16 +1067,15 @@ int tipc_createport(u32 user_ref,
1081 INIT_LIST_HEAD(&up_ptr->uport_list); 1067 INIT_LIST_HEAD(&up_ptr->uport_list);
1082 tipc_reg_add_port(up_ptr); 1068 tipc_reg_add_port(up_ptr);
1083 *portref = p_ptr->publ.ref; 1069 *portref = p_ptr->publ.ref;
1084 dbg(" tipc_createport: %x with ref %u\n", p_ptr, p_ptr->publ.ref);
1085 tipc_port_unlock(p_ptr); 1070 tipc_port_unlock(p_ptr);
1086 return TIPC_OK; 1071 return 0;
1087} 1072}
1088 1073
1089int tipc_ownidentity(u32 ref, struct tipc_portid *id) 1074int tipc_ownidentity(u32 ref, struct tipc_portid *id)
1090{ 1075{
1091 id->ref = ref; 1076 id->ref = ref;
1092 id->node = tipc_own_addr; 1077 id->node = tipc_own_addr;
1093 return TIPC_OK; 1078 return 0;
1094} 1079}
1095 1080
1096int tipc_portimportance(u32 ref, unsigned int *importance) 1081int tipc_portimportance(u32 ref, unsigned int *importance)
@@ -1102,7 +1087,7 @@ int tipc_portimportance(u32 ref, unsigned int *importance)
1102 return -EINVAL; 1087 return -EINVAL;
1103 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 1088 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr);
1104 tipc_port_unlock(p_ptr); 1089 tipc_port_unlock(p_ptr);
1105 return TIPC_OK; 1090 return 0;
1106} 1091}
1107 1092
1108int tipc_set_portimportance(u32 ref, unsigned int imp) 1093int tipc_set_portimportance(u32 ref, unsigned int imp)
@@ -1117,7 +1102,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
1117 return -EINVAL; 1102 return -EINVAL;
1118 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 1103 msg_set_importance(&p_ptr->publ.phdr, (u32)imp);
1119 tipc_port_unlock(p_ptr); 1104 tipc_port_unlock(p_ptr);
1120 return TIPC_OK; 1105 return 0;
1121} 1106}
1122 1107
1123 1108
@@ -1152,7 +1137,7 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1152 list_add(&publ->pport_list, &p_ptr->publications); 1137 list_add(&publ->pport_list, &p_ptr->publications);
1153 p_ptr->pub_count++; 1138 p_ptr->pub_count++;
1154 p_ptr->publ.published = 1; 1139 p_ptr->publ.published = 1;
1155 res = TIPC_OK; 1140 res = 0;
1156 } 1141 }
1157exit: 1142exit:
1158 tipc_port_unlock(p_ptr); 1143 tipc_port_unlock(p_ptr);
@@ -1175,7 +1160,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1175 tipc_nametbl_withdraw(publ->type, publ->lower, 1160 tipc_nametbl_withdraw(publ->type, publ->lower,
1176 publ->ref, publ->key); 1161 publ->ref, publ->key);
1177 } 1162 }
1178 res = TIPC_OK; 1163 res = 0;
1179 } else { 1164 } else {
1180 list_for_each_entry_safe(publ, tpubl, 1165 list_for_each_entry_safe(publ, tpubl,
1181 &p_ptr->publications, pport_list) { 1166 &p_ptr->publications, pport_list) {
@@ -1189,7 +1174,7 @@ int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1189 break; 1174 break;
1190 tipc_nametbl_withdraw(publ->type, publ->lower, 1175 tipc_nametbl_withdraw(publ->type, publ->lower,
1191 publ->ref, publ->key); 1176 publ->ref, publ->key);
1192 res = TIPC_OK; 1177 res = 0;
1193 break; 1178 break;
1194 } 1179 }
1195 } 1180 }
@@ -1233,7 +1218,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1233 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, 1218 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node,
1234 (void *)(unsigned long)ref, 1219 (void *)(unsigned long)ref,
1235 (net_ev_handler)port_handle_node_down); 1220 (net_ev_handler)port_handle_node_down);
1236 res = TIPC_OK; 1221 res = 0;
1237exit: 1222exit:
1238 tipc_port_unlock(p_ptr); 1223 tipc_port_unlock(p_ptr);
1239 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1224 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);
@@ -1255,7 +1240,7 @@ int tipc_disconnect_port(struct tipc_port *tp_ptr)
1255 /* let timer expire on it's own to avoid deadlock! */ 1240 /* let timer expire on it's own to avoid deadlock! */
1256 tipc_nodesub_unsubscribe( 1241 tipc_nodesub_unsubscribe(
1257 &((struct port *)tp_ptr)->subscription); 1242 &((struct port *)tp_ptr)->subscription);
1258 res = TIPC_OK; 1243 res = 0;
1259 } else { 1244 } else {
1260 res = -ENOTCONN; 1245 res = -ENOTCONN;
1261 } 1246 }
@@ -1320,7 +1305,7 @@ int tipc_isconnected(u32 ref, int *isconnected)
1320 return -EINVAL; 1305 return -EINVAL;
1321 *isconnected = p_ptr->publ.connected; 1306 *isconnected = p_ptr->publ.connected;
1322 tipc_port_unlock(p_ptr); 1307 tipc_port_unlock(p_ptr);
1323 return TIPC_OK; 1308 return 0;
1324} 1309}
1325 1310
1326int tipc_peer(u32 ref, struct tipc_portid *peer) 1311int tipc_peer(u32 ref, struct tipc_portid *peer)
@@ -1334,7 +1319,7 @@ int tipc_peer(u32 ref, struct tipc_portid *peer)
1334 if (p_ptr->publ.connected) { 1319 if (p_ptr->publ.connected) {
1335 peer->ref = port_peerport(p_ptr); 1320 peer->ref = port_peerport(p_ptr);
1336 peer->node = port_peernode(p_ptr); 1321 peer->node = port_peernode(p_ptr);
1337 res = TIPC_OK; 1322 res = 0;
1338 } else 1323 } else
1339 res = -ENOTCONN; 1324 res = -ENOTCONN;
1340 tipc_port_unlock(p_ptr); 1325 tipc_port_unlock(p_ptr);
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 89cbab24d08f..414fc34b8bea 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -123,7 +123,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start)
123 tipc_ref_table.index_mask = actual_size - 1; 123 tipc_ref_table.index_mask = actual_size - 1;
124 tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask; 124 tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
125 125
126 return TIPC_OK; 126 return 0;
127} 127}
128 128
129/** 129/**
@@ -142,9 +142,13 @@ void tipc_ref_table_stop(void)
142/** 142/**
143 * tipc_ref_acquire - create reference to an object 143 * tipc_ref_acquire - create reference to an object
144 * 144 *
145 * Return a unique reference value which can be translated back to the pointer 145 * Register an object pointer in reference table and lock the object.
146 * 'object' at a later time. Also, pass back a pointer to the lock protecting 146 * Returns a unique reference value that is used from then on to retrieve the
147 * the object, but without locking it. 147 * object pointer, or to determine that the object has been deregistered.
148 *
149 * Note: The object is returned in the locked state so that the caller can
150 * register a partially initialized object, without running the risk that
151 * the object will be accessed before initialization is complete.
148 */ 152 */
149 153
150u32 tipc_ref_acquire(void *object, spinlock_t **lock) 154u32 tipc_ref_acquire(void *object, spinlock_t **lock)
@@ -178,13 +182,13 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
178 ref = (next_plus_upper & ~index_mask) + index; 182 ref = (next_plus_upper & ~index_mask) + index;
179 entry->ref = ref; 183 entry->ref = ref;
180 entry->object = object; 184 entry->object = object;
181 spin_unlock_bh(&entry->lock);
182 *lock = &entry->lock; 185 *lock = &entry->lock;
183 } 186 }
184 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { 187 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
185 index = tipc_ref_table.init_point++; 188 index = tipc_ref_table.init_point++;
186 entry = &(tipc_ref_table.entries[index]); 189 entry = &(tipc_ref_table.entries[index]);
187 spin_lock_init(&entry->lock); 190 spin_lock_init(&entry->lock);
191 spin_lock_bh(&entry->lock);
188 ref = tipc_ref_table.start_mask + index; 192 ref = tipc_ref_table.start_mask + index;
189 entry->ref = ref; 193 entry->ref = ref;
190 entry->object = object; 194 entry->object = object;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 230f9ca2ad6b..1848693ebb82 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-2007, Wind River Systems 5 * Copyright (c) 2004-2008, 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
@@ -63,6 +63,7 @@
63struct tipc_sock { 63struct tipc_sock {
64 struct sock sk; 64 struct sock sk;
65 struct tipc_port *p; 65 struct tipc_port *p;
66 struct tipc_portid peer_name;
66}; 67};
67 68
68#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 69#define tipc_sk(sk) ((struct tipc_sock *)(sk))
@@ -188,7 +189,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
188 const struct proto_ops *ops; 189 const struct proto_ops *ops;
189 socket_state state; 190 socket_state state;
190 struct sock *sk; 191 struct sock *sk;
191 u32 portref; 192 struct tipc_port *tp_ptr;
192 193
193 /* Validate arguments */ 194 /* Validate arguments */
194 195
@@ -224,9 +225,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
224 225
225 /* Allocate TIPC port for socket to use */ 226 /* Allocate TIPC port for socket to use */
226 227
227 portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, 228 tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch,
228 TIPC_LOW_IMPORTANCE); 229 TIPC_LOW_IMPORTANCE);
229 if (unlikely(portref == 0)) { 230 if (unlikely(!tp_ptr)) {
230 sk_free(sk); 231 sk_free(sk);
231 return -ENOMEM; 232 return -ENOMEM;
232 } 233 }
@@ -239,12 +240,14 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
239 sock_init_data(sock, sk); 240 sock_init_data(sock, sk);
240 sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); 241 sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
241 sk->sk_backlog_rcv = backlog_rcv; 242 sk->sk_backlog_rcv = backlog_rcv;
242 tipc_sk(sk)->p = tipc_get_port(portref); 243 tipc_sk(sk)->p = tp_ptr;
244
245 spin_unlock_bh(tp_ptr->lock);
243 246
244 if (sock->state == SS_READY) { 247 if (sock->state == SS_READY) {
245 tipc_set_portunreturnable(portref, 1); 248 tipc_set_portunreturnable(tp_ptr->ref, 1);
246 if (sock->type == SOCK_DGRAM) 249 if (sock->type == SOCK_DGRAM)
247 tipc_set_portunreliable(portref, 1); 250 tipc_set_portunreliable(tp_ptr->ref, 1);
248 } 251 }
249 252
250 atomic_inc(&tipc_user_count); 253 atomic_inc(&tipc_user_count);
@@ -375,27 +378,29 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
375 * @sock: socket structure 378 * @sock: socket structure
376 * @uaddr: area for returned socket address 379 * @uaddr: area for returned socket address
377 * @uaddr_len: area for returned length of socket address 380 * @uaddr_len: area for returned length of socket address
378 * @peer: 0 to obtain socket name, 1 to obtain peer socket name 381 * @peer: 0 = own ID, 1 = current peer ID, 2 = current/former peer ID
379 * 382 *
380 * Returns 0 on success, errno otherwise 383 * Returns 0 on success, errno otherwise
381 * 384 *
382 * NOTE: This routine doesn't need to take the socket lock since it doesn't 385 * NOTE: This routine doesn't need to take the socket lock since it only
383 * access any non-constant socket information. 386 * accesses socket information that is unchanging (or which changes in
387 * a completely predictable manner).
384 */ 388 */
385 389
386static int get_name(struct socket *sock, struct sockaddr *uaddr, 390static int get_name(struct socket *sock, struct sockaddr *uaddr,
387 int *uaddr_len, int peer) 391 int *uaddr_len, int peer)
388{ 392{
389 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 393 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
390 u32 portref = tipc_sk_port(sock->sk)->ref; 394 struct tipc_sock *tsock = tipc_sk(sock->sk);
391 u32 res;
392 395
393 if (peer) { 396 if (peer) {
394 res = tipc_peer(portref, &addr->addr.id); 397 if ((sock->state != SS_CONNECTED) &&
395 if (res) 398 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
396 return res; 399 return -ENOTCONN;
400 addr->addr.id.ref = tsock->peer_name.ref;
401 addr->addr.id.node = tsock->peer_name.node;
397 } else { 402 } else {
398 tipc_ownidentity(portref, &addr->addr.id); 403 tipc_ownidentity(tsock->p->ref, &addr->addr.id);
399 } 404 }
400 405
401 *uaddr_len = sizeof(*addr); 406 *uaddr_len = sizeof(*addr);
@@ -764,18 +769,17 @@ exit:
764 769
765static int auto_connect(struct socket *sock, struct tipc_msg *msg) 770static int auto_connect(struct socket *sock, struct tipc_msg *msg)
766{ 771{
767 struct tipc_port *tport = tipc_sk_port(sock->sk); 772 struct tipc_sock *tsock = tipc_sk(sock->sk);
768 struct tipc_portid peer;
769 773
770 if (msg_errcode(msg)) { 774 if (msg_errcode(msg)) {
771 sock->state = SS_DISCONNECTING; 775 sock->state = SS_DISCONNECTING;
772 return -ECONNREFUSED; 776 return -ECONNREFUSED;
773 } 777 }
774 778
775 peer.ref = msg_origport(msg); 779 tsock->peer_name.ref = msg_origport(msg);
776 peer.node = msg_orignode(msg); 780 tsock->peer_name.node = msg_orignode(msg);
777 tipc_connect2port(tport->ref, &peer); 781 tipc_connect2port(tsock->p->ref, &tsock->peer_name);
778 tipc_set_portimportance(tport->ref, msg_importance(msg)); 782 tipc_set_portimportance(tsock->p->ref, msg_importance(msg));
779 sock->state = SS_CONNECTED; 783 sock->state = SS_CONNECTED;
780 return 0; 784 return 0;
781} 785}
@@ -1131,7 +1135,7 @@ restart:
1131 /* Loop around if more data is required */ 1135 /* Loop around if more data is required */
1132 1136
1133 if ((sz_copied < buf_len) /* didn't get all requested data */ 1137 if ((sz_copied < buf_len) /* didn't get all requested data */
1134 && (!skb_queue_empty(&sock->sk->sk_receive_queue) || 1138 && (!skb_queue_empty(&sk->sk_receive_queue) ||
1135 (flags & MSG_WAITALL)) 1139 (flags & MSG_WAITALL))
1136 /* ... and more is ready or required */ 1140 /* ... and more is ready or required */
1137 && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ 1141 && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */
@@ -1527,9 +1531,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1527 res = tipc_create(sock_net(sock->sk), new_sock, 0); 1531 res = tipc_create(sock_net(sock->sk), new_sock, 0);
1528 if (!res) { 1532 if (!res) {
1529 struct sock *new_sk = new_sock->sk; 1533 struct sock *new_sk = new_sock->sk;
1530 struct tipc_port *new_tport = tipc_sk_port(new_sk); 1534 struct tipc_sock *new_tsock = tipc_sk(new_sk);
1535 struct tipc_port *new_tport = new_tsock->p;
1531 u32 new_ref = new_tport->ref; 1536 u32 new_ref = new_tport->ref;
1532 struct tipc_portid id;
1533 struct tipc_msg *msg = buf_msg(buf); 1537 struct tipc_msg *msg = buf_msg(buf);
1534 1538
1535 lock_sock(new_sk); 1539 lock_sock(new_sk);
@@ -1543,9 +1547,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1543 1547
1544 /* Connect new socket to it's peer */ 1548 /* Connect new socket to it's peer */
1545 1549
1546 id.ref = msg_origport(msg); 1550 new_tsock->peer_name.ref = msg_origport(msg);
1547 id.node = msg_orignode(msg); 1551 new_tsock->peer_name.node = msg_orignode(msg);
1548 tipc_connect2port(new_ref, &id); 1552 tipc_connect2port(new_ref, &new_tsock->peer_name);
1549 new_sock->state = SS_CONNECTED; 1553 new_sock->state = SS_CONNECTED;
1550 1554
1551 tipc_set_portimportance(new_ref, msg_importance(msg)); 1555 tipc_set_portimportance(new_ref, msg_importance(msg));
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 8c01ccd3626c..0326d3060bc7 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/subscr.c: TIPC subscription 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, Wind River Systems 5 * Copyright (c) 2005-2007, 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
@@ -36,27 +36,24 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "dbg.h" 38#include "dbg.h"
39#include "subscr.h"
40#include "name_table.h" 39#include "name_table.h"
40#include "port.h"
41#include "ref.h" 41#include "ref.h"
42#include "subscr.h"
42 43
43/** 44/**
44 * struct subscriber - TIPC network topology subscriber 45 * struct subscriber - TIPC network topology subscriber
45 * @ref: object reference to subscriber object itself 46 * @port_ref: object reference to server port connecting to subscriber
46 * @lock: pointer to spinlock controlling access to subscriber object 47 * @lock: pointer to spinlock controlling access to subscriber's server port
47 * @subscriber_list: adjacent subscribers in top. server's list of subscribers 48 * @subscriber_list: adjacent subscribers in top. server's list of subscribers
48 * @subscription_list: list of subscription objects for this subscriber 49 * @subscription_list: list of subscription objects for this subscriber
49 * @port_ref: object reference to port used to communicate with subscriber
50 * @swap: indicates if subscriber uses opposite endianness in its messages
51 */ 50 */
52 51
53struct subscriber { 52struct subscriber {
54 u32 ref; 53 u32 port_ref;
55 spinlock_t *lock; 54 spinlock_t *lock;
56 struct list_head subscriber_list; 55 struct list_head subscriber_list;
57 struct list_head subscription_list; 56 struct list_head subscription_list;
58 u32 port_ref;
59 int swap;
60}; 57};
61 58
62/** 59/**
@@ -88,13 +85,14 @@ static struct top_srv topsrv = { 0 };
88 85
89static u32 htohl(u32 in, int swap) 86static u32 htohl(u32 in, int swap)
90{ 87{
91 char *c = (char *)&in; 88 return swap ? (u32)___constant_swab32(in) : in;
92
93 return swap ? ((c[3] << 3) + (c[2] << 2) + (c[1] << 1) + c[0]) : in;
94} 89}
95 90
96/** 91/**
97 * subscr_send_event - send a message containing a tipc_event to the subscriber 92 * subscr_send_event - send a message containing a tipc_event to the subscriber
93 *
94 * Note: Must not hold subscriber's server port lock, since tipc_send() will
95 * try to take the lock if the message is rejected and returned!
98 */ 96 */
99 97
100static void subscr_send_event(struct subscription *sub, 98static void subscr_send_event(struct subscription *sub,
@@ -109,12 +107,12 @@ static void subscr_send_event(struct subscription *sub,
109 msg_sect.iov_base = (void *)&sub->evt; 107 msg_sect.iov_base = (void *)&sub->evt;
110 msg_sect.iov_len = sizeof(struct tipc_event); 108 msg_sect.iov_len = sizeof(struct tipc_event);
111 109
112 sub->evt.event = htohl(event, sub->owner->swap); 110 sub->evt.event = htohl(event, sub->swap);
113 sub->evt.found_lower = htohl(found_lower, sub->owner->swap); 111 sub->evt.found_lower = htohl(found_lower, sub->swap);
114 sub->evt.found_upper = htohl(found_upper, sub->owner->swap); 112 sub->evt.found_upper = htohl(found_upper, sub->swap);
115 sub->evt.port.ref = htohl(port_ref, sub->owner->swap); 113 sub->evt.port.ref = htohl(port_ref, sub->swap);
116 sub->evt.port.node = htohl(node, sub->owner->swap); 114 sub->evt.port.node = htohl(node, sub->swap);
117 tipc_send(sub->owner->port_ref, 1, &msg_sect); 115 tipc_send(sub->server_ref, 1, &msg_sect);
118} 116}
119 117
120/** 118/**
@@ -151,13 +149,12 @@ void tipc_subscr_report_overlap(struct subscription *sub,
151 u32 node, 149 u32 node,
152 int must) 150 int must)
153{ 151{
154 dbg("Rep overlap %u:%u,%u<->%u,%u\n", sub->seq.type, sub->seq.lower,
155 sub->seq.upper, found_lower, found_upper);
156 if (!tipc_subscr_overlap(sub, found_lower, found_upper)) 152 if (!tipc_subscr_overlap(sub, found_lower, found_upper))
157 return; 153 return;
158 if (!must && !(sub->filter & TIPC_SUB_PORTS)) 154 if (!must && !(sub->filter & TIPC_SUB_PORTS))
159 return; 155 return;
160 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); 156
157 sub->event_cb(sub, found_lower, found_upper, event, port_ref, node);
161} 158}
162 159
163/** 160/**
@@ -166,20 +163,18 @@ void tipc_subscr_report_overlap(struct subscription *sub,
166 163
167static void subscr_timeout(struct subscription *sub) 164static void subscr_timeout(struct subscription *sub)
168{ 165{
169 struct subscriber *subscriber; 166 struct port *server_port;
170 u32 subscriber_ref;
171 167
172 /* Validate subscriber reference (in case subscriber is terminating) */ 168 /* Validate server port reference (in case subscriber is terminating) */
173 169
174 subscriber_ref = sub->owner->ref; 170 server_port = tipc_port_lock(sub->server_ref);
175 subscriber = (struct subscriber *)tipc_ref_lock(subscriber_ref); 171 if (server_port == NULL)
176 if (subscriber == NULL)
177 return; 172 return;
178 173
179 /* Validate timeout (in case subscription is being cancelled) */ 174 /* Validate timeout (in case subscription is being cancelled) */
180 175
181 if (sub->timeout == TIPC_WAIT_FOREVER) { 176 if (sub->timeout == TIPC_WAIT_FOREVER) {
182 tipc_ref_unlock(subscriber_ref); 177 tipc_port_unlock(server_port);
183 return; 178 return;
184 } 179 }
185 180
@@ -187,19 +182,21 @@ static void subscr_timeout(struct subscription *sub)
187 182
188 tipc_nametbl_unsubscribe(sub); 183 tipc_nametbl_unsubscribe(sub);
189 184
190 /* Notify subscriber of timeout, then unlink subscription */ 185 /* Unlink subscription from subscriber */
191 186
192 subscr_send_event(sub,
193 sub->evt.s.seq.lower,
194 sub->evt.s.seq.upper,
195 TIPC_SUBSCR_TIMEOUT,
196 0,
197 0);
198 list_del(&sub->subscription_list); 187 list_del(&sub->subscription_list);
199 188
189 /* Release subscriber's server port */
190
191 tipc_port_unlock(server_port);
192
193 /* Notify subscriber of timeout */
194
195 subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
196 TIPC_SUBSCR_TIMEOUT, 0, 0);
197
200 /* Now destroy subscription */ 198 /* Now destroy subscription */
201 199
202 tipc_ref_unlock(subscriber_ref);
203 k_term_timer(&sub->timer); 200 k_term_timer(&sub->timer);
204 kfree(sub); 201 kfree(sub);
205 atomic_dec(&topsrv.subscription_count); 202 atomic_dec(&topsrv.subscription_count);
@@ -208,7 +205,7 @@ static void subscr_timeout(struct subscription *sub)
208/** 205/**
209 * subscr_del - delete a subscription within a subscription list 206 * subscr_del - delete a subscription within a subscription list
210 * 207 *
211 * Called with subscriber locked. 208 * Called with subscriber port locked.
212 */ 209 */
213 210
214static void subscr_del(struct subscription *sub) 211static void subscr_del(struct subscription *sub)
@@ -222,7 +219,7 @@ static void subscr_del(struct subscription *sub)
222/** 219/**
223 * subscr_terminate - terminate communication with a subscriber 220 * subscr_terminate - terminate communication with a subscriber
224 * 221 *
225 * Called with subscriber locked. Routine must temporarily release this lock 222 * Called with subscriber port locked. Routine must temporarily release lock
226 * to enable subscription timeout routine(s) to finish without deadlocking; 223 * to enable subscription timeout routine(s) to finish without deadlocking;
227 * the lock is then reclaimed to allow caller to release it upon return. 224 * the lock is then reclaimed to allow caller to release it upon return.
228 * (This should work even in the unlikely event some other thread creates 225 * (This should work even in the unlikely event some other thread creates
@@ -232,14 +229,21 @@ static void subscr_del(struct subscription *sub)
232 229
233static void subscr_terminate(struct subscriber *subscriber) 230static void subscr_terminate(struct subscriber *subscriber)
234{ 231{
232 u32 port_ref;
235 struct subscription *sub; 233 struct subscription *sub;
236 struct subscription *sub_temp; 234 struct subscription *sub_temp;
237 235
238 /* Invalidate subscriber reference */ 236 /* Invalidate subscriber reference */
239 237
240 tipc_ref_discard(subscriber->ref); 238 port_ref = subscriber->port_ref;
239 subscriber->port_ref = 0;
241 spin_unlock_bh(subscriber->lock); 240 spin_unlock_bh(subscriber->lock);
242 241
242 /* Sever connection to subscriber */
243
244 tipc_shutdown(port_ref);
245 tipc_deleteport(port_ref);
246
243 /* Destroy any existing subscriptions for subscriber */ 247 /* Destroy any existing subscriptions for subscriber */
244 248
245 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, 249 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
@@ -253,27 +257,25 @@ static void subscr_terminate(struct subscriber *subscriber)
253 subscr_del(sub); 257 subscr_del(sub);
254 } 258 }
255 259
256 /* Sever connection to subscriber */
257
258 tipc_shutdown(subscriber->port_ref);
259 tipc_deleteport(subscriber->port_ref);
260
261 /* Remove subscriber from topology server's subscriber list */ 260 /* Remove subscriber from topology server's subscriber list */
262 261
263 spin_lock_bh(&topsrv.lock); 262 spin_lock_bh(&topsrv.lock);
264 list_del(&subscriber->subscriber_list); 263 list_del(&subscriber->subscriber_list);
265 spin_unlock_bh(&topsrv.lock); 264 spin_unlock_bh(&topsrv.lock);
266 265
267 /* Now destroy subscriber */ 266 /* Reclaim subscriber lock */
268 267
269 spin_lock_bh(subscriber->lock); 268 spin_lock_bh(subscriber->lock);
269
270 /* Now destroy subscriber */
271
270 kfree(subscriber); 272 kfree(subscriber);
271} 273}
272 274
273/** 275/**
274 * subscr_cancel - handle subscription cancellation request 276 * subscr_cancel - handle subscription cancellation request
275 * 277 *
276 * Called with subscriber locked. Routine must temporarily release this lock 278 * Called with subscriber port locked. Routine must temporarily release lock
277 * to enable the subscription timeout routine to finish without deadlocking; 279 * to enable the subscription timeout routine to finish without deadlocking;
278 * the lock is then reclaimed to allow caller to release it upon return. 280 * the lock is then reclaimed to allow caller to release it upon return.
279 * 281 *
@@ -316,27 +318,25 @@ static void subscr_cancel(struct tipc_subscr *s,
316/** 318/**
317 * subscr_subscribe - create subscription for subscriber 319 * subscr_subscribe - create subscription for subscriber
318 * 320 *
319 * Called with subscriber locked 321 * Called with subscriber port locked.
320 */ 322 */
321 323
322static void subscr_subscribe(struct tipc_subscr *s, 324static struct subscription *subscr_subscribe(struct tipc_subscr *s,
323 struct subscriber *subscriber) 325 struct subscriber *subscriber)
324{ 326{
325 struct subscription *sub; 327 struct subscription *sub;
328 int swap;
326 329
327 /* Determine/update subscriber's endianness */ 330 /* Determine subscriber's endianness */
328 331
329 if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)) 332 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
330 subscriber->swap = 0;
331 else
332 subscriber->swap = 1;
333 333
334 /* Detect & process a subscription cancellation request */ 334 /* Detect & process a subscription cancellation request */
335 335
336 if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) { 336 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
337 s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap); 337 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
338 subscr_cancel(s, subscriber); 338 subscr_cancel(s, subscriber);
339 return; 339 return NULL;
340 } 340 }
341 341
342 /* Refuse subscription if global limit exceeded */ 342 /* Refuse subscription if global limit exceeded */
@@ -345,63 +345,66 @@ static void subscr_subscribe(struct tipc_subscr *s,
345 warn("Subscription rejected, subscription limit reached (%u)\n", 345 warn("Subscription rejected, subscription limit reached (%u)\n",
346 tipc_max_subscriptions); 346 tipc_max_subscriptions);
347 subscr_terminate(subscriber); 347 subscr_terminate(subscriber);
348 return; 348 return NULL;
349 } 349 }
350 350
351 /* Allocate subscription object */ 351 /* Allocate subscription object */
352 352
353 sub = kzalloc(sizeof(*sub), GFP_ATOMIC); 353 sub = kmalloc(sizeof(*sub), GFP_ATOMIC);
354 if (!sub) { 354 if (!sub) {
355 warn("Subscription rejected, no memory\n"); 355 warn("Subscription rejected, no memory\n");
356 subscr_terminate(subscriber); 356 subscr_terminate(subscriber);
357 return; 357 return NULL;
358 } 358 }
359 359
360 /* Initialize subscription object */ 360 /* Initialize subscription object */
361 361
362 sub->seq.type = htohl(s->seq.type, subscriber->swap); 362 sub->seq.type = htohl(s->seq.type, swap);
363 sub->seq.lower = htohl(s->seq.lower, subscriber->swap); 363 sub->seq.lower = htohl(s->seq.lower, swap);
364 sub->seq.upper = htohl(s->seq.upper, subscriber->swap); 364 sub->seq.upper = htohl(s->seq.upper, swap);
365 sub->timeout = htohl(s->timeout, subscriber->swap); 365 sub->timeout = htohl(s->timeout, swap);
366 sub->filter = htohl(s->filter, subscriber->swap); 366 sub->filter = htohl(s->filter, swap);
367 if ((!(sub->filter & TIPC_SUB_PORTS) 367 if ((!(sub->filter & TIPC_SUB_PORTS)
368 == !(sub->filter & TIPC_SUB_SERVICE)) 368 == !(sub->filter & TIPC_SUB_SERVICE))
369 || (sub->seq.lower > sub->seq.upper)) { 369 || (sub->seq.lower > sub->seq.upper)) {
370 warn("Subscription rejected, illegal request\n"); 370 warn("Subscription rejected, illegal request\n");
371 kfree(sub); 371 kfree(sub);
372 subscr_terminate(subscriber); 372 subscr_terminate(subscriber);
373 return; 373 return NULL;
374 } 374 }
375 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); 375 sub->event_cb = subscr_send_event;
376 INIT_LIST_HEAD(&sub->subscription_list);
377 INIT_LIST_HEAD(&sub->nameseq_list); 376 INIT_LIST_HEAD(&sub->nameseq_list);
378 list_add(&sub->subscription_list, &subscriber->subscription_list); 377 list_add(&sub->subscription_list, &subscriber->subscription_list);
378 sub->server_ref = subscriber->port_ref;
379 sub->swap = swap;
380 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
379 atomic_inc(&topsrv.subscription_count); 381 atomic_inc(&topsrv.subscription_count);
380 if (sub->timeout != TIPC_WAIT_FOREVER) { 382 if (sub->timeout != TIPC_WAIT_FOREVER) {
381 k_init_timer(&sub->timer, 383 k_init_timer(&sub->timer,
382 (Handler)subscr_timeout, (unsigned long)sub); 384 (Handler)subscr_timeout, (unsigned long)sub);
383 k_start_timer(&sub->timer, sub->timeout); 385 k_start_timer(&sub->timer, sub->timeout);
384 } 386 }
385 sub->owner = subscriber; 387
386 tipc_nametbl_subscribe(sub); 388 return sub;
387} 389}
388 390
389/** 391/**
390 * subscr_conn_shutdown_event - handle termination request from subscriber 392 * subscr_conn_shutdown_event - handle termination request from subscriber
393 *
394 * Called with subscriber's server port unlocked.
391 */ 395 */
392 396
393static void subscr_conn_shutdown_event(void *usr_handle, 397static void subscr_conn_shutdown_event(void *usr_handle,
394 u32 portref, 398 u32 port_ref,
395 struct sk_buff **buf, 399 struct sk_buff **buf,
396 unsigned char const *data, 400 unsigned char const *data,
397 unsigned int size, 401 unsigned int size,
398 int reason) 402 int reason)
399{ 403{
400 struct subscriber *subscriber; 404 struct subscriber *subscriber = usr_handle;
401 spinlock_t *subscriber_lock; 405 spinlock_t *subscriber_lock;
402 406
403 subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); 407 if (tipc_port_lock(port_ref) == NULL)
404 if (subscriber == NULL)
405 return; 408 return;
406 409
407 subscriber_lock = subscriber->lock; 410 subscriber_lock = subscriber->lock;
@@ -411,6 +414,8 @@ static void subscr_conn_shutdown_event(void *usr_handle,
411 414
412/** 415/**
413 * subscr_conn_msg_event - handle new subscription request from subscriber 416 * subscr_conn_msg_event - handle new subscription request from subscriber
417 *
418 * Called with subscriber's server port unlocked.
414 */ 419 */
415 420
416static void subscr_conn_msg_event(void *usr_handle, 421static void subscr_conn_msg_event(void *usr_handle,
@@ -419,20 +424,46 @@ static void subscr_conn_msg_event(void *usr_handle,
419 const unchar *data, 424 const unchar *data,
420 u32 size) 425 u32 size)
421{ 426{
422 struct subscriber *subscriber; 427 struct subscriber *subscriber = usr_handle;
423 spinlock_t *subscriber_lock; 428 spinlock_t *subscriber_lock;
429 struct subscription *sub;
430
431 /*
432 * Lock subscriber's server port (& make a local copy of lock pointer,
433 * in case subscriber is deleted while processing subscription request)
434 */
424 435
425 subscriber = tipc_ref_lock((u32)(unsigned long)usr_handle); 436 if (tipc_port_lock(port_ref) == NULL)
426 if (subscriber == NULL)
427 return; 437 return;
428 438
429 subscriber_lock = subscriber->lock; 439 subscriber_lock = subscriber->lock;
430 if (size != sizeof(struct tipc_subscr))
431 subscr_terminate(subscriber);
432 else
433 subscr_subscribe((struct tipc_subscr *)data, subscriber);
434 440
435 spin_unlock_bh(subscriber_lock); 441 if (size != sizeof(struct tipc_subscr)) {
442 subscr_terminate(subscriber);
443 spin_unlock_bh(subscriber_lock);
444 } else {
445 sub = subscr_subscribe((struct tipc_subscr *)data, subscriber);
446 spin_unlock_bh(subscriber_lock);
447 if (sub != NULL) {
448
449 /*
450 * We must release the server port lock before adding a
451 * subscription to the name table since TIPC needs to be
452 * able to (re)acquire the port lock if an event message
453 * issued by the subscription process is rejected and
454 * returned. The subscription cannot be deleted while
455 * it is being added to the name table because:
456 * a) the single-threading of the native API port code
457 * ensures the subscription cannot be cancelled and
458 * the subscriber connection cannot be broken, and
459 * b) the name table lock ensures the subscription
460 * timeout code cannot delete the subscription,
461 * so the subscription object is still protected.
462 */
463
464 tipc_nametbl_subscribe(sub);
465 }
466 }
436} 467}
437 468
438/** 469/**
@@ -448,16 +479,10 @@ static void subscr_named_msg_event(void *usr_handle,
448 struct tipc_portid const *orig, 479 struct tipc_portid const *orig,
449 struct tipc_name_seq const *dest) 480 struct tipc_name_seq const *dest)
450{ 481{
451 struct subscriber *subscriber; 482 static struct iovec msg_sect = {NULL, 0};
452 struct iovec msg_sect = {NULL, 0};
453 spinlock_t *subscriber_lock;
454 483
455 dbg("subscr_named_msg_event: orig = %x own = %x,\n", 484 struct subscriber *subscriber;
456 orig->node, tipc_own_addr); 485 u32 server_port_ref;
457 if (size && (size != sizeof(struct tipc_subscr))) {
458 warn("Subscriber rejected, invalid subscription size\n");
459 return;
460 }
461 486
462 /* Create subscriber object */ 487 /* Create subscriber object */
463 488
@@ -468,17 +493,11 @@ static void subscr_named_msg_event(void *usr_handle,
468 } 493 }
469 INIT_LIST_HEAD(&subscriber->subscription_list); 494 INIT_LIST_HEAD(&subscriber->subscription_list);
470 INIT_LIST_HEAD(&subscriber->subscriber_list); 495 INIT_LIST_HEAD(&subscriber->subscriber_list);
471 subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock);
472 if (subscriber->ref == 0) {
473 warn("Subscriber rejected, reference table exhausted\n");
474 kfree(subscriber);
475 return;
476 }
477 496
478 /* Establish a connection to subscriber */ 497 /* Create server port & establish connection to subscriber */
479 498
480 tipc_createport(topsrv.user_ref, 499 tipc_createport(topsrv.user_ref,
481 (void *)(unsigned long)subscriber->ref, 500 subscriber,
482 importance, 501 importance,
483 NULL, 502 NULL,
484 NULL, 503 NULL,
@@ -490,32 +509,36 @@ static void subscr_named_msg_event(void *usr_handle,
490 &subscriber->port_ref); 509 &subscriber->port_ref);
491 if (subscriber->port_ref == 0) { 510 if (subscriber->port_ref == 0) {
492 warn("Subscriber rejected, unable to create port\n"); 511 warn("Subscriber rejected, unable to create port\n");
493 tipc_ref_discard(subscriber->ref);
494 kfree(subscriber); 512 kfree(subscriber);
495 return; 513 return;
496 } 514 }
497 tipc_connect2port(subscriber->port_ref, orig); 515 tipc_connect2port(subscriber->port_ref, orig);
498 516
517 /* Lock server port (& save lock address for future use) */
518
519 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock;
499 520
500 /* Add subscriber to topology server's subscriber list */ 521 /* Add subscriber to topology server's subscriber list */
501 522
502 tipc_ref_lock(subscriber->ref);
503 spin_lock_bh(&topsrv.lock); 523 spin_lock_bh(&topsrv.lock);
504 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); 524 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list);
505 spin_unlock_bh(&topsrv.lock); 525 spin_unlock_bh(&topsrv.lock);
506 526
507 /* 527 /* Unlock server port */
508 * Subscribe now if message contains a subscription,
509 * otherwise send an empty response to complete connection handshaking
510 */
511 528
512 subscriber_lock = subscriber->lock; 529 server_port_ref = subscriber->port_ref;
513 if (size) 530 spin_unlock_bh(subscriber->lock);
514 subscr_subscribe((struct tipc_subscr *)data, subscriber);
515 else
516 tipc_send(subscriber->port_ref, 1, &msg_sect);
517 531
518 spin_unlock_bh(subscriber_lock); 532 /* Send an ACK- to complete connection handshaking */
533
534 tipc_send(server_port_ref, 1, &msg_sect);
535
536 /* Handle optional subscription request */
537
538 if (size != 0) {
539 subscr_conn_msg_event(subscriber, server_port_ref,
540 buf, data, size);
541 }
519} 542}
520 543
521int tipc_subscr_start(void) 544int tipc_subscr_start(void)
@@ -574,8 +597,8 @@ void tipc_subscr_stop(void)
574 list_for_each_entry_safe(subscriber, subscriber_temp, 597 list_for_each_entry_safe(subscriber, subscriber_temp,
575 &topsrv.subscriber_list, 598 &topsrv.subscriber_list,
576 subscriber_list) { 599 subscriber_list) {
577 tipc_ref_lock(subscriber->ref);
578 subscriber_lock = subscriber->lock; 600 subscriber_lock = subscriber->lock;
601 spin_lock_bh(subscriber_lock);
579 subscr_terminate(subscriber); 602 subscr_terminate(subscriber);
580 spin_unlock_bh(subscriber_lock); 603 spin_unlock_bh(subscriber_lock);
581 } 604 }
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 93a8e674fac1..45d89bf4d202 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/subscr.h: Include file for TIPC subscription service 2 * net/tipc/subscr.h: Include file for TIPC network topology service
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-2007, 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,34 +37,44 @@
37#ifndef _TIPC_SUBSCR_H 37#ifndef _TIPC_SUBSCR_H
38#define _TIPC_SUBSCR_H 38#define _TIPC_SUBSCR_H
39 39
40struct subscription;
41
42typedef void (*tipc_subscr_event) (struct subscription *sub,
43 u32 found_lower, u32 found_upper,
44 u32 event, u32 port_ref, u32 node);
45
40/** 46/**
41 * struct subscription - TIPC network topology subscription object 47 * struct subscription - TIPC network topology subscription object
42 * @seq: name sequence associated with subscription 48 * @seq: name sequence associated with subscription
43 * @timeout: duration of subscription (in ms) 49 * @timeout: duration of subscription (in ms)
44 * @filter: event filtering to be done for subscription 50 * @filter: event filtering to be done for subscription
45 * @evt: template for events generated by subscription 51 * @event_cb: routine invoked when a subscription event is detected
46 * @subscription_list: adjacent subscriptions in subscriber's subscription list 52 * @timer: timer governing subscription duration (optional)
47 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 53 * @nameseq_list: adjacent subscriptions in name sequence's subscription list
48 * @timer_ref: reference to timer governing subscription duration (may be NULL) 54 * @subscription_list: adjacent subscriptions in subscriber's subscription list
49 * @owner: pointer to subscriber object associated with this subscription 55 * @server_ref: object reference of server port associated with subscription
56 * @swap: indicates if subscriber uses opposite endianness in its messages
57 * @evt: template for events generated by subscription
50 */ 58 */
51 59
52struct subscription { 60struct subscription {
53 struct tipc_name_seq seq; 61 struct tipc_name_seq seq;
54 u32 timeout; 62 u32 timeout;
55 u32 filter; 63 u32 filter;
56 struct tipc_event evt; 64 tipc_subscr_event event_cb;
57 struct list_head subscription_list;
58 struct list_head nameseq_list;
59 struct timer_list timer; 65 struct timer_list timer;
60 struct subscriber *owner; 66 struct list_head nameseq_list;
67 struct list_head subscription_list;
68 u32 server_ref;
69 int swap;
70 struct tipc_event evt;
61}; 71};
62 72
63int tipc_subscr_overlap(struct subscription * sub, 73int tipc_subscr_overlap(struct subscription *sub,
64 u32 found_lower, 74 u32 found_lower,
65 u32 found_upper); 75 u32 found_upper);
66 76
67void tipc_subscr_report_overlap(struct subscription * sub, 77void tipc_subscr_report_overlap(struct subscription *sub,
68 u32 found_lower, 78 u32 found_lower,
69 u32 found_upper, 79 u32 found_upper,
70 u32 event, 80 u32 event,
diff --git a/net/tipc/user_reg.c b/net/tipc/user_reg.c
index 4146c40cd20b..506928803162 100644
--- a/net/tipc/user_reg.c
+++ b/net/tipc/user_reg.c
@@ -91,7 +91,7 @@ static int reg_init(void)
91 } 91 }
92 } 92 }
93 spin_unlock_bh(&reg_lock); 93 spin_unlock_bh(&reg_lock);
94 return users ? TIPC_OK : -ENOMEM; 94 return users ? 0 : -ENOMEM;
95} 95}
96 96
97/** 97/**
@@ -129,7 +129,7 @@ int tipc_reg_start(void)
129 tipc_k_signal((Handler)reg_callback, 129 tipc_k_signal((Handler)reg_callback,
130 (unsigned long)&users[u]); 130 (unsigned long)&users[u]);
131 } 131 }
132 return TIPC_OK; 132 return 0;
133} 133}
134 134
135/** 135/**
@@ -184,7 +184,7 @@ int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle)
184 184
185 if (cb && (tipc_mode != TIPC_NOT_RUNNING)) 185 if (cb && (tipc_mode != TIPC_NOT_RUNNING))
186 tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr); 186 tipc_k_signal((Handler)reg_callback, (unsigned long)user_ptr);
187 return TIPC_OK; 187 return 0;
188} 188}
189 189
190/** 190/**
@@ -230,7 +230,7 @@ int tipc_reg_add_port(struct user_port *up_ptr)
230 struct tipc_user *user_ptr; 230 struct tipc_user *user_ptr;
231 231
232 if (up_ptr->user_ref == 0) 232 if (up_ptr->user_ref == 0)
233 return TIPC_OK; 233 return 0;
234 if (up_ptr->user_ref > MAX_USERID) 234 if (up_ptr->user_ref > MAX_USERID)
235 return -EINVAL; 235 return -EINVAL;
236 if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) 236 if ((tipc_mode == TIPC_NOT_RUNNING) || !users )
@@ -240,7 +240,7 @@ int tipc_reg_add_port(struct user_port *up_ptr)
240 user_ptr = &users[up_ptr->user_ref]; 240 user_ptr = &users[up_ptr->user_ref];
241 list_add(&up_ptr->uport_list, &user_ptr->ports); 241 list_add(&up_ptr->uport_list, &user_ptr->ports);
242 spin_unlock_bh(&reg_lock); 242 spin_unlock_bh(&reg_lock);
243 return TIPC_OK; 243 return 0;
244} 244}
245 245
246/** 246/**
@@ -250,7 +250,7 @@ int tipc_reg_add_port(struct user_port *up_ptr)
250int tipc_reg_remove_port(struct user_port *up_ptr) 250int tipc_reg_remove_port(struct user_port *up_ptr)
251{ 251{
252 if (up_ptr->user_ref == 0) 252 if (up_ptr->user_ref == 0)
253 return TIPC_OK; 253 return 0;
254 if (up_ptr->user_ref > MAX_USERID) 254 if (up_ptr->user_ref > MAX_USERID)
255 return -EINVAL; 255 return -EINVAL;
256 if (!users ) 256 if (!users )
@@ -259,6 +259,6 @@ int tipc_reg_remove_port(struct user_port *up_ptr)
259 spin_lock_bh(&reg_lock); 259 spin_lock_bh(&reg_lock);
260 list_del_init(&up_ptr->uport_list); 260 list_del_init(&up_ptr->uport_list);
261 spin_unlock_bh(&reg_lock); 261 spin_unlock_bh(&reg_lock);
262 return TIPC_OK; 262 return 0;
263} 263}
264 264