aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bearer.c8
-rw-r--r--net/tipc/config.c5
-rw-r--r--net/tipc/core.c4
-rw-r--r--net/tipc/core.h30
-rw-r--r--net/tipc/dbg.c136
-rw-r--r--net/tipc/dbg.h15
-rw-r--r--net/tipc/discover.c39
-rw-r--r--net/tipc/link.c8
-rw-r--r--net/tipc/name_distr.c2
-rw-r--r--net/tipc/node.c2
-rw-r--r--net/tipc/port.c7
-rw-r--r--net/tipc/socket.c13
-rw-r--r--net/tipc/subscr.c99
13 files changed, 269 insertions, 99 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 75a5968c2139..39744a33bd36 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -2,7 +2,7 @@
2 * net/tipc/bearer.c: TIPC bearer code 2 * net/tipc/bearer.c: TIPC bearer code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2006, 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
@@ -191,14 +191,14 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
191 if ((i < media_count) && (m_ptr->addr2str != NULL)) { 191 if ((i < media_count) && (m_ptr->addr2str != NULL)) {
192 char addr_str[MAX_ADDR_STR]; 192 char addr_str[MAX_ADDR_STR];
193 193
194 tipc_printf(pb, "%s(%s) ", m_ptr->name, 194 tipc_printf(pb, "%s(%s)", m_ptr->name,
195 m_ptr->addr2str(a, addr_str, sizeof(addr_str))); 195 m_ptr->addr2str(a, addr_str, sizeof(addr_str)));
196 } else { 196 } else {
197 unchar *addr = (unchar *)&a->dev_addr; 197 unchar *addr = (unchar *)&a->dev_addr;
198 198
199 tipc_printf(pb, "UNKNOWN(%u):", media_type); 199 tipc_printf(pb, "UNKNOWN(%u)", media_type);
200 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { 200 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) {
201 tipc_printf(pb, "%02x ", addr[i]); 201 tipc_printf(pb, "-%02x", addr[i]);
202 } 202 }
203 } 203 }
204} 204}
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 285e1bc2d880..ed1351ed05e1 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-2005, Wind River Systems 5 * Copyright (c) 2004-2006, 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
@@ -613,7 +613,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
613 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 613 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
614 break; 614 break;
615 default: 615 default:
616 rep_tlv_buf = NULL; 616 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
617 " (unknown command)");
617 break; 618 break;
618 } 619 }
619 620
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 0539a8362858..6f5b7ee31180 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -57,7 +57,7 @@ void tipc_socket_stop(void);
57int tipc_netlink_start(void); 57int tipc_netlink_start(void);
58void tipc_netlink_stop(void); 58void tipc_netlink_stop(void);
59 59
60#define TIPC_MOD_VER "1.6.1" 60#define TIPC_MOD_VER "1.6.2"
61 61
62#ifndef CONFIG_TIPC_ZONES 62#ifndef CONFIG_TIPC_ZONES
63#define CONFIG_TIPC_ZONES 3 63#define CONFIG_TIPC_ZONES 3
@@ -90,7 +90,7 @@ int tipc_random;
90atomic_t tipc_user_count = ATOMIC_INIT(0); 90atomic_t tipc_user_count = ATOMIC_INIT(0);
91 91
92const char tipc_alphabet[] = 92const char tipc_alphabet[] =
93 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; 93 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
94 94
95/* configurable TIPC parameters */ 95/* configurable TIPC parameters */
96 96
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 762aac2572be..4638947c2326 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -65,7 +65,7 @@
65#define assert(i) BUG_ON(!(i)) 65#define assert(i) BUG_ON(!(i))
66 66
67struct tipc_msg; 67struct tipc_msg;
68extern struct print_buf *TIPC_CONS, *TIPC_LOG; 68extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG;
69extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); 69extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
70void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); 70void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
71void tipc_printf(struct print_buf *, const char *fmt, ...); 71void tipc_printf(struct print_buf *, const char *fmt, ...);
@@ -83,9 +83,9 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
83#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) 83#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg)
84#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) 84#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg)
85 85
86#define dbg(fmt, arg...) do {if (DBG_OUTPUT) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) 86#define dbg(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0)
87#define msg_dbg(msg, txt) do {if (DBG_OUTPUT) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0) 87#define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0)
88#define dump(fmt, arg...) do {if (DBG_OUTPUT) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) 88#define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0)
89 89
90 90
91/* 91/*
@@ -94,11 +94,11 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
94 * here, or on a per .c file basis, by redefining these symbols. The following 94 * here, or on a per .c file basis, by redefining these symbols. The following
95 * print buffer options are available: 95 * print buffer options are available:
96 * 96 *
97 * NULL : Output to null print buffer (i.e. print nowhere) 97 * TIPC_NULL : null buffer (i.e. print nowhere)
98 * TIPC_CONS : Output to system console 98 * TIPC_CONS : system console
99 * TIPC_LOG : Output to TIPC log buffer 99 * TIPC_LOG : TIPC log buffer
100 * &buf : Output to user-defined buffer (struct print_buf *) 100 * &buf : user-defined buffer (struct print_buf *)
101 * TIPC_TEE(&buf_a,&buf_b) : Output to two print buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG) ) 101 * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG))
102 */ 102 */
103 103
104#ifndef TIPC_OUTPUT 104#ifndef TIPC_OUTPUT
@@ -106,7 +106,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
106#endif 106#endif
107 107
108#ifndef DBG_OUTPUT 108#ifndef DBG_OUTPUT
109#define DBG_OUTPUT NULL 109#define DBG_OUTPUT TIPC_NULL
110#endif 110#endif
111 111
112#else 112#else
@@ -136,7 +136,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
136#define TIPC_OUTPUT TIPC_CONS 136#define TIPC_OUTPUT TIPC_CONS
137 137
138#undef DBG_OUTPUT 138#undef DBG_OUTPUT
139#define DBG_OUTPUT NULL 139#define DBG_OUTPUT TIPC_NULL
140 140
141#endif 141#endif
142 142
@@ -275,11 +275,15 @@ static inline void k_term_timer(struct timer_list *timer)
275/* 275/*
276 * TIPC message buffer code 276 * TIPC message buffer code
277 * 277 *
278 * TIPC message buffer headroom leaves room for 14 byte Ethernet header, 278 * TIPC message buffer headroom reserves space for a link-level header
279 * (in case the message is sent off-node),
279 * while ensuring TIPC header is word aligned for quicker access 280 * while ensuring TIPC header is word aligned for quicker access
281 *
282 * The largest header currently supported is 18 bytes, which is used when
283 * the standard 14 byte Ethernet header has 4 added bytes for VLAN info
280 */ 284 */
281 285
282#define BUF_HEADROOM 16u 286#define BUF_HEADROOM 20u
283 287
284struct tipc_skb_cb { 288struct tipc_skb_cb {
285 void *handle; 289 void *handle;
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index 55130655e1ed..d8af4c28695d 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/dbg.c: TIPC print buffer routines for debuggign 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, Wind River Systems 5 * Copyright (c) 2005-2006, 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,11 +38,12 @@
38#include "config.h" 38#include "config.h"
39#include "dbg.h" 39#include "dbg.h"
40 40
41#define MAX_STRING 512 41static char print_string[TIPC_PB_MAX_STR];
42
43static char print_string[MAX_STRING];
44static DEFINE_SPINLOCK(print_lock); 42static DEFINE_SPINLOCK(print_lock);
45 43
44static struct print_buf null_buf = { NULL, 0, NULL, NULL };
45struct print_buf *TIPC_NULL = &null_buf;
46
46static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; 47static struct print_buf cons_buf = { NULL, 0, NULL, NULL };
47struct print_buf *TIPC_CONS = &cons_buf; 48struct print_buf *TIPC_CONS = &cons_buf;
48 49
@@ -62,68 +63,83 @@ struct print_buf *TIPC_LOG = &log_buf;
62/* 63/*
63 * Locking policy when using print buffers. 64 * Locking policy when using print buffers.
64 * 65 *
65 * 1) Routines of the form printbuf_XXX() rely on the caller to prevent 66 * The following routines use 'print_lock' for protection:
66 * simultaneous use of the print buffer(s) being manipulated. 67 * 1) tipc_printf() - to protect its print buffer(s) and 'print_string'
67 * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of 68 * 2) TIPC_TEE() - to protect its print buffer(s)
68 * 'print_string' and to protect its print buffer(s). 69 * 3) tipc_dump() - to protect its print buffer(s) and 'print_string'
69 * 3) TIPC_TEE() uses 'print_lock' to protect its print buffer(s). 70 * 4) tipc_log_XXX() - to protect TIPC_LOG
70 * 4) Routines of the form log_XXX() uses 'print_lock' 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.
71 */ 74 */
72 75
73/** 76/**
74 * tipc_printbuf_init - initialize print buffer to empty 77 * tipc_printbuf_init - initialize print buffer to empty
78 * @pb: pointer to print buffer structure
79 * @raw: pointer to character array used by print buffer
80 * @size: size of character array
81 *
82 * Makes the print buffer a null device that discards anything written to it
83 * if the character array is too small (or absent).
75 */ 84 */
76 85
77void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz) 86void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
78{ 87{
79 if (!pb || !raw || (sz < (MAX_STRING + 1))) 88 pb->buf = raw;
80 return; 89 pb->crs = raw;
81 90 pb->size = size;
82 pb->crs = pb->buf = raw;
83 pb->size = sz;
84 pb->next = NULL; 91 pb->next = NULL;
85 pb->buf[0] = 0; 92
86 pb->buf[sz-1] = ~0; 93 if (size < TIPC_PB_MIN_SIZE) {
94 pb->buf = NULL;
95 } else if (raw) {
96 pb->buf[0] = 0;
97 pb->buf[size-1] = ~0;
98 }
87} 99}
88 100
89/** 101/**
90 * tipc_printbuf_reset - reinitialize print buffer to empty state 102 * tipc_printbuf_reset - reinitialize print buffer to empty state
103 * @pb: pointer to print buffer structure
91 */ 104 */
92 105
93void tipc_printbuf_reset(struct print_buf *pb) 106void tipc_printbuf_reset(struct print_buf *pb)
94{ 107{
95 if (pb && pb->buf) 108 tipc_printbuf_init(pb, pb->buf, pb->size);
96 tipc_printbuf_init(pb, pb->buf, pb->size);
97} 109}
98 110
99/** 111/**
100 * tipc_printbuf_empty - test if print buffer is in empty state 112 * tipc_printbuf_empty - test if print buffer is in empty state
113 * @pb: pointer to print buffer structure
114 *
115 * Returns non-zero if print buffer is empty.
101 */ 116 */
102 117
103int tipc_printbuf_empty(struct print_buf *pb) 118int tipc_printbuf_empty(struct print_buf *pb)
104{ 119{
105 return (!pb || !pb->buf || (pb->crs == pb->buf)); 120 return (!pb->buf || (pb->crs == pb->buf));
106} 121}
107 122
108/** 123/**
109 * tipc_printbuf_validate - check for print buffer overflow 124 * tipc_printbuf_validate - check for print buffer overflow
125 * @pb: pointer to print buffer structure
110 * 126 *
111 * Verifies that a print buffer has captured all data written to it. 127 * Verifies that a print buffer has captured all data written to it.
112 * If data has been lost, linearize buffer and prepend an error message 128 * If data has been lost, linearize buffer and prepend an error message
113 * 129 *
114 * Returns length of print buffer data string (including trailing NULL) 130 * Returns length of print buffer data string (including trailing NUL)
115 */ 131 */
116 132
117int tipc_printbuf_validate(struct print_buf *pb) 133int tipc_printbuf_validate(struct print_buf *pb)
118{ 134{
119 char *err = " *** PRINT BUFFER WRAPPED AROUND ***\n"; 135 char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n";
120 char *cp_buf; 136 char *cp_buf;
121 struct print_buf cb; 137 struct print_buf cb;
122 138
123 if (!pb || !pb->buf) 139 if (!pb->buf)
124 return 0; 140 return 0;
125 141
126 if (pb->buf[pb->size - 1] == '\0') { 142 if (pb->buf[pb->size - 1] == 0) {
127 cp_buf = kmalloc(pb->size, GFP_ATOMIC); 143 cp_buf = kmalloc(pb->size, GFP_ATOMIC);
128 if (cp_buf != NULL){ 144 if (cp_buf != NULL){
129 tipc_printbuf_init(&cb, cp_buf, pb->size); 145 tipc_printbuf_init(&cb, cp_buf, pb->size);
@@ -141,6 +157,8 @@ int tipc_printbuf_validate(struct print_buf *pb)
141 157
142/** 158/**
143 * tipc_printbuf_move - move print buffer contents to another print buffer 159 * tipc_printbuf_move - move print buffer contents to another print buffer
160 * @pb_to: pointer to destination print buffer structure
161 * @pb_from: pointer to source print buffer structure
144 * 162 *
145 * Current contents of destination print buffer (if any) are discarded. 163 * Current contents of destination print buffer (if any) are discarded.
146 * Source print buffer becomes empty if a successful move occurs. 164 * Source print buffer becomes empty if a successful move occurs.
@@ -152,21 +170,22 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
152 170
153 /* Handle the cases where contents can't be moved */ 171 /* Handle the cases where contents can't be moved */
154 172
155 if (!pb_to || !pb_to->buf) 173 if (!pb_to->buf)
156 return; 174 return;
157 175
158 if (!pb_from || !pb_from->buf) { 176 if (!pb_from->buf) {
159 tipc_printbuf_reset(pb_to); 177 tipc_printbuf_reset(pb_to);
160 return; 178 return;
161 } 179 }
162 180
163 if (pb_to->size < pb_from->size) { 181 if (pb_to->size < pb_from->size) {
164 tipc_printbuf_reset(pb_to); 182 tipc_printbuf_reset(pb_to);
165 tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***"); 183 tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***");
166 return; 184 return;
167 } 185 }
168 186
169 /* Copy data from char after cursor to end (if used) */ 187 /* Copy data from char after cursor to end (if used) */
188
170 len = pb_from->buf + pb_from->size - pb_from->crs - 2; 189 len = pb_from->buf + pb_from->size - pb_from->crs - 2;
171 if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { 190 if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) {
172 strcpy(pb_to->buf, pb_from->crs + 1); 191 strcpy(pb_to->buf, pb_from->crs + 1);
@@ -175,6 +194,7 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
175 pb_to->crs = pb_to->buf; 194 pb_to->crs = pb_to->buf;
176 195
177 /* Copy data from start to cursor (always) */ 196 /* Copy data from start to cursor (always) */
197
178 len = pb_from->crs - pb_from->buf; 198 len = pb_from->crs - pb_from->buf;
179 strcpy(pb_to->crs, pb_from->buf); 199 strcpy(pb_to->crs, pb_from->buf);
180 pb_to->crs += len; 200 pb_to->crs += len;
@@ -184,6 +204,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
184 204
185/** 205/**
186 * tipc_printf - append formatted output to print buffer chain 206 * tipc_printf - append formatted output to print buffer chain
207 * @pb: pointer to chain of print buffers (may be NULL)
208 * @fmt: formatted info to be printed
187 */ 209 */
188 210
189void tipc_printf(struct print_buf *pb, const char *fmt, ...) 211void tipc_printf(struct print_buf *pb, const char *fmt, ...)
@@ -195,8 +217,8 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
195 217
196 spin_lock_bh(&print_lock); 218 spin_lock_bh(&print_lock);
197 FORMAT(print_string, chars_to_add, fmt); 219 FORMAT(print_string, chars_to_add, fmt);
198 if (chars_to_add >= MAX_STRING) 220 if (chars_to_add >= TIPC_PB_MAX_STR)
199 strcpy(print_string, "*** STRING TOO LONG ***"); 221 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***");
200 222
201 while (pb) { 223 while (pb) {
202 if (pb == TIPC_CONS) 224 if (pb == TIPC_CONS)
@@ -206,6 +228,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
206 if (chars_to_add <= chars_left) { 228 if (chars_to_add <= chars_left) {
207 strcpy(pb->crs, print_string); 229 strcpy(pb->crs, print_string);
208 pb->crs += chars_to_add; 230 pb->crs += chars_to_add;
231 } else if (chars_to_add >= (pb->size - 1)) {
232 strcpy(pb->buf, print_string + chars_to_add + 1
233 - pb->size);
234 pb->crs = pb->buf + pb->size - 1;
209 } else { 235 } else {
210 strcpy(pb->buf, print_string + chars_left); 236 strcpy(pb->buf, print_string + chars_left);
211 save_char = print_string[chars_left]; 237 save_char = print_string[chars_left];
@@ -224,6 +250,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
224 250
225/** 251/**
226 * TIPC_TEE - perform next output operation on both print buffers 252 * TIPC_TEE - perform next output operation on both print buffers
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.
227 */ 257 */
228 258
229struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) 259struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
@@ -232,8 +262,6 @@ struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
232 262
233 if (!b0 || (b0 == b1)) 263 if (!b0 || (b0 == b1))
234 return b1; 264 return b1;
235 if (!b1)
236 return b0;
237 265
238 spin_lock_bh(&print_lock); 266 spin_lock_bh(&print_lock);
239 while (pb->next) { 267 while (pb->next) {
@@ -256,7 +284,7 @@ static void print_to_console(char *crs, int len)
256 int rest = len; 284 int rest = len;
257 285
258 while (rest > 0) { 286 while (rest > 0) {
259 int sz = rest < MAX_STRING ? rest : MAX_STRING; 287 int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR;
260 char c = crs[sz]; 288 char c = crs[sz];
261 289
262 crs[sz] = 0; 290 crs[sz] = 0;
@@ -275,36 +303,48 @@ static void printbuf_dump(struct print_buf *pb)
275{ 303{
276 int len; 304 int len;
277 305
306 if (!pb->buf) {
307 printk("*** PRINT BUFFER NOT ALLOCATED ***");
308 return;
309 }
310
278 /* Dump print buffer from char after cursor to end (if used) */ 311 /* Dump print buffer from char after cursor to end (if used) */
312
279 len = pb->buf + pb->size - pb->crs - 2; 313 len = pb->buf + pb->size - pb->crs - 2;
280 if ((pb->buf[pb->size - 1] == 0) && (len > 0)) 314 if ((pb->buf[pb->size - 1] == 0) && (len > 0))
281 print_to_console(pb->crs + 1, len); 315 print_to_console(pb->crs + 1, len);
282 316
283 /* Dump print buffer from start to cursor (always) */ 317 /* Dump print buffer from start to cursor (always) */
318
284 len = pb->crs - pb->buf; 319 len = pb->crs - pb->buf;
285 print_to_console(pb->buf, len); 320 print_to_console(pb->buf, len);
286} 321}
287 322
288/** 323/**
289 * tipc_dump - dump non-console print buffer(s) to console 324 * tipc_dump - dump non-console print buffer(s) to console
325 * @pb: pointer to chain of print buffers
290 */ 326 */
291 327
292void tipc_dump(struct print_buf *pb, const char *fmt, ...) 328void tipc_dump(struct print_buf *pb, const char *fmt, ...)
293{ 329{
330 struct print_buf *pb_next;
294 int len; 331 int len;
295 332
296 spin_lock_bh(&print_lock); 333 spin_lock_bh(&print_lock);
297 FORMAT(TIPC_CONS->buf, len, fmt); 334 FORMAT(print_string, len, fmt);
298 printk(TIPC_CONS->buf); 335 printk(print_string);
299 336
300 for (; pb; pb = pb->next) { 337 for (; pb; pb = pb->next) {
301 if (pb == TIPC_CONS) 338 if (pb != TIPC_CONS) {
302 continue; 339 printk("\n---- Start of %s log dump ----\n\n",
303 printk("\n---- Start of dump,%s log ----\n\n", 340 (pb == TIPC_LOG) ? "global" : "local");
304 (pb == TIPC_LOG) ? "global" : "local"); 341 printbuf_dump(pb);
305 printbuf_dump(pb); 342 tipc_printbuf_reset(pb);
306 tipc_printbuf_reset(pb); 343 printk("\n---- End of dump ----\n");
307 printk("\n-------- End of dump --------\n"); 344 }
345 pb_next = pb->next;
346 pb->next = NULL;
347 pb = pb_next;
308 } 348 }
309 spin_unlock_bh(&print_lock); 349 spin_unlock_bh(&print_lock);
310} 350}
@@ -324,7 +364,8 @@ void tipc_log_stop(void)
324} 364}
325 365
326/** 366/**
327 * tipc_log_reinit - set TIPC log print buffer to specified size 367 * tipc_log_reinit - (re)initialize TIPC log print buffer
368 * @log_size: print buffer size to use
328 */ 369 */
329 370
330void tipc_log_reinit(int log_size) 371void tipc_log_reinit(int log_size)
@@ -332,10 +373,11 @@ void tipc_log_reinit(int log_size)
332 tipc_log_stop(); 373 tipc_log_stop();
333 374
334 if (log_size) { 375 if (log_size) {
335 if (log_size <= MAX_STRING) 376 if (log_size < TIPC_PB_MIN_SIZE)
336 log_size = MAX_STRING + 1; 377 log_size = TIPC_PB_MIN_SIZE;
337 spin_lock_bh(&print_lock); 378 spin_lock_bh(&print_lock);
338 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size); 379 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC),
380 log_size);
339 spin_unlock_bh(&print_lock); 381 spin_unlock_bh(&print_lock);
340 } 382 }
341} 383}
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h
index 227f050d2a52..467c0bc78a79 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, Wind River Systems 5 * Copyright (c) 2005-2006, 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,6 +37,14 @@
37#ifndef _TIPC_DBG_H 37#ifndef _TIPC_DBG_H
38#define _TIPC_DBG_H 38#define _TIPC_DBG_H
39 39
40/**
41 * struct print_buf - TIPC print buffer structure
42 * @buf: pointer to character array containing print buffer contents
43 * @size: size of character array
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
46 */
47
40struct print_buf { 48struct print_buf {
41 char *buf; 49 char *buf;
42 u32 size; 50 u32 size;
@@ -44,7 +52,10 @@ struct print_buf {
44 struct print_buf *next; 52 struct print_buf *next;
45}; 53};
46 54
47void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 sz); 55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */
56#define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */
57
58void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size);
48void tipc_printbuf_reset(struct print_buf *pb); 59void tipc_printbuf_reset(struct print_buf *pb);
49int tipc_printbuf_empty(struct print_buf *pb); 60int tipc_printbuf_empty(struct print_buf *pb);
50int tipc_printbuf_validate(struct print_buf *pb); 61int tipc_printbuf_validate(struct print_buf *pb);
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index ee94de92ae99..3b0cd12f37da 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -132,6 +132,28 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
132} 132}
133 133
134/** 134/**
135 * disc_dupl_alert - issue node address duplication alert
136 * @b_ptr: pointer to bearer detecting duplication
137 * @node_addr: duplicated node address
138 * @media_addr: media address advertised by duplicated node
139 */
140
141static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
142 struct tipc_media_addr *media_addr)
143{
144 char node_addr_str[16];
145 char media_addr_str[64];
146 struct print_buf pb;
147
148 addr_string_fill(node_addr_str, node_addr);
149 tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str));
150 tipc_media_addr_printf(&pb, media_addr);
151 tipc_printbuf_validate(&pb);
152 warn("Duplicate %s using %s seen on <%s>\n",
153 node_addr_str, media_addr_str, b_ptr->publ.name);
154}
155
156/**
135 * tipc_disc_recv_msg - handle incoming link setup message (request or response) 157 * tipc_disc_recv_msg - handle incoming link setup message (request or response)
136 * @buf: buffer containing message 158 * @buf: buffer containing message
137 */ 159 */
@@ -157,8 +179,11 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
157 return; 179 return;
158 if (!tipc_addr_node_valid(orig)) 180 if (!tipc_addr_node_valid(orig))
159 return; 181 return;
160 if (orig == tipc_own_addr) 182 if (orig == tipc_own_addr) {
183 if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr)))
184 disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
161 return; 185 return;
186 }
162 if (!in_scope(dest, tipc_own_addr)) 187 if (!in_scope(dest, tipc_own_addr))
163 return; 188 return;
164 if (is_slave(tipc_own_addr) && is_slave(orig)) 189 if (is_slave(tipc_own_addr) && is_slave(orig))
@@ -170,7 +195,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
170 struct sk_buff *rbuf; 195 struct sk_buff *rbuf;
171 struct tipc_media_addr *addr; 196 struct tipc_media_addr *addr;
172 struct node *n_ptr = tipc_node_find(orig); 197 struct node *n_ptr = tipc_node_find(orig);
173 int link_up; 198 int link_fully_up;
199
174 dbg(" in own cluster\n"); 200 dbg(" in own cluster\n");
175 if (n_ptr == NULL) { 201 if (n_ptr == NULL) {
176 n_ptr = tipc_node_create(orig); 202 n_ptr = tipc_node_create(orig);
@@ -190,14 +216,19 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
190 } 216 }
191 addr = &link->media_addr; 217 addr = &link->media_addr;
192 if (memcmp(addr, &media_addr, sizeof(*addr))) { 218 if (memcmp(addr, &media_addr, sizeof(*addr))) {
219 if (tipc_link_is_up(link) || (!link->started)) {
220 disc_dupl_alert(b_ptr, orig, &media_addr);
221 spin_unlock_bh(&n_ptr->lock);
222 return;
223 }
193 warn("Resetting link <%s>, peer interface address changed\n", 224 warn("Resetting link <%s>, peer interface address changed\n",
194 link->name); 225 link->name);
195 memcpy(addr, &media_addr, sizeof(*addr)); 226 memcpy(addr, &media_addr, sizeof(*addr));
196 tipc_link_reset(link); 227 tipc_link_reset(link);
197 } 228 }
198 link_up = tipc_link_is_up(link); 229 link_fully_up = (link->state == WORKING_WORKING);
199 spin_unlock_bh(&n_ptr->lock); 230 spin_unlock_bh(&n_ptr->lock);
200 if ((type == DSC_RESP_MSG) || link_up) 231 if ((type == DSC_RESP_MSG) || link_fully_up)
201 return; 232 return;
202 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); 233 rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
203 if (rbuf != NULL) { 234 if (rbuf != NULL) {
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 53bc8cb5adbc..1bb983c8130b 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -132,7 +132,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
132 * allow the output from multiple links to be intermixed. For this reason 132 * allow the output from multiple links to be intermixed. For this reason
133 * routines of the form "dbg_link_XXX()" have been created that will capture 133 * routines of the form "dbg_link_XXX()" have been created that will capture
134 * debug info into a link's personal print buffer, which can then be dumped 134 * debug info into a link's personal print buffer, which can then be dumped
135 * into the TIPC system log (LOG) upon request. 135 * into the TIPC system log (TIPC_LOG) upon request.
136 * 136 *
137 * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size 137 * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size
138 * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, 138 * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0,
@@ -141,7 +141,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
141 * when there is only a single link in the system being debugged. 141 * when there is only a single link in the system being debugged.
142 * 142 *
143 * Notes: 143 * Notes:
144 * - When enabled, LINK_LOG_BUF_SIZE should be set to at least 1000 (bytes) 144 * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE
145 * - "l_ptr" must be valid when using dbg_link_XXX() macros 145 * - "l_ptr" must be valid when using dbg_link_XXX() macros
146 */ 146 */
147 147
@@ -159,13 +159,13 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
159 159
160static void dbg_print_link(struct link *l_ptr, const char *str) 160static void dbg_print_link(struct link *l_ptr, const char *str)
161{ 161{
162 if (DBG_OUTPUT) 162 if (DBG_OUTPUT != TIPC_NULL)
163 link_print(l_ptr, DBG_OUTPUT, str); 163 link_print(l_ptr, DBG_OUTPUT, str);
164} 164}
165 165
166static void dbg_print_buf_chain(struct sk_buff *root_buf) 166static void dbg_print_buf_chain(struct sk_buff *root_buf)
167{ 167{
168 if (DBG_OUTPUT) { 168 if (DBG_OUTPUT != TIPC_NULL) {
169 struct sk_buff *buf = root_buf; 169 struct sk_buff *buf = root_buf;
170 170
171 while (buf) { 171 while (buf) {
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index f0b063bcc2a9..03bd659c43ca 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -122,7 +122,7 @@ void tipc_named_publish(struct publication *publ)
122 struct sk_buff *buf; 122 struct sk_buff *buf;
123 struct distr_item *item; 123 struct distr_item *item;
124 124
125 list_add(&publ->local_list, &publ_root); 125 list_add_tail(&publ->local_list, &publ_root);
126 publ_cnt++; 126 publ_cnt++;
127 127
128 buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); 128 buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index fc6d09630ccd..886bda5e88db 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -648,7 +648,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
648 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 648 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
649 " (network address)"); 649 " (network address)");
650 650
651 if (!tipc_nodes) 651 if (tipc_mode != TIPC_NET_MODE)
652 return tipc_cfg_reply_none(); 652 return tipc_cfg_reply_none();
653 653
654 /* Get space for all unicast links + multicast link */ 654 /* Get space for all unicast links + multicast link */
diff --git a/net/tipc/port.c b/net/tipc/port.c
index b9c8c6b9e94f..c1a1a76759b5 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -505,8 +505,13 @@ static void port_timeout(unsigned long ref)
505 struct port *p_ptr = tipc_port_lock(ref); 505 struct port *p_ptr = tipc_port_lock(ref);
506 struct sk_buff *buf = NULL; 506 struct sk_buff *buf = NULL;
507 507
508 if (!p_ptr || !p_ptr->publ.connected) 508 if (!p_ptr)
509 return;
510
511 if (!p_ptr->publ.connected) {
512 tipc_port_unlock(p_ptr);
509 return; 513 return;
514 }
510 515
511 /* Last probe answered ? */ 516 /* Last probe answered ? */
512 if (p_ptr->probing_state == PROBING) { 517 if (p_ptr->probing_state == PROBING) {
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index acfb852e7c98..2a6a5a6b4c12 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-2006, Ericsson AB 4 * Copyright (c) 2001-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2006, 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
@@ -629,6 +629,9 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
629 return -ENOTCONN; 629 return -ENOTCONN;
630 } 630 }
631 631
632 if (unlikely(m->msg_name))
633 return -EISCONN;
634
632 /* 635 /*
633 * Send each iovec entry using one or more messages 636 * Send each iovec entry using one or more messages
634 * 637 *
@@ -641,6 +644,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
641 curr_iovlen = m->msg_iovlen; 644 curr_iovlen = m->msg_iovlen;
642 my_msg.msg_iov = &my_iov; 645 my_msg.msg_iov = &my_iov;
643 my_msg.msg_iovlen = 1; 646 my_msg.msg_iovlen = 1;
647 my_msg.msg_flags = m->msg_flags;
648 my_msg.msg_name = NULL;
644 bytes_sent = 0; 649 bytes_sent = 0;
645 650
646 while (curr_iovlen--) { 651 while (curr_iovlen--) {
@@ -1203,7 +1208,8 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
1203 atomic_inc(&tipc_queue_size); 1208 atomic_inc(&tipc_queue_size);
1204 skb_queue_tail(&sock->sk->sk_receive_queue, buf); 1209 skb_queue_tail(&sock->sk->sk_receive_queue, buf);
1205 1210
1206 wake_up_interruptible(sock->sk->sk_sleep); 1211 if (waitqueue_active(sock->sk->sk_sleep))
1212 wake_up_interruptible(sock->sk->sk_sleep);
1207 return TIPC_OK; 1213 return TIPC_OK;
1208} 1214}
1209 1215
@@ -1218,7 +1224,8 @@ static void wakeupdispatch(struct tipc_port *tport)
1218{ 1224{
1219 struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle; 1225 struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle;
1220 1226
1221 wake_up_interruptible(tsock->sk.sk_sleep); 1227 if (waitqueue_active(tsock->sk.sk_sleep))
1228 wake_up_interruptible(tsock->sk.sk_sleep);
1222} 1229}
1223 1230
1224/** 1231/**
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index c51600ba5f4a..7a918f12a5df 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -155,7 +155,7 @@ void tipc_subscr_report_overlap(struct subscription *sub,
155 sub->seq.upper, found_lower, found_upper); 155 sub->seq.upper, found_lower, found_upper);
156 if (!tipc_subscr_overlap(sub, found_lower, found_upper)) 156 if (!tipc_subscr_overlap(sub, found_lower, found_upper))
157 return; 157 return;
158 if (!must && (sub->filter != TIPC_SUB_PORTS)) 158 if (!must && !(sub->filter & TIPC_SUB_PORTS))
159 return; 159 return;
160 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); 160 subscr_send_event(sub, found_lower, found_upper, event, port_ref, node);
161} 161}
@@ -176,6 +176,13 @@ static void subscr_timeout(struct subscription *sub)
176 if (subscriber == NULL) 176 if (subscriber == NULL)
177 return; 177 return;
178 178
179 /* Validate timeout (in case subscription is being cancelled) */
180
181 if (sub->timeout == TIPC_WAIT_FOREVER) {
182 tipc_ref_unlock(subscriber_ref);
183 return;
184 }
185
179 /* Unlink subscription from name table */ 186 /* Unlink subscription from name table */
180 187
181 tipc_nametbl_unsubscribe(sub); 188 tipc_nametbl_unsubscribe(sub);
@@ -199,6 +206,20 @@ static void subscr_timeout(struct subscription *sub)
199} 206}
200 207
201/** 208/**
209 * subscr_del - delete a subscription within a subscription list
210 *
211 * Called with subscriber locked.
212 */
213
214static void subscr_del(struct subscription *sub)
215{
216 tipc_nametbl_unsubscribe(sub);
217 list_del(&sub->subscription_list);
218 kfree(sub);
219 atomic_dec(&topsrv.subscription_count);
220}
221
222/**
202 * subscr_terminate - terminate communication with a subscriber 223 * subscr_terminate - terminate communication with a subscriber
203 * 224 *
204 * Called with subscriber locked. Routine must temporarily release this lock 225 * Called with subscriber locked. Routine must temporarily release this lock
@@ -227,12 +248,9 @@ static void subscr_terminate(struct subscriber *subscriber)
227 k_cancel_timer(&sub->timer); 248 k_cancel_timer(&sub->timer);
228 k_term_timer(&sub->timer); 249 k_term_timer(&sub->timer);
229 } 250 }
230 tipc_nametbl_unsubscribe(sub); 251 dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
231 list_del(&sub->subscription_list);
232 dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n",
233 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); 252 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
234 kfree(sub); 253 subscr_del(sub);
235 atomic_dec(&topsrv.subscription_count);
236 } 254 }
237 255
238 /* Sever connection to subscriber */ 256 /* Sever connection to subscriber */
@@ -253,6 +271,49 @@ static void subscr_terminate(struct subscriber *subscriber)
253} 271}
254 272
255/** 273/**
274 * subscr_cancel - handle subscription cancellation request
275 *
276 * Called with subscriber locked. Routine must temporarily release this lock
277 * to enable the subscription timeout routine to finish without deadlocking;
278 * the lock is then reclaimed to allow caller to release it upon return.
279 *
280 * Note that fields of 's' use subscriber's endianness!
281 */
282
283static void subscr_cancel(struct tipc_subscr *s,
284 struct subscriber *subscriber)
285{
286 struct subscription *sub;
287 struct subscription *sub_temp;
288 int found = 0;
289
290 /* Find first matching subscription, exit if not found */
291
292 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
293 subscription_list) {
294 if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
295 found = 1;
296 break;
297 }
298 }
299 if (!found)
300 return;
301
302 /* Cancel subscription timer (if used), then delete subscription */
303
304 if (sub->timeout != TIPC_WAIT_FOREVER) {
305 sub->timeout = TIPC_WAIT_FOREVER;
306 spin_unlock_bh(subscriber->lock);
307 k_cancel_timer(&sub->timer);
308 k_term_timer(&sub->timer);
309 spin_lock_bh(subscriber->lock);
310 }
311 dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
312 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
313 subscr_del(sub);
314}
315
316/**
256 * subscr_subscribe - create subscription for subscriber 317 * subscr_subscribe - create subscription for subscriber
257 * 318 *
258 * Called with subscriber locked 319 * Called with subscriber locked
@@ -263,6 +324,21 @@ static void subscr_subscribe(struct tipc_subscr *s,
263{ 324{
264 struct subscription *sub; 325 struct subscription *sub;
265 326
327 /* Determine/update subscriber's endianness */
328
329 if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE))
330 subscriber->swap = 0;
331 else
332 subscriber->swap = 1;
333
334 /* Detect & process a subscription cancellation request */
335
336 if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) {
337 s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap);
338 subscr_cancel(s, subscriber);
339 return;
340 }
341
266 /* Refuse subscription if global limit exceeded */ 342 /* Refuse subscription if global limit exceeded */
267 343
268 if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { 344 if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) {
@@ -281,13 +357,6 @@ static void subscr_subscribe(struct tipc_subscr *s,
281 return; 357 return;
282 } 358 }
283 359
284 /* Determine/update subscriber's endianness */
285
286 if ((s->filter == TIPC_SUB_PORTS) || (s->filter == TIPC_SUB_SERVICE))
287 subscriber->swap = 0;
288 else
289 subscriber->swap = 1;
290
291 /* Initialize subscription object */ 360 /* Initialize subscription object */
292 361
293 memset(sub, 0, sizeof(*sub)); 362 memset(sub, 0, sizeof(*sub));
@@ -296,8 +365,8 @@ static void subscr_subscribe(struct tipc_subscr *s,
296 sub->seq.upper = htohl(s->seq.upper, subscriber->swap); 365 sub->seq.upper = htohl(s->seq.upper, subscriber->swap);
297 sub->timeout = htohl(s->timeout, subscriber->swap); 366 sub->timeout = htohl(s->timeout, subscriber->swap);
298 sub->filter = htohl(s->filter, subscriber->swap); 367 sub->filter = htohl(s->filter, subscriber->swap);
299 if ((((sub->filter != TIPC_SUB_PORTS) 368 if ((!(sub->filter & TIPC_SUB_PORTS)
300 && (sub->filter != TIPC_SUB_SERVICE))) 369 == !(sub->filter & TIPC_SUB_SERVICE))
301 || (sub->seq.lower > sub->seq.upper)) { 370 || (sub->seq.lower > sub->seq.upper)) {
302 warn("Subscription rejected, illegal request\n"); 371 warn("Subscription rejected, illegal request\n");
303 kfree(sub); 372 kfree(sub);