diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bearer.c | 8 | ||||
-rw-r--r-- | net/tipc/config.c | 5 | ||||
-rw-r--r-- | net/tipc/core.c | 4 | ||||
-rw-r--r-- | net/tipc/core.h | 30 | ||||
-rw-r--r-- | net/tipc/dbg.c | 136 | ||||
-rw-r--r-- | net/tipc/dbg.h | 15 | ||||
-rw-r--r-- | net/tipc/discover.c | 39 | ||||
-rw-r--r-- | net/tipc/link.c | 8 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 2 | ||||
-rw-r--r-- | net/tipc/node.c | 2 | ||||
-rw-r--r-- | net/tipc/port.c | 7 | ||||
-rw-r--r-- | net/tipc/socket.c | 13 | ||||
-rw-r--r-- | net/tipc/subscr.c | 99 |
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); | |||
57 | int tipc_netlink_start(void); | 57 | int tipc_netlink_start(void); |
58 | void tipc_netlink_stop(void); | 58 | void 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; | |||
90 | atomic_t tipc_user_count = ATOMIC_INIT(0); | 90 | atomic_t tipc_user_count = ATOMIC_INIT(0); |
91 | 91 | ||
92 | const char tipc_alphabet[] = | 92 | const 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 | ||
67 | struct tipc_msg; | 67 | struct tipc_msg; |
68 | extern struct print_buf *TIPC_CONS, *TIPC_LOG; | 68 | extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG; |
69 | extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); | 69 | extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *); |
70 | void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); | 70 | void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); |
71 | void tipc_printf(struct print_buf *, const char *fmt, ...); | 71 | void 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 | ||
284 | struct tipc_skb_cb { | 288 | struct 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 | 41 | static char print_string[TIPC_PB_MAX_STR]; |
42 | |||
43 | static char print_string[MAX_STRING]; | ||
44 | static DEFINE_SPINLOCK(print_lock); | 42 | static DEFINE_SPINLOCK(print_lock); |
45 | 43 | ||
44 | static struct print_buf null_buf = { NULL, 0, NULL, NULL }; | ||
45 | struct print_buf *TIPC_NULL = &null_buf; | ||
46 | |||
46 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; | 47 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; |
47 | struct print_buf *TIPC_CONS = &cons_buf; | 48 | struct 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 | ||
77 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz) | 86 | void 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 | ||
93 | void tipc_printbuf_reset(struct print_buf *pb) | 106 | void 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 | ||
103 | int tipc_printbuf_empty(struct print_buf *pb) | 118 | int 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 | ||
117 | int tipc_printbuf_validate(struct print_buf *pb) | 133 | int 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 | ||
189 | void tipc_printf(struct print_buf *pb, const char *fmt, ...) | 211 | void 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 | ||
229 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | 259 | struct 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 | ||
292 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) | 328 | void 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 | ||
330 | void tipc_log_reinit(int log_size) | 371 | void 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 | |||
40 | struct print_buf { | 48 | struct 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 | ||
47 | void 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 | |||
58 | void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); | ||
48 | void tipc_printbuf_reset(struct print_buf *pb); | 59 | void tipc_printbuf_reset(struct print_buf *pb); |
49 | int tipc_printbuf_empty(struct print_buf *pb); | 60 | int tipc_printbuf_empty(struct print_buf *pb); |
50 | int tipc_printbuf_validate(struct print_buf *pb); | 61 | int 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 | |||
141 | static 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 | ||
160 | static void dbg_print_link(struct link *l_ptr, const char *str) | 160 | static 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 | ||
166 | static void dbg_print_buf_chain(struct sk_buff *root_buf) | 166 | static 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 | |||
214 | static 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 | |||
283 | static 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); |