Commit b0c1e928c85023c73780b5d9873406ccf1cd8019

Authored by Allan Stephens
Committed by David S. Miller
1 parent aa70200e00

tipc: Remove user registry subsystem

Eliminates routines, data structures, and files that make up TIPC's
user registry. The user registry is no longer needed since the native
API routines that utilized it no longer exist and there are no longer
any internal TIPC services that use it.

Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 8 changed files with 7 additions and 292 deletions Inline Diff

1 # 1 #
2 # Makefile for the Linux TIPC layer 2 # Makefile for the Linux TIPC layer
3 # 3 #
4 4
5 obj-$(CONFIG_TIPC) := tipc.o 5 obj-$(CONFIG_TIPC) := tipc.o
6 6
7 tipc-y += addr.o bcast.o bearer.o config.o \ 7 tipc-y += addr.o bcast.o bearer.o config.o \
8 core.o handler.o link.o discover.o msg.o \ 8 core.o handler.o link.o discover.o msg.o \
9 name_distr.o subscr.o name_table.o net.o \ 9 name_distr.o subscr.o name_table.o net.o \
10 netlink.o node.o node_subscr.o port.o ref.o \ 10 netlink.o node.o node_subscr.o port.o ref.o \
11 socket.o user_reg.o dbg.o eth_media.o 11 socket.o dbg.o eth_media.o
12 12
13 # End of file 13 # End of file
14 14
1 /* 1 /*
2 * net/tipc/config.c: TIPC configuration management code 2 * net/tipc/config.c: TIPC configuration management code
3 * 3 *
4 * Copyright (c) 2002-2006, Ericsson AB 4 * Copyright (c) 2002-2006, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 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
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #include "core.h" 37 #include "core.h"
38 #include "port.h" 38 #include "port.h"
39 #include "link.h" 39 #include "link.h"
40 #include "name_table.h" 40 #include "name_table.h"
41 #include "config.h" 41 #include "config.h"
42 42
43 static u32 config_port_ref; 43 static u32 config_port_ref;
44 44
45 static DEFINE_SPINLOCK(config_lock); 45 static DEFINE_SPINLOCK(config_lock);
46 46
47 static const void *req_tlv_area; /* request message TLV area */ 47 static const void *req_tlv_area; /* request message TLV area */
48 static int req_tlv_space; /* request message TLV area size */ 48 static int req_tlv_space; /* request message TLV area size */
49 static int rep_headroom; /* reply message headroom to use */ 49 static int rep_headroom; /* reply message headroom to use */
50 50
51 51
52 struct sk_buff *tipc_cfg_reply_alloc(int payload_size) 52 struct sk_buff *tipc_cfg_reply_alloc(int payload_size)
53 { 53 {
54 struct sk_buff *buf; 54 struct sk_buff *buf;
55 55
56 buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC); 56 buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC);
57 if (buf) 57 if (buf)
58 skb_reserve(buf, rep_headroom); 58 skb_reserve(buf, rep_headroom);
59 return buf; 59 return buf;
60 } 60 }
61 61
62 int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, 62 int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
63 void *tlv_data, int tlv_data_size) 63 void *tlv_data, int tlv_data_size)
64 { 64 {
65 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf); 65 struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
66 int new_tlv_space = TLV_SPACE(tlv_data_size); 66 int new_tlv_space = TLV_SPACE(tlv_data_size);
67 67
68 if (skb_tailroom(buf) < new_tlv_space) { 68 if (skb_tailroom(buf) < new_tlv_space) {
69 dbg("tipc_cfg_append_tlv unable to append TLV\n"); 69 dbg("tipc_cfg_append_tlv unable to append TLV\n");
70 return 0; 70 return 0;
71 } 71 }
72 skb_put(buf, new_tlv_space); 72 skb_put(buf, new_tlv_space);
73 tlv->tlv_type = htons(tlv_type); 73 tlv->tlv_type = htons(tlv_type);
74 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); 74 tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size));
75 if (tlv_data_size && tlv_data) 75 if (tlv_data_size && tlv_data)
76 memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size); 76 memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size);
77 return 1; 77 return 1;
78 } 78 }
79 79
80 static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) 80 static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
81 { 81 {
82 struct sk_buff *buf; 82 struct sk_buff *buf;
83 __be32 value_net; 83 __be32 value_net;
84 84
85 buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value))); 85 buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value)));
86 if (buf) { 86 if (buf) {
87 value_net = htonl(value); 87 value_net = htonl(value);
88 tipc_cfg_append_tlv(buf, tlv_type, &value_net, 88 tipc_cfg_append_tlv(buf, tlv_type, &value_net,
89 sizeof(value_net)); 89 sizeof(value_net));
90 } 90 }
91 return buf; 91 return buf;
92 } 92 }
93 93
94 static struct sk_buff *tipc_cfg_reply_unsigned(u32 value) 94 static struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
95 { 95 {
96 return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); 96 return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
97 } 97 }
98 98
99 struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) 99 struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
100 { 100 {
101 struct sk_buff *buf; 101 struct sk_buff *buf;
102 int string_len = strlen(string) + 1; 102 int string_len = strlen(string) + 1;
103 103
104 buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len)); 104 buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len));
105 if (buf) 105 if (buf)
106 tipc_cfg_append_tlv(buf, tlv_type, string, string_len); 106 tipc_cfg_append_tlv(buf, tlv_type, string, string_len);
107 return buf; 107 return buf;
108 } 108 }
109 109
110 #define MAX_STATS_INFO 2000 110 #define MAX_STATS_INFO 2000
111 111
112 static struct sk_buff *tipc_show_stats(void) 112 static struct sk_buff *tipc_show_stats(void)
113 { 113 {
114 struct sk_buff *buf; 114 struct sk_buff *buf;
115 struct tlv_desc *rep_tlv; 115 struct tlv_desc *rep_tlv;
116 struct print_buf pb; 116 struct print_buf pb;
117 int str_len; 117 int str_len;
118 u32 value; 118 u32 value;
119 119
120 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 120 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
121 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 121 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
122 122
123 value = ntohl(*(u32 *)TLV_DATA(req_tlv_area)); 123 value = ntohl(*(u32 *)TLV_DATA(req_tlv_area));
124 if (value != 0) 124 if (value != 0)
125 return tipc_cfg_reply_error_string("unsupported argument"); 125 return tipc_cfg_reply_error_string("unsupported argument");
126 126
127 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO)); 127 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO));
128 if (buf == NULL) 128 if (buf == NULL)
129 return NULL; 129 return NULL;
130 130
131 rep_tlv = (struct tlv_desc *)buf->data; 131 rep_tlv = (struct tlv_desc *)buf->data;
132 tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO); 132 tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO);
133 133
134 tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n"); 134 tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "\n");
135 135
136 /* Use additional tipc_printf()'s to return more info ... */ 136 /* Use additional tipc_printf()'s to return more info ... */
137 137
138 str_len = tipc_printbuf_validate(&pb); 138 str_len = tipc_printbuf_validate(&pb);
139 skb_put(buf, TLV_SPACE(str_len)); 139 skb_put(buf, TLV_SPACE(str_len));
140 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 140 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
141 141
142 return buf; 142 return buf;
143 } 143 }
144 144
145 static struct sk_buff *cfg_enable_bearer(void) 145 static struct sk_buff *cfg_enable_bearer(void)
146 { 146 {
147 struct tipc_bearer_config *args; 147 struct tipc_bearer_config *args;
148 148
149 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG)) 149 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG))
150 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 150 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
151 151
152 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); 152 args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
153 if (tipc_enable_bearer(args->name, 153 if (tipc_enable_bearer(args->name,
154 ntohl(args->detect_scope), 154 ntohl(args->detect_scope),
155 ntohl(args->priority))) 155 ntohl(args->priority)))
156 return tipc_cfg_reply_error_string("unable to enable bearer"); 156 return tipc_cfg_reply_error_string("unable to enable bearer");
157 157
158 return tipc_cfg_reply_none(); 158 return tipc_cfg_reply_none();
159 } 159 }
160 160
161 static struct sk_buff *cfg_disable_bearer(void) 161 static struct sk_buff *cfg_disable_bearer(void)
162 { 162 {
163 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME)) 163 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME))
164 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 164 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
165 165
166 if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area))) 166 if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))
167 return tipc_cfg_reply_error_string("unable to disable bearer"); 167 return tipc_cfg_reply_error_string("unable to disable bearer");
168 168
169 return tipc_cfg_reply_none(); 169 return tipc_cfg_reply_none();
170 } 170 }
171 171
172 static struct sk_buff *cfg_set_own_addr(void) 172 static struct sk_buff *cfg_set_own_addr(void)
173 { 173 {
174 u32 addr; 174 u32 addr;
175 175
176 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 176 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
177 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 177 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
178 178
179 addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 179 addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
180 if (addr == tipc_own_addr) 180 if (addr == tipc_own_addr)
181 return tipc_cfg_reply_none(); 181 return tipc_cfg_reply_none();
182 if (!tipc_addr_node_valid(addr)) 182 if (!tipc_addr_node_valid(addr))
183 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 183 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
184 " (node address)"); 184 " (node address)");
185 if (tipc_mode == TIPC_NET_MODE) 185 if (tipc_mode == TIPC_NET_MODE)
186 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 186 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
187 " (cannot change node address once assigned)"); 187 " (cannot change node address once assigned)");
188 188
189 /* 189 /*
190 * Must release all spinlocks before calling start_net() because 190 * Must release all spinlocks before calling start_net() because
191 * Linux version of TIPC calls eth_media_start() which calls 191 * Linux version of TIPC calls eth_media_start() which calls
192 * register_netdevice_notifier() which may block! 192 * register_netdevice_notifier() which may block!
193 * 193 *
194 * Temporarily releasing the lock should be harmless for non-Linux TIPC, 194 * Temporarily releasing the lock should be harmless for non-Linux TIPC,
195 * but Linux version of eth_media_start() should really be reworked 195 * but Linux version of eth_media_start() should really be reworked
196 * so that it can be called with spinlocks held. 196 * so that it can be called with spinlocks held.
197 */ 197 */
198 198
199 spin_unlock_bh(&config_lock); 199 spin_unlock_bh(&config_lock);
200 tipc_core_start_net(addr); 200 tipc_core_start_net(addr);
201 spin_lock_bh(&config_lock); 201 spin_lock_bh(&config_lock);
202 return tipc_cfg_reply_none(); 202 return tipc_cfg_reply_none();
203 } 203 }
204 204
205 static struct sk_buff *cfg_set_remote_mng(void) 205 static struct sk_buff *cfg_set_remote_mng(void)
206 { 206 {
207 u32 value; 207 u32 value;
208 208
209 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 209 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
210 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 210 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
211 211
212 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 212 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
213 tipc_remote_management = (value != 0); 213 tipc_remote_management = (value != 0);
214 return tipc_cfg_reply_none(); 214 return tipc_cfg_reply_none();
215 } 215 }
216 216
217 static struct sk_buff *cfg_set_max_publications(void) 217 static struct sk_buff *cfg_set_max_publications(void)
218 { 218 {
219 u32 value; 219 u32 value;
220 220
221 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 221 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
222 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 222 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
223 223
224 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 224 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
225 if (value != delimit(value, 1, 65535)) 225 if (value != delimit(value, 1, 65535))
226 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 226 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
227 " (max publications must be 1-65535)"); 227 " (max publications must be 1-65535)");
228 tipc_max_publications = value; 228 tipc_max_publications = value;
229 return tipc_cfg_reply_none(); 229 return tipc_cfg_reply_none();
230 } 230 }
231 231
232 static struct sk_buff *cfg_set_max_subscriptions(void) 232 static struct sk_buff *cfg_set_max_subscriptions(void)
233 { 233 {
234 u32 value; 234 u32 value;
235 235
236 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 236 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
237 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 237 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
238 238
239 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 239 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
240 if (value != delimit(value, 1, 65535)) 240 if (value != delimit(value, 1, 65535))
241 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 241 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
242 " (max subscriptions must be 1-65535"); 242 " (max subscriptions must be 1-65535");
243 tipc_max_subscriptions = value; 243 tipc_max_subscriptions = value;
244 return tipc_cfg_reply_none(); 244 return tipc_cfg_reply_none();
245 } 245 }
246 246
247 static struct sk_buff *cfg_set_max_ports(void) 247 static struct sk_buff *cfg_set_max_ports(void)
248 { 248 {
249 u32 value; 249 u32 value;
250 250
251 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 251 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
252 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 252 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
253 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 253 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
254 if (value == tipc_max_ports) 254 if (value == tipc_max_ports)
255 return tipc_cfg_reply_none(); 255 return tipc_cfg_reply_none();
256 if (value != delimit(value, 127, 65535)) 256 if (value != delimit(value, 127, 65535))
257 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 257 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
258 " (max ports must be 127-65535)"); 258 " (max ports must be 127-65535)");
259 if (tipc_mode != TIPC_NOT_RUNNING) 259 if (tipc_mode != TIPC_NOT_RUNNING)
260 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 260 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
261 " (cannot change max ports while TIPC is active)"); 261 " (cannot change max ports while TIPC is active)");
262 tipc_max_ports = value; 262 tipc_max_ports = value;
263 return tipc_cfg_reply_none(); 263 return tipc_cfg_reply_none();
264 } 264 }
265 265
266 static struct sk_buff *cfg_set_max_nodes(void) 266 static struct sk_buff *cfg_set_max_nodes(void)
267 { 267 {
268 u32 value; 268 u32 value;
269 269
270 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 270 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
271 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 271 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
272 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 272 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
273 if (value == tipc_max_nodes) 273 if (value == tipc_max_nodes)
274 return tipc_cfg_reply_none(); 274 return tipc_cfg_reply_none();
275 if (value != delimit(value, 8, 2047)) 275 if (value != delimit(value, 8, 2047))
276 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 276 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
277 " (max nodes must be 8-2047)"); 277 " (max nodes must be 8-2047)");
278 if (tipc_mode == TIPC_NET_MODE) 278 if (tipc_mode == TIPC_NET_MODE)
279 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 279 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
280 " (cannot change max nodes once TIPC has joined a network)"); 280 " (cannot change max nodes once TIPC has joined a network)");
281 tipc_max_nodes = value; 281 tipc_max_nodes = value;
282 return tipc_cfg_reply_none(); 282 return tipc_cfg_reply_none();
283 } 283 }
284 284
285 static struct sk_buff *cfg_set_netid(void) 285 static struct sk_buff *cfg_set_netid(void)
286 { 286 {
287 u32 value; 287 u32 value;
288 288
289 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 289 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
290 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 290 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
291 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area)); 291 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
292 if (value == tipc_net_id) 292 if (value == tipc_net_id)
293 return tipc_cfg_reply_none(); 293 return tipc_cfg_reply_none();
294 if (value != delimit(value, 1, 9999)) 294 if (value != delimit(value, 1, 9999))
295 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 295 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
296 " (network id must be 1-9999)"); 296 " (network id must be 1-9999)");
297 if (tipc_mode == TIPC_NET_MODE) 297 if (tipc_mode == TIPC_NET_MODE)
298 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 298 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
299 " (cannot change network id once TIPC has joined a network)"); 299 " (cannot change network id once TIPC has joined a network)");
300 tipc_net_id = value; 300 tipc_net_id = value;
301 return tipc_cfg_reply_none(); 301 return tipc_cfg_reply_none();
302 } 302 }
303 303
304 struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area, 304 struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
305 int request_space, int reply_headroom) 305 int request_space, int reply_headroom)
306 { 306 {
307 struct sk_buff *rep_tlv_buf; 307 struct sk_buff *rep_tlv_buf;
308 308
309 spin_lock_bh(&config_lock); 309 spin_lock_bh(&config_lock);
310 310
311 /* Save request and reply details in a well-known location */ 311 /* Save request and reply details in a well-known location */
312 312
313 req_tlv_area = request_area; 313 req_tlv_area = request_area;
314 req_tlv_space = request_space; 314 req_tlv_space = request_space;
315 rep_headroom = reply_headroom; 315 rep_headroom = reply_headroom;
316 316
317 /* Check command authorization */ 317 /* Check command authorization */
318 318
319 if (likely(orig_node == tipc_own_addr)) { 319 if (likely(orig_node == tipc_own_addr)) {
320 /* command is permitted */ 320 /* command is permitted */
321 } else if (cmd >= 0x8000) { 321 } else if (cmd >= 0x8000) {
322 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 322 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
323 " (cannot be done remotely)"); 323 " (cannot be done remotely)");
324 goto exit; 324 goto exit;
325 } else if (!tipc_remote_management) { 325 } else if (!tipc_remote_management) {
326 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE); 326 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
327 goto exit; 327 goto exit;
328 } 328 }
329 else if (cmd >= 0x4000) { 329 else if (cmd >= 0x4000) {
330 u32 domain = 0; 330 u32 domain = 0;
331 331
332 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) || 332 if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
333 (domain != orig_node)) { 333 (domain != orig_node)) {
334 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR); 334 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR);
335 goto exit; 335 goto exit;
336 } 336 }
337 } 337 }
338 338
339 /* Call appropriate processing routine */ 339 /* Call appropriate processing routine */
340 340
341 switch (cmd) { 341 switch (cmd) {
342 case TIPC_CMD_NOOP: 342 case TIPC_CMD_NOOP:
343 rep_tlv_buf = tipc_cfg_reply_none(); 343 rep_tlv_buf = tipc_cfg_reply_none();
344 break; 344 break;
345 case TIPC_CMD_GET_NODES: 345 case TIPC_CMD_GET_NODES:
346 rep_tlv_buf = tipc_node_get_nodes(req_tlv_area, req_tlv_space); 346 rep_tlv_buf = tipc_node_get_nodes(req_tlv_area, req_tlv_space);
347 break; 347 break;
348 case TIPC_CMD_GET_LINKS: 348 case TIPC_CMD_GET_LINKS:
349 rep_tlv_buf = tipc_node_get_links(req_tlv_area, req_tlv_space); 349 rep_tlv_buf = tipc_node_get_links(req_tlv_area, req_tlv_space);
350 break; 350 break;
351 case TIPC_CMD_SHOW_LINK_STATS: 351 case TIPC_CMD_SHOW_LINK_STATS:
352 rep_tlv_buf = tipc_link_cmd_show_stats(req_tlv_area, req_tlv_space); 352 rep_tlv_buf = tipc_link_cmd_show_stats(req_tlv_area, req_tlv_space);
353 break; 353 break;
354 case TIPC_CMD_RESET_LINK_STATS: 354 case TIPC_CMD_RESET_LINK_STATS:
355 rep_tlv_buf = tipc_link_cmd_reset_stats(req_tlv_area, req_tlv_space); 355 rep_tlv_buf = tipc_link_cmd_reset_stats(req_tlv_area, req_tlv_space);
356 break; 356 break;
357 case TIPC_CMD_SHOW_NAME_TABLE: 357 case TIPC_CMD_SHOW_NAME_TABLE:
358 rep_tlv_buf = tipc_nametbl_get(req_tlv_area, req_tlv_space); 358 rep_tlv_buf = tipc_nametbl_get(req_tlv_area, req_tlv_space);
359 break; 359 break;
360 case TIPC_CMD_GET_BEARER_NAMES: 360 case TIPC_CMD_GET_BEARER_NAMES:
361 rep_tlv_buf = tipc_bearer_get_names(); 361 rep_tlv_buf = tipc_bearer_get_names();
362 break; 362 break;
363 case TIPC_CMD_GET_MEDIA_NAMES: 363 case TIPC_CMD_GET_MEDIA_NAMES:
364 rep_tlv_buf = tipc_media_get_names(); 364 rep_tlv_buf = tipc_media_get_names();
365 break; 365 break;
366 case TIPC_CMD_SHOW_PORTS: 366 case TIPC_CMD_SHOW_PORTS:
367 rep_tlv_buf = tipc_port_get_ports(); 367 rep_tlv_buf = tipc_port_get_ports();
368 break; 368 break;
369 case TIPC_CMD_SET_LOG_SIZE: 369 case TIPC_CMD_SET_LOG_SIZE:
370 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); 370 rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
371 break; 371 break;
372 case TIPC_CMD_DUMP_LOG: 372 case TIPC_CMD_DUMP_LOG:
373 rep_tlv_buf = tipc_log_dump(); 373 rep_tlv_buf = tipc_log_dump();
374 break; 374 break;
375 case TIPC_CMD_SHOW_STATS: 375 case TIPC_CMD_SHOW_STATS:
376 rep_tlv_buf = tipc_show_stats(); 376 rep_tlv_buf = tipc_show_stats();
377 break; 377 break;
378 case TIPC_CMD_SET_LINK_TOL: 378 case TIPC_CMD_SET_LINK_TOL:
379 case TIPC_CMD_SET_LINK_PRI: 379 case TIPC_CMD_SET_LINK_PRI:
380 case TIPC_CMD_SET_LINK_WINDOW: 380 case TIPC_CMD_SET_LINK_WINDOW:
381 rep_tlv_buf = tipc_link_cmd_config(req_tlv_area, req_tlv_space, cmd); 381 rep_tlv_buf = tipc_link_cmd_config(req_tlv_area, req_tlv_space, cmd);
382 break; 382 break;
383 case TIPC_CMD_ENABLE_BEARER: 383 case TIPC_CMD_ENABLE_BEARER:
384 rep_tlv_buf = cfg_enable_bearer(); 384 rep_tlv_buf = cfg_enable_bearer();
385 break; 385 break;
386 case TIPC_CMD_DISABLE_BEARER: 386 case TIPC_CMD_DISABLE_BEARER:
387 rep_tlv_buf = cfg_disable_bearer(); 387 rep_tlv_buf = cfg_disable_bearer();
388 break; 388 break;
389 case TIPC_CMD_SET_NODE_ADDR: 389 case TIPC_CMD_SET_NODE_ADDR:
390 rep_tlv_buf = cfg_set_own_addr(); 390 rep_tlv_buf = cfg_set_own_addr();
391 break; 391 break;
392 case TIPC_CMD_SET_REMOTE_MNG: 392 case TIPC_CMD_SET_REMOTE_MNG:
393 rep_tlv_buf = cfg_set_remote_mng(); 393 rep_tlv_buf = cfg_set_remote_mng();
394 break; 394 break;
395 case TIPC_CMD_SET_MAX_PORTS: 395 case TIPC_CMD_SET_MAX_PORTS:
396 rep_tlv_buf = cfg_set_max_ports(); 396 rep_tlv_buf = cfg_set_max_ports();
397 break; 397 break;
398 case TIPC_CMD_SET_MAX_PUBL: 398 case TIPC_CMD_SET_MAX_PUBL:
399 rep_tlv_buf = cfg_set_max_publications(); 399 rep_tlv_buf = cfg_set_max_publications();
400 break; 400 break;
401 case TIPC_CMD_SET_MAX_SUBSCR: 401 case TIPC_CMD_SET_MAX_SUBSCR:
402 rep_tlv_buf = cfg_set_max_subscriptions(); 402 rep_tlv_buf = cfg_set_max_subscriptions();
403 break; 403 break;
404 case TIPC_CMD_SET_MAX_NODES: 404 case TIPC_CMD_SET_MAX_NODES:
405 rep_tlv_buf = cfg_set_max_nodes(); 405 rep_tlv_buf = cfg_set_max_nodes();
406 break; 406 break;
407 case TIPC_CMD_SET_NETID: 407 case TIPC_CMD_SET_NETID:
408 rep_tlv_buf = cfg_set_netid(); 408 rep_tlv_buf = cfg_set_netid();
409 break; 409 break;
410 case TIPC_CMD_GET_REMOTE_MNG: 410 case TIPC_CMD_GET_REMOTE_MNG:
411 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_remote_management); 411 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_remote_management);
412 break; 412 break;
413 case TIPC_CMD_GET_MAX_PORTS: 413 case TIPC_CMD_GET_MAX_PORTS:
414 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_ports); 414 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_ports);
415 break; 415 break;
416 case TIPC_CMD_GET_MAX_PUBL: 416 case TIPC_CMD_GET_MAX_PUBL:
417 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_publications); 417 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_publications);
418 break; 418 break;
419 case TIPC_CMD_GET_MAX_SUBSCR: 419 case TIPC_CMD_GET_MAX_SUBSCR:
420 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions); 420 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
421 break; 421 break;
422 case TIPC_CMD_GET_MAX_NODES: 422 case TIPC_CMD_GET_MAX_NODES:
423 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes); 423 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_nodes);
424 break; 424 break;
425 case TIPC_CMD_GET_NETID: 425 case TIPC_CMD_GET_NETID:
426 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id); 426 rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
427 break; 427 break;
428 case TIPC_CMD_NOT_NET_ADMIN: 428 case TIPC_CMD_NOT_NET_ADMIN:
429 rep_tlv_buf = 429 rep_tlv_buf =
430 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); 430 tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
431 break; 431 break;
432 case TIPC_CMD_SET_MAX_ZONES: 432 case TIPC_CMD_SET_MAX_ZONES:
433 case TIPC_CMD_GET_MAX_ZONES: 433 case TIPC_CMD_GET_MAX_ZONES:
434 case TIPC_CMD_SET_MAX_SLAVES: 434 case TIPC_CMD_SET_MAX_SLAVES:
435 case TIPC_CMD_GET_MAX_SLAVES: 435 case TIPC_CMD_GET_MAX_SLAVES:
436 case TIPC_CMD_SET_MAX_CLUSTERS: 436 case TIPC_CMD_SET_MAX_CLUSTERS:
437 case TIPC_CMD_GET_MAX_CLUSTERS: 437 case TIPC_CMD_GET_MAX_CLUSTERS:
438 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 438 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
439 " (obsolete command)"); 439 " (obsolete command)");
440 break; 440 break;
441 default: 441 default:
442 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 442 rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
443 " (unknown command)"); 443 " (unknown command)");
444 break; 444 break;
445 } 445 }
446 446
447 /* Return reply buffer */ 447 /* Return reply buffer */
448 exit: 448 exit:
449 spin_unlock_bh(&config_lock); 449 spin_unlock_bh(&config_lock);
450 return rep_tlv_buf; 450 return rep_tlv_buf;
451 } 451 }
452 452
453 static void cfg_named_msg_event(void *userdata, 453 static void cfg_named_msg_event(void *userdata,
454 u32 port_ref, 454 u32 port_ref,
455 struct sk_buff **buf, 455 struct sk_buff **buf,
456 const unchar *msg, 456 const unchar *msg,
457 u32 size, 457 u32 size,
458 u32 importance, 458 u32 importance,
459 struct tipc_portid const *orig, 459 struct tipc_portid const *orig,
460 struct tipc_name_seq const *dest) 460 struct tipc_name_seq const *dest)
461 { 461 {
462 struct tipc_cfg_msg_hdr *req_hdr; 462 struct tipc_cfg_msg_hdr *req_hdr;
463 struct tipc_cfg_msg_hdr *rep_hdr; 463 struct tipc_cfg_msg_hdr *rep_hdr;
464 struct sk_buff *rep_buf; 464 struct sk_buff *rep_buf;
465 465
466 /* Validate configuration message header (ignore invalid message) */ 466 /* Validate configuration message header (ignore invalid message) */
467 467
468 req_hdr = (struct tipc_cfg_msg_hdr *)msg; 468 req_hdr = (struct tipc_cfg_msg_hdr *)msg;
469 if ((size < sizeof(*req_hdr)) || 469 if ((size < sizeof(*req_hdr)) ||
470 (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) || 470 (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
471 (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) { 471 (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
472 warn("Invalid configuration message discarded\n"); 472 warn("Invalid configuration message discarded\n");
473 return; 473 return;
474 } 474 }
475 475
476 /* Generate reply for request (if can't, return request) */ 476 /* Generate reply for request (if can't, return request) */
477 477
478 rep_buf = tipc_cfg_do_cmd(orig->node, 478 rep_buf = tipc_cfg_do_cmd(orig->node,
479 ntohs(req_hdr->tcm_type), 479 ntohs(req_hdr->tcm_type),
480 msg + sizeof(*req_hdr), 480 msg + sizeof(*req_hdr),
481 size - sizeof(*req_hdr), 481 size - sizeof(*req_hdr),
482 BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr)); 482 BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
483 if (rep_buf) { 483 if (rep_buf) {
484 skb_push(rep_buf, sizeof(*rep_hdr)); 484 skb_push(rep_buf, sizeof(*rep_hdr));
485 rep_hdr = (struct tipc_cfg_msg_hdr *)rep_buf->data; 485 rep_hdr = (struct tipc_cfg_msg_hdr *)rep_buf->data;
486 memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); 486 memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
487 rep_hdr->tcm_len = htonl(rep_buf->len); 487 rep_hdr->tcm_len = htonl(rep_buf->len);
488 rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); 488 rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
489 } else { 489 } else {
490 rep_buf = *buf; 490 rep_buf = *buf;
491 *buf = NULL; 491 *buf = NULL;
492 } 492 }
493 493
494 /* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */ 494 /* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */
495 tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len); 495 tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len);
496 } 496 }
497 497
498 int tipc_cfg_init(void) 498 int tipc_cfg_init(void)
499 { 499 {
500 struct tipc_name_seq seq; 500 struct tipc_name_seq seq;
501 int res; 501 int res;
502 502
503 res = tipc_createport(0, NULL, TIPC_CRITICAL_IMPORTANCE, 503 res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
504 NULL, NULL, NULL, 504 NULL, NULL, NULL,
505 NULL, cfg_named_msg_event, NULL, 505 NULL, cfg_named_msg_event, NULL,
506 NULL, &config_port_ref); 506 NULL, &config_port_ref);
507 if (res) 507 if (res)
508 goto failed; 508 goto failed;
509 509
510 seq.type = TIPC_CFG_SRV; 510 seq.type = TIPC_CFG_SRV;
511 seq.lower = seq.upper = tipc_own_addr; 511 seq.lower = seq.upper = tipc_own_addr;
512 res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq); 512 res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
513 if (res) 513 if (res)
514 goto failed; 514 goto failed;
515 515
516 return 0; 516 return 0;
517 517
518 failed: 518 failed:
519 err("Unable to create configuration service\n"); 519 err("Unable to create configuration service\n");
520 return res; 520 return res;
521 } 521 }
522 522
523 void tipc_cfg_stop(void) 523 void tipc_cfg_stop(void)
524 { 524 {
525 if (config_port_ref) { 525 if (config_port_ref) {
526 tipc_deleteport(config_port_ref); 526 tipc_deleteport(config_port_ref);
527 config_port_ref = 0; 527 config_port_ref = 0;
528 } 528 }
529 } 529 }
530 530
1 /* 1 /*
2 * net/tipc/core.c: TIPC module code 2 * net/tipc/core.c: TIPC module code
3 * 3 *
4 * Copyright (c) 2003-2006, Ericsson AB 4 * Copyright (c) 2003-2006, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2006, 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
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #include <linux/init.h> 37 #include <linux/init.h>
38 #include <linux/module.h> 38 #include <linux/module.h>
39 #include <linux/kernel.h> 39 #include <linux/kernel.h>
40 #include <linux/random.h> 40 #include <linux/random.h>
41 41
42 #include "core.h" 42 #include "core.h"
43 #include "ref.h" 43 #include "ref.h"
44 #include "net.h" 44 #include "net.h"
45 #include "user_reg.h"
46 #include "name_table.h" 45 #include "name_table.h"
47 #include "subscr.h" 46 #include "subscr.h"
48 #include "config.h" 47 #include "config.h"
49 48
50 49
51 #ifndef CONFIG_TIPC_NODES 50 #ifndef CONFIG_TIPC_NODES
52 #define CONFIG_TIPC_NODES 255 51 #define CONFIG_TIPC_NODES 255
53 #endif 52 #endif
54 53
55 #ifndef CONFIG_TIPC_PORTS 54 #ifndef CONFIG_TIPC_PORTS
56 #define CONFIG_TIPC_PORTS 8191 55 #define CONFIG_TIPC_PORTS 8191
57 #endif 56 #endif
58 57
59 #ifndef CONFIG_TIPC_LOG 58 #ifndef CONFIG_TIPC_LOG
60 #define CONFIG_TIPC_LOG 0 59 #define CONFIG_TIPC_LOG 0
61 #endif 60 #endif
62 61
63 /* global variables used by multiple sub-systems within TIPC */ 62 /* global variables used by multiple sub-systems within TIPC */
64 63
65 int tipc_mode = TIPC_NOT_RUNNING; 64 int tipc_mode = TIPC_NOT_RUNNING;
66 int tipc_random; 65 int tipc_random;
67 atomic_t tipc_user_count = ATOMIC_INIT(0); 66 atomic_t tipc_user_count = ATOMIC_INIT(0);
68 67
69 const char tipc_alphabet[] = 68 const char tipc_alphabet[] =
70 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."; 69 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
71 70
72 /* configurable TIPC parameters */ 71 /* configurable TIPC parameters */
73 72
74 u32 tipc_own_addr; 73 u32 tipc_own_addr;
75 int tipc_max_nodes; 74 int tipc_max_nodes;
76 int tipc_max_ports; 75 int tipc_max_ports;
77 int tipc_max_subscriptions; 76 int tipc_max_subscriptions;
78 int tipc_max_publications; 77 int tipc_max_publications;
79 int tipc_net_id; 78 int tipc_net_id;
80 int tipc_remote_management; 79 int tipc_remote_management;
81 80
82 81
83 /** 82 /**
84 * tipc_buf_acquire - creates a TIPC message buffer 83 * tipc_buf_acquire - creates a TIPC message buffer
85 * @size: message size (including TIPC header) 84 * @size: message size (including TIPC header)
86 * 85 *
87 * Returns a new buffer with data pointers set to the specified size. 86 * Returns a new buffer with data pointers set to the specified size.
88 * 87 *
89 * NOTE: Headroom is reserved to allow prepending of a data link header. 88 * NOTE: Headroom is reserved to allow prepending of a data link header.
90 * There may also be unrequested tailroom present at the buffer's end. 89 * There may also be unrequested tailroom present at the buffer's end.
91 */ 90 */
92 91
93 struct sk_buff *tipc_buf_acquire(u32 size) 92 struct sk_buff *tipc_buf_acquire(u32 size)
94 { 93 {
95 struct sk_buff *skb; 94 struct sk_buff *skb;
96 unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; 95 unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
97 96
98 skb = alloc_skb_fclone(buf_size, GFP_ATOMIC); 97 skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
99 if (skb) { 98 if (skb) {
100 skb_reserve(skb, BUF_HEADROOM); 99 skb_reserve(skb, BUF_HEADROOM);
101 skb_put(skb, size); 100 skb_put(skb, size);
102 skb->next = NULL; 101 skb->next = NULL;
103 } 102 }
104 return skb; 103 return skb;
105 } 104 }
106 105
107 /** 106 /**
108 * tipc_core_stop_net - shut down TIPC networking sub-systems 107 * tipc_core_stop_net - shut down TIPC networking sub-systems
109 */ 108 */
110 109
111 static void tipc_core_stop_net(void) 110 static void tipc_core_stop_net(void)
112 { 111 {
113 tipc_eth_media_stop(); 112 tipc_eth_media_stop();
114 tipc_net_stop(); 113 tipc_net_stop();
115 } 114 }
116 115
117 /** 116 /**
118 * start_net - start TIPC networking sub-systems 117 * start_net - start TIPC networking sub-systems
119 */ 118 */
120 119
121 int tipc_core_start_net(unsigned long addr) 120 int tipc_core_start_net(unsigned long addr)
122 { 121 {
123 int res; 122 int res;
124 123
125 if ((res = tipc_net_start(addr)) || 124 if ((res = tipc_net_start(addr)) ||
126 (res = tipc_eth_media_start())) { 125 (res = tipc_eth_media_start())) {
127 tipc_core_stop_net(); 126 tipc_core_stop_net();
128 } 127 }
129 return res; 128 return res;
130 } 129 }
131 130
132 /** 131 /**
133 * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode 132 * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
134 */ 133 */
135 134
136 static void tipc_core_stop(void) 135 static void tipc_core_stop(void)
137 { 136 {
138 if (tipc_mode != TIPC_NODE_MODE) 137 if (tipc_mode != TIPC_NODE_MODE)
139 return; 138 return;
140 139
141 tipc_mode = TIPC_NOT_RUNNING; 140 tipc_mode = TIPC_NOT_RUNNING;
142 141
143 tipc_netlink_stop(); 142 tipc_netlink_stop();
144 tipc_handler_stop(); 143 tipc_handler_stop();
145 tipc_cfg_stop(); 144 tipc_cfg_stop();
146 tipc_subscr_stop(); 145 tipc_subscr_stop();
147 tipc_reg_stop();
148 tipc_nametbl_stop(); 146 tipc_nametbl_stop();
149 tipc_ref_table_stop(); 147 tipc_ref_table_stop();
150 tipc_socket_stop(); 148 tipc_socket_stop();
151 tipc_log_resize(0); 149 tipc_log_resize(0);
152 } 150 }
153 151
154 /** 152 /**
155 * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode 153 * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
156 */ 154 */
157 155
158 static int tipc_core_start(void) 156 static int tipc_core_start(void)
159 { 157 {
160 int res; 158 int res;
161 159
162 if (tipc_mode != TIPC_NOT_RUNNING) 160 if (tipc_mode != TIPC_NOT_RUNNING)
163 return -ENOPROTOOPT; 161 return -ENOPROTOOPT;
164 162
165 get_random_bytes(&tipc_random, sizeof(tipc_random)); 163 get_random_bytes(&tipc_random, sizeof(tipc_random));
166 tipc_mode = TIPC_NODE_MODE; 164 tipc_mode = TIPC_NODE_MODE;
167 165
168 if ((res = tipc_handler_start()) || 166 if ((res = tipc_handler_start()) ||
169 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) || 167 (res = tipc_ref_table_init(tipc_max_ports, tipc_random)) ||
170 (res = tipc_reg_start()) ||
171 (res = tipc_nametbl_init()) || 168 (res = tipc_nametbl_init()) ||
172 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) || 169 (res = tipc_k_signal((Handler)tipc_subscr_start, 0)) ||
173 (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) || 170 (res = tipc_k_signal((Handler)tipc_cfg_init, 0)) ||
174 (res = tipc_netlink_start()) || 171 (res = tipc_netlink_start()) ||
175 (res = tipc_socket_init())) { 172 (res = tipc_socket_init())) {
176 tipc_core_stop(); 173 tipc_core_stop();
177 } 174 }
178 return res; 175 return res;
179 } 176 }
180 177
181 178
182 static int __init tipc_init(void) 179 static int __init tipc_init(void)
183 { 180 {
184 int res; 181 int res;
185 182
186 if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) 183 if (tipc_log_resize(CONFIG_TIPC_LOG) != 0)
187 warn("Unable to create log buffer\n"); 184 warn("Unable to create log buffer\n");
188 185
189 info("Activated (version " TIPC_MOD_VER 186 info("Activated (version " TIPC_MOD_VER
190 " compiled " __DATE__ " " __TIME__ ")\n"); 187 " compiled " __DATE__ " " __TIME__ ")\n");
191 188
192 tipc_own_addr = 0; 189 tipc_own_addr = 0;
193 tipc_remote_management = 1; 190 tipc_remote_management = 1;
194 tipc_max_publications = 10000; 191 tipc_max_publications = 10000;
195 tipc_max_subscriptions = 2000; 192 tipc_max_subscriptions = 2000;
196 tipc_max_ports = CONFIG_TIPC_PORTS; 193 tipc_max_ports = CONFIG_TIPC_PORTS;
197 tipc_max_nodes = CONFIG_TIPC_NODES; 194 tipc_max_nodes = CONFIG_TIPC_NODES;
198 tipc_net_id = 4711; 195 tipc_net_id = 4711;
199 196
200 if ((res = tipc_core_start())) 197 if ((res = tipc_core_start()))
201 err("Unable to start in single node mode\n"); 198 err("Unable to start in single node mode\n");
202 else 199 else
203 info("Started in single node mode\n"); 200 info("Started in single node mode\n");
204 return res; 201 return res;
205 } 202 }
206 203
207 static void __exit tipc_exit(void) 204 static void __exit tipc_exit(void)
208 { 205 {
209 tipc_core_stop_net(); 206 tipc_core_stop_net();
210 tipc_core_stop(); 207 tipc_core_stop();
211 info("Deactivated\n"); 208 info("Deactivated\n");
212 } 209 }
213 210
214 module_init(tipc_init); 211 module_init(tipc_init);
215 module_exit(tipc_exit); 212 module_exit(tipc_exit);
216 213
217 MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication"); 214 MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication");
218 MODULE_LICENSE("Dual BSD/GPL"); 215 MODULE_LICENSE("Dual BSD/GPL");
219 MODULE_VERSION(TIPC_MOD_VER); 216 MODULE_VERSION(TIPC_MOD_VER);
220 217
1 /* 1 /*
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2007, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2008, Wind River Systems 5 * Copyright (c) 2004-2008, 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
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #include "core.h" 37 #include "core.h"
38 #include "config.h" 38 #include "config.h"
39 #include "port.h" 39 #include "port.h"
40 #include "name_table.h" 40 #include "name_table.h"
41 #include "user_reg.h"
42 41
43 /* Connection management: */ 42 /* Connection management: */
44 #define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ 43 #define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
45 #define CONFIRMED 0 44 #define CONFIRMED 0
46 #define PROBING 1 45 #define PROBING 1
47 46
48 #define MAX_REJECT_SIZE 1024 47 #define MAX_REJECT_SIZE 1024
49 48
50 static struct sk_buff *msg_queue_head = NULL; 49 static struct sk_buff *msg_queue_head = NULL;
51 static struct sk_buff *msg_queue_tail = NULL; 50 static struct sk_buff *msg_queue_tail = NULL;
52 51
53 DEFINE_SPINLOCK(tipc_port_list_lock); 52 DEFINE_SPINLOCK(tipc_port_list_lock);
54 static DEFINE_SPINLOCK(queue_lock); 53 static DEFINE_SPINLOCK(queue_lock);
55 54
56 static LIST_HEAD(ports); 55 static LIST_HEAD(ports);
57 static void port_handle_node_down(unsigned long ref); 56 static void port_handle_node_down(unsigned long ref);
58 static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err); 57 static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err);
59 static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err); 58 static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err);
60 static void port_timeout(unsigned long ref); 59 static void port_timeout(unsigned long ref);
61 60
62 61
63 static u32 port_peernode(struct port *p_ptr) 62 static u32 port_peernode(struct port *p_ptr)
64 { 63 {
65 return msg_destnode(&p_ptr->publ.phdr); 64 return msg_destnode(&p_ptr->publ.phdr);
66 } 65 }
67 66
68 static u32 port_peerport(struct port *p_ptr) 67 static u32 port_peerport(struct port *p_ptr)
69 { 68 {
70 return msg_destport(&p_ptr->publ.phdr); 69 return msg_destport(&p_ptr->publ.phdr);
71 } 70 }
72 71
73 static u32 port_out_seqno(struct port *p_ptr) 72 static u32 port_out_seqno(struct port *p_ptr)
74 { 73 {
75 return msg_transp_seqno(&p_ptr->publ.phdr); 74 return msg_transp_seqno(&p_ptr->publ.phdr);
76 } 75 }
77 76
78 static void port_incr_out_seqno(struct port *p_ptr) 77 static void port_incr_out_seqno(struct port *p_ptr)
79 { 78 {
80 struct tipc_msg *m = &p_ptr->publ.phdr; 79 struct tipc_msg *m = &p_ptr->publ.phdr;
81 80
82 if (likely(!msg_routed(m))) 81 if (likely(!msg_routed(m)))
83 return; 82 return;
84 msg_set_transp_seqno(m, (msg_transp_seqno(m) + 1)); 83 msg_set_transp_seqno(m, (msg_transp_seqno(m) + 1));
85 } 84 }
86 85
87 /** 86 /**
88 * tipc_multicast - send a multicast message to local and remote destinations 87 * tipc_multicast - send a multicast message to local and remote destinations
89 */ 88 */
90 89
91 int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, 90 int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
92 u32 num_sect, struct iovec const *msg_sect) 91 u32 num_sect, struct iovec const *msg_sect)
93 { 92 {
94 struct tipc_msg *hdr; 93 struct tipc_msg *hdr;
95 struct sk_buff *buf; 94 struct sk_buff *buf;
96 struct sk_buff *ibuf = NULL; 95 struct sk_buff *ibuf = NULL;
97 struct port_list dports = {0, NULL, }; 96 struct port_list dports = {0, NULL, };
98 struct port *oport = tipc_port_deref(ref); 97 struct port *oport = tipc_port_deref(ref);
99 int ext_targets; 98 int ext_targets;
100 int res; 99 int res;
101 100
102 if (unlikely(!oport)) 101 if (unlikely(!oport))
103 return -EINVAL; 102 return -EINVAL;
104 103
105 /* Create multicast message */ 104 /* Create multicast message */
106 105
107 hdr = &oport->publ.phdr; 106 hdr = &oport->publ.phdr;
108 msg_set_type(hdr, TIPC_MCAST_MSG); 107 msg_set_type(hdr, TIPC_MCAST_MSG);
109 msg_set_nametype(hdr, seq->type); 108 msg_set_nametype(hdr, seq->type);
110 msg_set_namelower(hdr, seq->lower); 109 msg_set_namelower(hdr, seq->lower);
111 msg_set_nameupper(hdr, seq->upper); 110 msg_set_nameupper(hdr, seq->upper);
112 msg_set_hdr_sz(hdr, MCAST_H_SIZE); 111 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
113 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, 112 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
114 !oport->user_port, &buf); 113 !oport->user_port, &buf);
115 if (unlikely(!buf)) 114 if (unlikely(!buf))
116 return res; 115 return res;
117 116
118 /* Figure out where to send multicast message */ 117 /* Figure out where to send multicast message */
119 118
120 ext_targets = tipc_nametbl_mc_translate(seq->type, seq->lower, seq->upper, 119 ext_targets = tipc_nametbl_mc_translate(seq->type, seq->lower, seq->upper,
121 TIPC_NODE_SCOPE, &dports); 120 TIPC_NODE_SCOPE, &dports);
122 121
123 /* Send message to destinations (duplicate it only if necessary) */ 122 /* Send message to destinations (duplicate it only if necessary) */
124 123
125 if (ext_targets) { 124 if (ext_targets) {
126 if (dports.count != 0) { 125 if (dports.count != 0) {
127 ibuf = skb_copy(buf, GFP_ATOMIC); 126 ibuf = skb_copy(buf, GFP_ATOMIC);
128 if (ibuf == NULL) { 127 if (ibuf == NULL) {
129 tipc_port_list_free(&dports); 128 tipc_port_list_free(&dports);
130 buf_discard(buf); 129 buf_discard(buf);
131 return -ENOMEM; 130 return -ENOMEM;
132 } 131 }
133 } 132 }
134 res = tipc_bclink_send_msg(buf); 133 res = tipc_bclink_send_msg(buf);
135 if ((res < 0) && (dports.count != 0)) { 134 if ((res < 0) && (dports.count != 0)) {
136 buf_discard(ibuf); 135 buf_discard(ibuf);
137 } 136 }
138 } else { 137 } else {
139 ibuf = buf; 138 ibuf = buf;
140 } 139 }
141 140
142 if (res >= 0) { 141 if (res >= 0) {
143 if (ibuf) 142 if (ibuf)
144 tipc_port_recv_mcast(ibuf, &dports); 143 tipc_port_recv_mcast(ibuf, &dports);
145 } else { 144 } else {
146 tipc_port_list_free(&dports); 145 tipc_port_list_free(&dports);
147 } 146 }
148 return res; 147 return res;
149 } 148 }
150 149
151 /** 150 /**
152 * tipc_port_recv_mcast - deliver multicast message to all destination ports 151 * tipc_port_recv_mcast - deliver multicast message to all destination ports
153 * 152 *
154 * If there is no port list, perform a lookup to create one 153 * If there is no port list, perform a lookup to create one
155 */ 154 */
156 155
157 void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp) 156 void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp)
158 { 157 {
159 struct tipc_msg* msg; 158 struct tipc_msg* msg;
160 struct port_list dports = {0, NULL, }; 159 struct port_list dports = {0, NULL, };
161 struct port_list *item = dp; 160 struct port_list *item = dp;
162 int cnt = 0; 161 int cnt = 0;
163 162
164 msg = buf_msg(buf); 163 msg = buf_msg(buf);
165 164
166 /* Create destination port list, if one wasn't supplied */ 165 /* Create destination port list, if one wasn't supplied */
167 166
168 if (dp == NULL) { 167 if (dp == NULL) {
169 tipc_nametbl_mc_translate(msg_nametype(msg), 168 tipc_nametbl_mc_translate(msg_nametype(msg),
170 msg_namelower(msg), 169 msg_namelower(msg),
171 msg_nameupper(msg), 170 msg_nameupper(msg),
172 TIPC_CLUSTER_SCOPE, 171 TIPC_CLUSTER_SCOPE,
173 &dports); 172 &dports);
174 item = dp = &dports; 173 item = dp = &dports;
175 } 174 }
176 175
177 /* Deliver a copy of message to each destination port */ 176 /* Deliver a copy of message to each destination port */
178 177
179 if (dp->count != 0) { 178 if (dp->count != 0) {
180 if (dp->count == 1) { 179 if (dp->count == 1) {
181 msg_set_destport(msg, dp->ports[0]); 180 msg_set_destport(msg, dp->ports[0]);
182 tipc_port_recv_msg(buf); 181 tipc_port_recv_msg(buf);
183 tipc_port_list_free(dp); 182 tipc_port_list_free(dp);
184 return; 183 return;
185 } 184 }
186 for (; cnt < dp->count; cnt++) { 185 for (; cnt < dp->count; cnt++) {
187 int index = cnt % PLSIZE; 186 int index = cnt % PLSIZE;
188 struct sk_buff *b = skb_clone(buf, GFP_ATOMIC); 187 struct sk_buff *b = skb_clone(buf, GFP_ATOMIC);
189 188
190 if (b == NULL) { 189 if (b == NULL) {
191 warn("Unable to deliver multicast message(s)\n"); 190 warn("Unable to deliver multicast message(s)\n");
192 msg_dbg(msg, "LOST:"); 191 msg_dbg(msg, "LOST:");
193 goto exit; 192 goto exit;
194 } 193 }
195 if ((index == 0) && (cnt != 0)) { 194 if ((index == 0) && (cnt != 0)) {
196 item = item->next; 195 item = item->next;
197 } 196 }
198 msg_set_destport(buf_msg(b),item->ports[index]); 197 msg_set_destport(buf_msg(b),item->ports[index]);
199 tipc_port_recv_msg(b); 198 tipc_port_recv_msg(b);
200 } 199 }
201 } 200 }
202 exit: 201 exit:
203 buf_discard(buf); 202 buf_discard(buf);
204 tipc_port_list_free(dp); 203 tipc_port_list_free(dp);
205 } 204 }
206 205
207 /** 206 /**
208 * tipc_createport_raw - create a generic TIPC port 207 * tipc_createport_raw - create a generic TIPC port
209 * 208 *
210 * Returns pointer to (locked) TIPC port, or NULL if unable to create it 209 * Returns pointer to (locked) TIPC port, or NULL if unable to create it
211 */ 210 */
212 211
213 struct tipc_port *tipc_createport_raw(void *usr_handle, 212 struct tipc_port *tipc_createport_raw(void *usr_handle,
214 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 213 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
215 void (*wakeup)(struct tipc_port *), 214 void (*wakeup)(struct tipc_port *),
216 const u32 importance) 215 const u32 importance)
217 { 216 {
218 struct port *p_ptr; 217 struct port *p_ptr;
219 struct tipc_msg *msg; 218 struct tipc_msg *msg;
220 u32 ref; 219 u32 ref;
221 220
222 p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); 221 p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC);
223 if (!p_ptr) { 222 if (!p_ptr) {
224 warn("Port creation failed, no memory\n"); 223 warn("Port creation failed, no memory\n");
225 return NULL; 224 return NULL;
226 } 225 }
227 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); 226 ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock);
228 if (!ref) { 227 if (!ref) {
229 warn("Port creation failed, reference table exhausted\n"); 228 warn("Port creation failed, reference table exhausted\n");
230 kfree(p_ptr); 229 kfree(p_ptr);
231 return NULL; 230 return NULL;
232 } 231 }
233 232
234 p_ptr->publ.usr_handle = usr_handle; 233 p_ptr->publ.usr_handle = usr_handle;
235 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT; 234 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
236 p_ptr->publ.ref = ref; 235 p_ptr->publ.ref = ref;
237 msg = &p_ptr->publ.phdr; 236 msg = &p_ptr->publ.phdr;
238 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 237 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
239 msg_set_origport(msg, ref); 238 msg_set_origport(msg, ref);
240 p_ptr->last_in_seqno = 41; 239 p_ptr->last_in_seqno = 41;
241 p_ptr->sent = 1; 240 p_ptr->sent = 1;
242 INIT_LIST_HEAD(&p_ptr->wait_list); 241 INIT_LIST_HEAD(&p_ptr->wait_list);
243 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 242 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
244 p_ptr->dispatcher = dispatcher; 243 p_ptr->dispatcher = dispatcher;
245 p_ptr->wakeup = wakeup; 244 p_ptr->wakeup = wakeup;
246 p_ptr->user_port = NULL; 245 p_ptr->user_port = NULL;
247 k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref); 246 k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);
248 spin_lock_bh(&tipc_port_list_lock); 247 spin_lock_bh(&tipc_port_list_lock);
249 INIT_LIST_HEAD(&p_ptr->publications); 248 INIT_LIST_HEAD(&p_ptr->publications);
250 INIT_LIST_HEAD(&p_ptr->port_list); 249 INIT_LIST_HEAD(&p_ptr->port_list);
251 list_add_tail(&p_ptr->port_list, &ports); 250 list_add_tail(&p_ptr->port_list, &ports);
252 spin_unlock_bh(&tipc_port_list_lock); 251 spin_unlock_bh(&tipc_port_list_lock);
253 return &(p_ptr->publ); 252 return &(p_ptr->publ);
254 } 253 }
255 254
256 int tipc_deleteport(u32 ref) 255 int tipc_deleteport(u32 ref)
257 { 256 {
258 struct port *p_ptr; 257 struct port *p_ptr;
259 struct sk_buff *buf = NULL; 258 struct sk_buff *buf = NULL;
260 259
261 tipc_withdraw(ref, 0, NULL); 260 tipc_withdraw(ref, 0, NULL);
262 p_ptr = tipc_port_lock(ref); 261 p_ptr = tipc_port_lock(ref);
263 if (!p_ptr) 262 if (!p_ptr)
264 return -EINVAL; 263 return -EINVAL;
265 264
266 tipc_ref_discard(ref); 265 tipc_ref_discard(ref);
267 tipc_port_unlock(p_ptr); 266 tipc_port_unlock(p_ptr);
268 267
269 k_cancel_timer(&p_ptr->timer); 268 k_cancel_timer(&p_ptr->timer);
270 if (p_ptr->publ.connected) { 269 if (p_ptr->publ.connected) {
271 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 270 buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
272 tipc_nodesub_unsubscribe(&p_ptr->subscription); 271 tipc_nodesub_unsubscribe(&p_ptr->subscription);
273 } 272 }
274 if (p_ptr->user_port) { 273 if (p_ptr->user_port) {
275 tipc_reg_remove_port(p_ptr->user_port);
276 kfree(p_ptr->user_port); 274 kfree(p_ptr->user_port);
277 } 275 }
278 276
279 spin_lock_bh(&tipc_port_list_lock); 277 spin_lock_bh(&tipc_port_list_lock);
280 list_del(&p_ptr->port_list); 278 list_del(&p_ptr->port_list);
281 list_del(&p_ptr->wait_list); 279 list_del(&p_ptr->wait_list);
282 spin_unlock_bh(&tipc_port_list_lock); 280 spin_unlock_bh(&tipc_port_list_lock);
283 k_term_timer(&p_ptr->timer); 281 k_term_timer(&p_ptr->timer);
284 kfree(p_ptr); 282 kfree(p_ptr);
285 dbg("Deleted port %u\n", ref); 283 dbg("Deleted port %u\n", ref);
286 tipc_net_route_msg(buf); 284 tipc_net_route_msg(buf);
287 return 0; 285 return 0;
288 } 286 }
289 287
290 static int port_unreliable(struct port *p_ptr) 288 static int port_unreliable(struct port *p_ptr)
291 { 289 {
292 return msg_src_droppable(&p_ptr->publ.phdr); 290 return msg_src_droppable(&p_ptr->publ.phdr);
293 } 291 }
294 292
295 int tipc_portunreliable(u32 ref, unsigned int *isunreliable) 293 int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
296 { 294 {
297 struct port *p_ptr; 295 struct port *p_ptr;
298 296
299 p_ptr = tipc_port_lock(ref); 297 p_ptr = tipc_port_lock(ref);
300 if (!p_ptr) 298 if (!p_ptr)
301 return -EINVAL; 299 return -EINVAL;
302 *isunreliable = port_unreliable(p_ptr); 300 *isunreliable = port_unreliable(p_ptr);
303 tipc_port_unlock(p_ptr); 301 tipc_port_unlock(p_ptr);
304 return 0; 302 return 0;
305 } 303 }
306 304
307 int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) 305 int tipc_set_portunreliable(u32 ref, unsigned int isunreliable)
308 { 306 {
309 struct port *p_ptr; 307 struct port *p_ptr;
310 308
311 p_ptr = tipc_port_lock(ref); 309 p_ptr = tipc_port_lock(ref);
312 if (!p_ptr) 310 if (!p_ptr)
313 return -EINVAL; 311 return -EINVAL;
314 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); 312 msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0));
315 tipc_port_unlock(p_ptr); 313 tipc_port_unlock(p_ptr);
316 return 0; 314 return 0;
317 } 315 }
318 316
319 static int port_unreturnable(struct port *p_ptr) 317 static int port_unreturnable(struct port *p_ptr)
320 { 318 {
321 return msg_dest_droppable(&p_ptr->publ.phdr); 319 return msg_dest_droppable(&p_ptr->publ.phdr);
322 } 320 }
323 321
324 int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) 322 int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
325 { 323 {
326 struct port *p_ptr; 324 struct port *p_ptr;
327 325
328 p_ptr = tipc_port_lock(ref); 326 p_ptr = tipc_port_lock(ref);
329 if (!p_ptr) 327 if (!p_ptr)
330 return -EINVAL; 328 return -EINVAL;
331 *isunrejectable = port_unreturnable(p_ptr); 329 *isunrejectable = port_unreturnable(p_ptr);
332 tipc_port_unlock(p_ptr); 330 tipc_port_unlock(p_ptr);
333 return 0; 331 return 0;
334 } 332 }
335 333
336 int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) 334 int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable)
337 { 335 {
338 struct port *p_ptr; 336 struct port *p_ptr;
339 337
340 p_ptr = tipc_port_lock(ref); 338 p_ptr = tipc_port_lock(ref);
341 if (!p_ptr) 339 if (!p_ptr)
342 return -EINVAL; 340 return -EINVAL;
343 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); 341 msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0));
344 tipc_port_unlock(p_ptr); 342 tipc_port_unlock(p_ptr);
345 return 0; 343 return 0;
346 } 344 }
347 345
348 /* 346 /*
349 * port_build_proto_msg(): build a port level protocol 347 * port_build_proto_msg(): build a port level protocol
350 * or a connection abortion message. Called with 348 * or a connection abortion message. Called with
351 * tipc_port lock on. 349 * tipc_port lock on.
352 */ 350 */
353 static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, 351 static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode,
354 u32 origport, u32 orignode, 352 u32 origport, u32 orignode,
355 u32 usr, u32 type, u32 err, 353 u32 usr, u32 type, u32 err,
356 u32 seqno, u32 ack) 354 u32 seqno, u32 ack)
357 { 355 {
358 struct sk_buff *buf; 356 struct sk_buff *buf;
359 struct tipc_msg *msg; 357 struct tipc_msg *msg;
360 358
361 buf = tipc_buf_acquire(LONG_H_SIZE); 359 buf = tipc_buf_acquire(LONG_H_SIZE);
362 if (buf) { 360 if (buf) {
363 msg = buf_msg(buf); 361 msg = buf_msg(buf);
364 tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); 362 tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode);
365 msg_set_errcode(msg, err); 363 msg_set_errcode(msg, err);
366 msg_set_destport(msg, destport); 364 msg_set_destport(msg, destport);
367 msg_set_origport(msg, origport); 365 msg_set_origport(msg, origport);
368 msg_set_orignode(msg, orignode); 366 msg_set_orignode(msg, orignode);
369 msg_set_transp_seqno(msg, seqno); 367 msg_set_transp_seqno(msg, seqno);
370 msg_set_msgcnt(msg, ack); 368 msg_set_msgcnt(msg, ack);
371 msg_dbg(msg, "PORT>SEND>:"); 369 msg_dbg(msg, "PORT>SEND>:");
372 } 370 }
373 return buf; 371 return buf;
374 } 372 }
375 373
376 int tipc_reject_msg(struct sk_buff *buf, u32 err) 374 int tipc_reject_msg(struct sk_buff *buf, u32 err)
377 { 375 {
378 struct tipc_msg *msg = buf_msg(buf); 376 struct tipc_msg *msg = buf_msg(buf);
379 struct sk_buff *rbuf; 377 struct sk_buff *rbuf;
380 struct tipc_msg *rmsg; 378 struct tipc_msg *rmsg;
381 int hdr_sz; 379 int hdr_sz;
382 u32 imp = msg_importance(msg); 380 u32 imp = msg_importance(msg);
383 u32 data_sz = msg_data_sz(msg); 381 u32 data_sz = msg_data_sz(msg);
384 382
385 if (data_sz > MAX_REJECT_SIZE) 383 if (data_sz > MAX_REJECT_SIZE)
386 data_sz = MAX_REJECT_SIZE; 384 data_sz = MAX_REJECT_SIZE;
387 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE)) 385 if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE))
388 imp++; 386 imp++;
389 msg_dbg(msg, "port->rej: "); 387 msg_dbg(msg, "port->rej: ");
390 388
391 /* discard rejected message if it shouldn't be returned to sender */ 389 /* discard rejected message if it shouldn't be returned to sender */
392 if (msg_errcode(msg) || msg_dest_droppable(msg)) { 390 if (msg_errcode(msg) || msg_dest_droppable(msg)) {
393 buf_discard(buf); 391 buf_discard(buf);
394 return data_sz; 392 return data_sz;
395 } 393 }
396 394
397 /* construct rejected message */ 395 /* construct rejected message */
398 if (msg_mcast(msg)) 396 if (msg_mcast(msg))
399 hdr_sz = MCAST_H_SIZE; 397 hdr_sz = MCAST_H_SIZE;
400 else 398 else
401 hdr_sz = LONG_H_SIZE; 399 hdr_sz = LONG_H_SIZE;
402 rbuf = tipc_buf_acquire(data_sz + hdr_sz); 400 rbuf = tipc_buf_acquire(data_sz + hdr_sz);
403 if (rbuf == NULL) { 401 if (rbuf == NULL) {
404 buf_discard(buf); 402 buf_discard(buf);
405 return data_sz; 403 return data_sz;
406 } 404 }
407 rmsg = buf_msg(rbuf); 405 rmsg = buf_msg(rbuf);
408 tipc_msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg)); 406 tipc_msg_init(rmsg, imp, msg_type(msg), hdr_sz, msg_orignode(msg));
409 msg_set_errcode(rmsg, err); 407 msg_set_errcode(rmsg, err);
410 msg_set_destport(rmsg, msg_origport(msg)); 408 msg_set_destport(rmsg, msg_origport(msg));
411 msg_set_origport(rmsg, msg_destport(msg)); 409 msg_set_origport(rmsg, msg_destport(msg));
412 if (msg_short(msg)) { 410 if (msg_short(msg)) {
413 msg_set_orignode(rmsg, tipc_own_addr); 411 msg_set_orignode(rmsg, tipc_own_addr);
414 /* leave name type & instance as zeroes */ 412 /* leave name type & instance as zeroes */
415 } else { 413 } else {
416 msg_set_orignode(rmsg, msg_destnode(msg)); 414 msg_set_orignode(rmsg, msg_destnode(msg));
417 msg_set_nametype(rmsg, msg_nametype(msg)); 415 msg_set_nametype(rmsg, msg_nametype(msg));
418 msg_set_nameinst(rmsg, msg_nameinst(msg)); 416 msg_set_nameinst(rmsg, msg_nameinst(msg));
419 } 417 }
420 msg_set_size(rmsg, data_sz + hdr_sz); 418 msg_set_size(rmsg, data_sz + hdr_sz);
421 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz); 419 skb_copy_to_linear_data_offset(rbuf, hdr_sz, msg_data(msg), data_sz);
422 420
423 /* send self-abort message when rejecting on a connected port */ 421 /* send self-abort message when rejecting on a connected port */
424 if (msg_connected(msg)) { 422 if (msg_connected(msg)) {
425 struct sk_buff *abuf = NULL; 423 struct sk_buff *abuf = NULL;
426 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 424 struct port *p_ptr = tipc_port_lock(msg_destport(msg));
427 425
428 if (p_ptr) { 426 if (p_ptr) {
429 if (p_ptr->publ.connected) 427 if (p_ptr->publ.connected)
430 abuf = port_build_self_abort_msg(p_ptr, err); 428 abuf = port_build_self_abort_msg(p_ptr, err);
431 tipc_port_unlock(p_ptr); 429 tipc_port_unlock(p_ptr);
432 } 430 }
433 tipc_net_route_msg(abuf); 431 tipc_net_route_msg(abuf);
434 } 432 }
435 433
436 /* send rejected message */ 434 /* send rejected message */
437 buf_discard(buf); 435 buf_discard(buf);
438 tipc_net_route_msg(rbuf); 436 tipc_net_route_msg(rbuf);
439 return data_sz; 437 return data_sz;
440 } 438 }
441 439
442 int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 440 int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
443 struct iovec const *msg_sect, u32 num_sect, 441 struct iovec const *msg_sect, u32 num_sect,
444 int err) 442 int err)
445 { 443 {
446 struct sk_buff *buf; 444 struct sk_buff *buf;
447 int res; 445 int res;
448 446
449 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, 447 res = tipc_msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE,
450 !p_ptr->user_port, &buf); 448 !p_ptr->user_port, &buf);
451 if (!buf) 449 if (!buf)
452 return res; 450 return res;
453 451
454 return tipc_reject_msg(buf, err); 452 return tipc_reject_msg(buf, err);
455 } 453 }
456 454
457 static void port_timeout(unsigned long ref) 455 static void port_timeout(unsigned long ref)
458 { 456 {
459 struct port *p_ptr = tipc_port_lock(ref); 457 struct port *p_ptr = tipc_port_lock(ref);
460 struct sk_buff *buf = NULL; 458 struct sk_buff *buf = NULL;
461 459
462 if (!p_ptr) 460 if (!p_ptr)
463 return; 461 return;
464 462
465 if (!p_ptr->publ.connected) { 463 if (!p_ptr->publ.connected) {
466 tipc_port_unlock(p_ptr); 464 tipc_port_unlock(p_ptr);
467 return; 465 return;
468 } 466 }
469 467
470 /* Last probe answered ? */ 468 /* Last probe answered ? */
471 if (p_ptr->probing_state == PROBING) { 469 if (p_ptr->probing_state == PROBING) {
472 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT); 470 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
473 } else { 471 } else {
474 buf = port_build_proto_msg(port_peerport(p_ptr), 472 buf = port_build_proto_msg(port_peerport(p_ptr),
475 port_peernode(p_ptr), 473 port_peernode(p_ptr),
476 p_ptr->publ.ref, 474 p_ptr->publ.ref,
477 tipc_own_addr, 475 tipc_own_addr,
478 CONN_MANAGER, 476 CONN_MANAGER,
479 CONN_PROBE, 477 CONN_PROBE,
480 TIPC_OK, 478 TIPC_OK,
481 port_out_seqno(p_ptr), 479 port_out_seqno(p_ptr),
482 0); 480 0);
483 port_incr_out_seqno(p_ptr); 481 port_incr_out_seqno(p_ptr);
484 p_ptr->probing_state = PROBING; 482 p_ptr->probing_state = PROBING;
485 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 483 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
486 } 484 }
487 tipc_port_unlock(p_ptr); 485 tipc_port_unlock(p_ptr);
488 tipc_net_route_msg(buf); 486 tipc_net_route_msg(buf);
489 } 487 }
490 488
491 489
492 static void port_handle_node_down(unsigned long ref) 490 static void port_handle_node_down(unsigned long ref)
493 { 491 {
494 struct port *p_ptr = tipc_port_lock(ref); 492 struct port *p_ptr = tipc_port_lock(ref);
495 struct sk_buff* buf = NULL; 493 struct sk_buff* buf = NULL;
496 494
497 if (!p_ptr) 495 if (!p_ptr)
498 return; 496 return;
499 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE); 497 buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE);
500 tipc_port_unlock(p_ptr); 498 tipc_port_unlock(p_ptr);
501 tipc_net_route_msg(buf); 499 tipc_net_route_msg(buf);
502 } 500 }
503 501
504 502
505 static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err) 503 static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err)
506 { 504 {
507 u32 imp = msg_importance(&p_ptr->publ.phdr); 505 u32 imp = msg_importance(&p_ptr->publ.phdr);
508 506
509 if (!p_ptr->publ.connected) 507 if (!p_ptr->publ.connected)
510 return NULL; 508 return NULL;
511 if (imp < TIPC_CRITICAL_IMPORTANCE) 509 if (imp < TIPC_CRITICAL_IMPORTANCE)
512 imp++; 510 imp++;
513 return port_build_proto_msg(p_ptr->publ.ref, 511 return port_build_proto_msg(p_ptr->publ.ref,
514 tipc_own_addr, 512 tipc_own_addr,
515 port_peerport(p_ptr), 513 port_peerport(p_ptr),
516 port_peernode(p_ptr), 514 port_peernode(p_ptr),
517 imp, 515 imp,
518 TIPC_CONN_MSG, 516 TIPC_CONN_MSG,
519 err, 517 err,
520 p_ptr->last_in_seqno + 1, 518 p_ptr->last_in_seqno + 1,
521 0); 519 0);
522 } 520 }
523 521
524 522
525 static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err) 523 static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err)
526 { 524 {
527 u32 imp = msg_importance(&p_ptr->publ.phdr); 525 u32 imp = msg_importance(&p_ptr->publ.phdr);
528 526
529 if (!p_ptr->publ.connected) 527 if (!p_ptr->publ.connected)
530 return NULL; 528 return NULL;
531 if (imp < TIPC_CRITICAL_IMPORTANCE) 529 if (imp < TIPC_CRITICAL_IMPORTANCE)
532 imp++; 530 imp++;
533 return port_build_proto_msg(port_peerport(p_ptr), 531 return port_build_proto_msg(port_peerport(p_ptr),
534 port_peernode(p_ptr), 532 port_peernode(p_ptr),
535 p_ptr->publ.ref, 533 p_ptr->publ.ref,
536 tipc_own_addr, 534 tipc_own_addr,
537 imp, 535 imp,
538 TIPC_CONN_MSG, 536 TIPC_CONN_MSG,
539 err, 537 err,
540 port_out_seqno(p_ptr), 538 port_out_seqno(p_ptr),
541 0); 539 0);
542 } 540 }
543 541
544 void tipc_port_recv_proto_msg(struct sk_buff *buf) 542 void tipc_port_recv_proto_msg(struct sk_buff *buf)
545 { 543 {
546 struct tipc_msg *msg = buf_msg(buf); 544 struct tipc_msg *msg = buf_msg(buf);
547 struct port *p_ptr = tipc_port_lock(msg_destport(msg)); 545 struct port *p_ptr = tipc_port_lock(msg_destport(msg));
548 u32 err = TIPC_OK; 546 u32 err = TIPC_OK;
549 struct sk_buff *r_buf = NULL; 547 struct sk_buff *r_buf = NULL;
550 struct sk_buff *abort_buf = NULL; 548 struct sk_buff *abort_buf = NULL;
551 549
552 msg_dbg(msg, "PORT<RECV<:"); 550 msg_dbg(msg, "PORT<RECV<:");
553 551
554 if (!p_ptr) { 552 if (!p_ptr) {
555 err = TIPC_ERR_NO_PORT; 553 err = TIPC_ERR_NO_PORT;
556 } else if (p_ptr->publ.connected) { 554 } else if (p_ptr->publ.connected) {
557 if ((port_peernode(p_ptr) != msg_orignode(msg)) || 555 if ((port_peernode(p_ptr) != msg_orignode(msg)) ||
558 (port_peerport(p_ptr) != msg_origport(msg))) { 556 (port_peerport(p_ptr) != msg_origport(msg))) {
559 err = TIPC_ERR_NO_PORT; 557 err = TIPC_ERR_NO_PORT;
560 } else if (msg_type(msg) == CONN_ACK) { 558 } else if (msg_type(msg) == CONN_ACK) {
561 int wakeup = tipc_port_congested(p_ptr) && 559 int wakeup = tipc_port_congested(p_ptr) &&
562 p_ptr->publ.congested && 560 p_ptr->publ.congested &&
563 p_ptr->wakeup; 561 p_ptr->wakeup;
564 p_ptr->acked += msg_msgcnt(msg); 562 p_ptr->acked += msg_msgcnt(msg);
565 if (tipc_port_congested(p_ptr)) 563 if (tipc_port_congested(p_ptr))
566 goto exit; 564 goto exit;
567 p_ptr->publ.congested = 0; 565 p_ptr->publ.congested = 0;
568 if (!wakeup) 566 if (!wakeup)
569 goto exit; 567 goto exit;
570 p_ptr->wakeup(&p_ptr->publ); 568 p_ptr->wakeup(&p_ptr->publ);
571 goto exit; 569 goto exit;
572 } 570 }
573 } else if (p_ptr->publ.published) { 571 } else if (p_ptr->publ.published) {
574 err = TIPC_ERR_NO_PORT; 572 err = TIPC_ERR_NO_PORT;
575 } 573 }
576 if (err) { 574 if (err) {
577 r_buf = port_build_proto_msg(msg_origport(msg), 575 r_buf = port_build_proto_msg(msg_origport(msg),
578 msg_orignode(msg), 576 msg_orignode(msg),
579 msg_destport(msg), 577 msg_destport(msg),
580 tipc_own_addr, 578 tipc_own_addr,
581 TIPC_HIGH_IMPORTANCE, 579 TIPC_HIGH_IMPORTANCE,
582 TIPC_CONN_MSG, 580 TIPC_CONN_MSG,
583 err, 581 err,
584 0, 582 0,
585 0); 583 0);
586 goto exit; 584 goto exit;
587 } 585 }
588 586
589 /* All is fine */ 587 /* All is fine */
590 if (msg_type(msg) == CONN_PROBE) { 588 if (msg_type(msg) == CONN_PROBE) {
591 r_buf = port_build_proto_msg(msg_origport(msg), 589 r_buf = port_build_proto_msg(msg_origport(msg),
592 msg_orignode(msg), 590 msg_orignode(msg),
593 msg_destport(msg), 591 msg_destport(msg),
594 tipc_own_addr, 592 tipc_own_addr,
595 CONN_MANAGER, 593 CONN_MANAGER,
596 CONN_PROBE_REPLY, 594 CONN_PROBE_REPLY,
597 TIPC_OK, 595 TIPC_OK,
598 port_out_seqno(p_ptr), 596 port_out_seqno(p_ptr),
599 0); 597 0);
600 } 598 }
601 p_ptr->probing_state = CONFIRMED; 599 p_ptr->probing_state = CONFIRMED;
602 port_incr_out_seqno(p_ptr); 600 port_incr_out_seqno(p_ptr);
603 exit: 601 exit:
604 if (p_ptr) 602 if (p_ptr)
605 tipc_port_unlock(p_ptr); 603 tipc_port_unlock(p_ptr);
606 tipc_net_route_msg(r_buf); 604 tipc_net_route_msg(r_buf);
607 tipc_net_route_msg(abort_buf); 605 tipc_net_route_msg(abort_buf);
608 buf_discard(buf); 606 buf_discard(buf);
609 } 607 }
610 608
611 static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) 609 static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id)
612 { 610 {
613 struct publication *publ; 611 struct publication *publ;
614 612
615 if (full_id) 613 if (full_id)
616 tipc_printf(buf, "<%u.%u.%u:%u>:", 614 tipc_printf(buf, "<%u.%u.%u:%u>:",
617 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 615 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
618 tipc_node(tipc_own_addr), p_ptr->publ.ref); 616 tipc_node(tipc_own_addr), p_ptr->publ.ref);
619 else 617 else
620 tipc_printf(buf, "%-10u:", p_ptr->publ.ref); 618 tipc_printf(buf, "%-10u:", p_ptr->publ.ref);
621 619
622 if (p_ptr->publ.connected) { 620 if (p_ptr->publ.connected) {
623 u32 dport = port_peerport(p_ptr); 621 u32 dport = port_peerport(p_ptr);
624 u32 destnode = port_peernode(p_ptr); 622 u32 destnode = port_peernode(p_ptr);
625 623
626 tipc_printf(buf, " connected to <%u.%u.%u:%u>", 624 tipc_printf(buf, " connected to <%u.%u.%u:%u>",
627 tipc_zone(destnode), tipc_cluster(destnode), 625 tipc_zone(destnode), tipc_cluster(destnode),
628 tipc_node(destnode), dport); 626 tipc_node(destnode), dport);
629 if (p_ptr->publ.conn_type != 0) 627 if (p_ptr->publ.conn_type != 0)
630 tipc_printf(buf, " via {%u,%u}", 628 tipc_printf(buf, " via {%u,%u}",
631 p_ptr->publ.conn_type, 629 p_ptr->publ.conn_type,
632 p_ptr->publ.conn_instance); 630 p_ptr->publ.conn_instance);
633 } 631 }
634 else if (p_ptr->publ.published) { 632 else if (p_ptr->publ.published) {
635 tipc_printf(buf, " bound to"); 633 tipc_printf(buf, " bound to");
636 list_for_each_entry(publ, &p_ptr->publications, pport_list) { 634 list_for_each_entry(publ, &p_ptr->publications, pport_list) {
637 if (publ->lower == publ->upper) 635 if (publ->lower == publ->upper)
638 tipc_printf(buf, " {%u,%u}", publ->type, 636 tipc_printf(buf, " {%u,%u}", publ->type,
639 publ->lower); 637 publ->lower);
640 else 638 else
641 tipc_printf(buf, " {%u,%u,%u}", publ->type, 639 tipc_printf(buf, " {%u,%u,%u}", publ->type,
642 publ->lower, publ->upper); 640 publ->lower, publ->upper);
643 } 641 }
644 } 642 }
645 tipc_printf(buf, "\n"); 643 tipc_printf(buf, "\n");
646 } 644 }
647 645
648 #define MAX_PORT_QUERY 32768 646 #define MAX_PORT_QUERY 32768
649 647
650 struct sk_buff *tipc_port_get_ports(void) 648 struct sk_buff *tipc_port_get_ports(void)
651 { 649 {
652 struct sk_buff *buf; 650 struct sk_buff *buf;
653 struct tlv_desc *rep_tlv; 651 struct tlv_desc *rep_tlv;
654 struct print_buf pb; 652 struct print_buf pb;
655 struct port *p_ptr; 653 struct port *p_ptr;
656 int str_len; 654 int str_len;
657 655
658 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); 656 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY));
659 if (!buf) 657 if (!buf)
660 return NULL; 658 return NULL;
661 rep_tlv = (struct tlv_desc *)buf->data; 659 rep_tlv = (struct tlv_desc *)buf->data;
662 660
663 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); 661 tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY);
664 spin_lock_bh(&tipc_port_list_lock); 662 spin_lock_bh(&tipc_port_list_lock);
665 list_for_each_entry(p_ptr, &ports, port_list) { 663 list_for_each_entry(p_ptr, &ports, port_list) {
666 spin_lock_bh(p_ptr->publ.lock); 664 spin_lock_bh(p_ptr->publ.lock);
667 port_print(p_ptr, &pb, 0); 665 port_print(p_ptr, &pb, 0);
668 spin_unlock_bh(p_ptr->publ.lock); 666 spin_unlock_bh(p_ptr->publ.lock);
669 } 667 }
670 spin_unlock_bh(&tipc_port_list_lock); 668 spin_unlock_bh(&tipc_port_list_lock);
671 str_len = tipc_printbuf_validate(&pb); 669 str_len = tipc_printbuf_validate(&pb);
672 670
673 skb_put(buf, TLV_SPACE(str_len)); 671 skb_put(buf, TLV_SPACE(str_len));
674 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 672 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
675 673
676 return buf; 674 return buf;
677 } 675 }
678 676
679 void tipc_port_reinit(void) 677 void tipc_port_reinit(void)
680 { 678 {
681 struct port *p_ptr; 679 struct port *p_ptr;
682 struct tipc_msg *msg; 680 struct tipc_msg *msg;
683 681
684 spin_lock_bh(&tipc_port_list_lock); 682 spin_lock_bh(&tipc_port_list_lock);
685 list_for_each_entry(p_ptr, &ports, port_list) { 683 list_for_each_entry(p_ptr, &ports, port_list) {
686 msg = &p_ptr->publ.phdr; 684 msg = &p_ptr->publ.phdr;
687 if (msg_orignode(msg) == tipc_own_addr) 685 if (msg_orignode(msg) == tipc_own_addr)
688 break; 686 break;
689 msg_set_prevnode(msg, tipc_own_addr); 687 msg_set_prevnode(msg, tipc_own_addr);
690 msg_set_orignode(msg, tipc_own_addr); 688 msg_set_orignode(msg, tipc_own_addr);
691 } 689 }
692 spin_unlock_bh(&tipc_port_list_lock); 690 spin_unlock_bh(&tipc_port_list_lock);
693 } 691 }
694 692
695 693
696 /* 694 /*
697 * port_dispatcher_sigh(): Signal handler for messages destinated 695 * port_dispatcher_sigh(): Signal handler for messages destinated
698 * to the tipc_port interface. 696 * to the tipc_port interface.
699 */ 697 */
700 698
701 static void port_dispatcher_sigh(void *dummy) 699 static void port_dispatcher_sigh(void *dummy)
702 { 700 {
703 struct sk_buff *buf; 701 struct sk_buff *buf;
704 702
705 spin_lock_bh(&queue_lock); 703 spin_lock_bh(&queue_lock);
706 buf = msg_queue_head; 704 buf = msg_queue_head;
707 msg_queue_head = NULL; 705 msg_queue_head = NULL;
708 spin_unlock_bh(&queue_lock); 706 spin_unlock_bh(&queue_lock);
709 707
710 while (buf) { 708 while (buf) {
711 struct port *p_ptr; 709 struct port *p_ptr;
712 struct user_port *up_ptr; 710 struct user_port *up_ptr;
713 struct tipc_portid orig; 711 struct tipc_portid orig;
714 struct tipc_name_seq dseq; 712 struct tipc_name_seq dseq;
715 void *usr_handle; 713 void *usr_handle;
716 int connected; 714 int connected;
717 int published; 715 int published;
718 u32 message_type; 716 u32 message_type;
719 717
720 struct sk_buff *next = buf->next; 718 struct sk_buff *next = buf->next;
721 struct tipc_msg *msg = buf_msg(buf); 719 struct tipc_msg *msg = buf_msg(buf);
722 u32 dref = msg_destport(msg); 720 u32 dref = msg_destport(msg);
723 721
724 message_type = msg_type(msg); 722 message_type = msg_type(msg);
725 if (message_type > TIPC_DIRECT_MSG) 723 if (message_type > TIPC_DIRECT_MSG)
726 goto reject; /* Unsupported message type */ 724 goto reject; /* Unsupported message type */
727 725
728 p_ptr = tipc_port_lock(dref); 726 p_ptr = tipc_port_lock(dref);
729 if (!p_ptr) 727 if (!p_ptr)
730 goto reject; /* Port deleted while msg in queue */ 728 goto reject; /* Port deleted while msg in queue */
731 729
732 orig.ref = msg_origport(msg); 730 orig.ref = msg_origport(msg);
733 orig.node = msg_orignode(msg); 731 orig.node = msg_orignode(msg);
734 up_ptr = p_ptr->user_port; 732 up_ptr = p_ptr->user_port;
735 usr_handle = up_ptr->usr_handle; 733 usr_handle = up_ptr->usr_handle;
736 connected = p_ptr->publ.connected; 734 connected = p_ptr->publ.connected;
737 published = p_ptr->publ.published; 735 published = p_ptr->publ.published;
738 736
739 if (unlikely(msg_errcode(msg))) 737 if (unlikely(msg_errcode(msg)))
740 goto err; 738 goto err;
741 739
742 switch (message_type) { 740 switch (message_type) {
743 741
744 case TIPC_CONN_MSG:{ 742 case TIPC_CONN_MSG:{
745 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 743 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
746 u32 peer_port = port_peerport(p_ptr); 744 u32 peer_port = port_peerport(p_ptr);
747 u32 peer_node = port_peernode(p_ptr); 745 u32 peer_node = port_peernode(p_ptr);
748 746
749 tipc_port_unlock(p_ptr); 747 tipc_port_unlock(p_ptr);
750 if (unlikely(!cb)) 748 if (unlikely(!cb))
751 goto reject; 749 goto reject;
752 if (unlikely(!connected)) { 750 if (unlikely(!connected)) {
753 if (tipc_connect2port(dref, &orig)) 751 if (tipc_connect2port(dref, &orig))
754 goto reject; 752 goto reject;
755 } else if ((msg_origport(msg) != peer_port) || 753 } else if ((msg_origport(msg) != peer_port) ||
756 (msg_orignode(msg) != peer_node)) 754 (msg_orignode(msg) != peer_node))
757 goto reject; 755 goto reject;
758 if (unlikely(++p_ptr->publ.conn_unacked >= 756 if (unlikely(++p_ptr->publ.conn_unacked >=
759 TIPC_FLOW_CONTROL_WIN)) 757 TIPC_FLOW_CONTROL_WIN))
760 tipc_acknowledge(dref, 758 tipc_acknowledge(dref,
761 p_ptr->publ.conn_unacked); 759 p_ptr->publ.conn_unacked);
762 skb_pull(buf, msg_hdr_sz(msg)); 760 skb_pull(buf, msg_hdr_sz(msg));
763 cb(usr_handle, dref, &buf, msg_data(msg), 761 cb(usr_handle, dref, &buf, msg_data(msg),
764 msg_data_sz(msg)); 762 msg_data_sz(msg));
765 break; 763 break;
766 } 764 }
767 case TIPC_DIRECT_MSG:{ 765 case TIPC_DIRECT_MSG:{
768 tipc_msg_event cb = up_ptr->msg_cb; 766 tipc_msg_event cb = up_ptr->msg_cb;
769 767
770 tipc_port_unlock(p_ptr); 768 tipc_port_unlock(p_ptr);
771 if (unlikely(!cb || connected)) 769 if (unlikely(!cb || connected))
772 goto reject; 770 goto reject;
773 skb_pull(buf, msg_hdr_sz(msg)); 771 skb_pull(buf, msg_hdr_sz(msg));
774 cb(usr_handle, dref, &buf, msg_data(msg), 772 cb(usr_handle, dref, &buf, msg_data(msg),
775 msg_data_sz(msg), msg_importance(msg), 773 msg_data_sz(msg), msg_importance(msg),
776 &orig); 774 &orig);
777 break; 775 break;
778 } 776 }
779 case TIPC_MCAST_MSG: 777 case TIPC_MCAST_MSG:
780 case TIPC_NAMED_MSG:{ 778 case TIPC_NAMED_MSG:{
781 tipc_named_msg_event cb = up_ptr->named_msg_cb; 779 tipc_named_msg_event cb = up_ptr->named_msg_cb;
782 780
783 tipc_port_unlock(p_ptr); 781 tipc_port_unlock(p_ptr);
784 if (unlikely(!cb || connected || !published)) 782 if (unlikely(!cb || connected || !published))
785 goto reject; 783 goto reject;
786 dseq.type = msg_nametype(msg); 784 dseq.type = msg_nametype(msg);
787 dseq.lower = msg_nameinst(msg); 785 dseq.lower = msg_nameinst(msg);
788 dseq.upper = (message_type == TIPC_NAMED_MSG) 786 dseq.upper = (message_type == TIPC_NAMED_MSG)
789 ? dseq.lower : msg_nameupper(msg); 787 ? dseq.lower : msg_nameupper(msg);
790 skb_pull(buf, msg_hdr_sz(msg)); 788 skb_pull(buf, msg_hdr_sz(msg));
791 cb(usr_handle, dref, &buf, msg_data(msg), 789 cb(usr_handle, dref, &buf, msg_data(msg),
792 msg_data_sz(msg), msg_importance(msg), 790 msg_data_sz(msg), msg_importance(msg),
793 &orig, &dseq); 791 &orig, &dseq);
794 break; 792 break;
795 } 793 }
796 } 794 }
797 if (buf) 795 if (buf)
798 buf_discard(buf); 796 buf_discard(buf);
799 buf = next; 797 buf = next;
800 continue; 798 continue;
801 err: 799 err:
802 switch (message_type) { 800 switch (message_type) {
803 801
804 case TIPC_CONN_MSG:{ 802 case TIPC_CONN_MSG:{
805 tipc_conn_shutdown_event cb = 803 tipc_conn_shutdown_event cb =
806 up_ptr->conn_err_cb; 804 up_ptr->conn_err_cb;
807 u32 peer_port = port_peerport(p_ptr); 805 u32 peer_port = port_peerport(p_ptr);
808 u32 peer_node = port_peernode(p_ptr); 806 u32 peer_node = port_peernode(p_ptr);
809 807
810 tipc_port_unlock(p_ptr); 808 tipc_port_unlock(p_ptr);
811 if (!cb || !connected) 809 if (!cb || !connected)
812 break; 810 break;
813 if ((msg_origport(msg) != peer_port) || 811 if ((msg_origport(msg) != peer_port) ||
814 (msg_orignode(msg) != peer_node)) 812 (msg_orignode(msg) != peer_node))
815 break; 813 break;
816 tipc_disconnect(dref); 814 tipc_disconnect(dref);
817 skb_pull(buf, msg_hdr_sz(msg)); 815 skb_pull(buf, msg_hdr_sz(msg));
818 cb(usr_handle, dref, &buf, msg_data(msg), 816 cb(usr_handle, dref, &buf, msg_data(msg),
819 msg_data_sz(msg), msg_errcode(msg)); 817 msg_data_sz(msg), msg_errcode(msg));
820 break; 818 break;
821 } 819 }
822 case TIPC_DIRECT_MSG:{ 820 case TIPC_DIRECT_MSG:{
823 tipc_msg_err_event cb = up_ptr->err_cb; 821 tipc_msg_err_event cb = up_ptr->err_cb;
824 822
825 tipc_port_unlock(p_ptr); 823 tipc_port_unlock(p_ptr);
826 if (!cb || connected) 824 if (!cb || connected)
827 break; 825 break;
828 skb_pull(buf, msg_hdr_sz(msg)); 826 skb_pull(buf, msg_hdr_sz(msg));
829 cb(usr_handle, dref, &buf, msg_data(msg), 827 cb(usr_handle, dref, &buf, msg_data(msg),
830 msg_data_sz(msg), msg_errcode(msg), &orig); 828 msg_data_sz(msg), msg_errcode(msg), &orig);
831 break; 829 break;
832 } 830 }
833 case TIPC_MCAST_MSG: 831 case TIPC_MCAST_MSG:
834 case TIPC_NAMED_MSG:{ 832 case TIPC_NAMED_MSG:{
835 tipc_named_msg_err_event cb = 833 tipc_named_msg_err_event cb =
836 up_ptr->named_err_cb; 834 up_ptr->named_err_cb;
837 835
838 tipc_port_unlock(p_ptr); 836 tipc_port_unlock(p_ptr);
839 if (!cb || connected) 837 if (!cb || connected)
840 break; 838 break;
841 dseq.type = msg_nametype(msg); 839 dseq.type = msg_nametype(msg);
842 dseq.lower = msg_nameinst(msg); 840 dseq.lower = msg_nameinst(msg);
843 dseq.upper = (message_type == TIPC_NAMED_MSG) 841 dseq.upper = (message_type == TIPC_NAMED_MSG)
844 ? dseq.lower : msg_nameupper(msg); 842 ? dseq.lower : msg_nameupper(msg);
845 skb_pull(buf, msg_hdr_sz(msg)); 843 skb_pull(buf, msg_hdr_sz(msg));
846 cb(usr_handle, dref, &buf, msg_data(msg), 844 cb(usr_handle, dref, &buf, msg_data(msg),
847 msg_data_sz(msg), msg_errcode(msg), &dseq); 845 msg_data_sz(msg), msg_errcode(msg), &dseq);
848 break; 846 break;
849 } 847 }
850 } 848 }
851 if (buf) 849 if (buf)
852 buf_discard(buf); 850 buf_discard(buf);
853 buf = next; 851 buf = next;
854 continue; 852 continue;
855 reject: 853 reject:
856 tipc_reject_msg(buf, TIPC_ERR_NO_PORT); 854 tipc_reject_msg(buf, TIPC_ERR_NO_PORT);
857 buf = next; 855 buf = next;
858 } 856 }
859 } 857 }
860 858
861 /* 859 /*
862 * port_dispatcher(): Dispatcher for messages destinated 860 * port_dispatcher(): Dispatcher for messages destinated
863 * to the tipc_port interface. Called with port locked. 861 * to the tipc_port interface. Called with port locked.
864 */ 862 */
865 863
866 static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf) 864 static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf)
867 { 865 {
868 buf->next = NULL; 866 buf->next = NULL;
869 spin_lock_bh(&queue_lock); 867 spin_lock_bh(&queue_lock);
870 if (msg_queue_head) { 868 if (msg_queue_head) {
871 msg_queue_tail->next = buf; 869 msg_queue_tail->next = buf;
872 msg_queue_tail = buf; 870 msg_queue_tail = buf;
873 } else { 871 } else {
874 msg_queue_tail = msg_queue_head = buf; 872 msg_queue_tail = msg_queue_head = buf;
875 tipc_k_signal((Handler)port_dispatcher_sigh, 0); 873 tipc_k_signal((Handler)port_dispatcher_sigh, 0);
876 } 874 }
877 spin_unlock_bh(&queue_lock); 875 spin_unlock_bh(&queue_lock);
878 return 0; 876 return 0;
879 } 877 }
880 878
881 /* 879 /*
882 * Wake up port after congestion: Called with port locked, 880 * Wake up port after congestion: Called with port locked,
883 * 881 *
884 */ 882 */
885 883
886 static void port_wakeup_sh(unsigned long ref) 884 static void port_wakeup_sh(unsigned long ref)
887 { 885 {
888 struct port *p_ptr; 886 struct port *p_ptr;
889 struct user_port *up_ptr; 887 struct user_port *up_ptr;
890 tipc_continue_event cb = NULL; 888 tipc_continue_event cb = NULL;
891 void *uh = NULL; 889 void *uh = NULL;
892 890
893 p_ptr = tipc_port_lock(ref); 891 p_ptr = tipc_port_lock(ref);
894 if (p_ptr) { 892 if (p_ptr) {
895 up_ptr = p_ptr->user_port; 893 up_ptr = p_ptr->user_port;
896 if (up_ptr) { 894 if (up_ptr) {
897 cb = up_ptr->continue_event_cb; 895 cb = up_ptr->continue_event_cb;
898 uh = up_ptr->usr_handle; 896 uh = up_ptr->usr_handle;
899 } 897 }
900 tipc_port_unlock(p_ptr); 898 tipc_port_unlock(p_ptr);
901 } 899 }
902 if (cb) 900 if (cb)
903 cb(uh, ref); 901 cb(uh, ref);
904 } 902 }
905 903
906 904
907 static void port_wakeup(struct tipc_port *p_ptr) 905 static void port_wakeup(struct tipc_port *p_ptr)
908 { 906 {
909 tipc_k_signal((Handler)port_wakeup_sh, p_ptr->ref); 907 tipc_k_signal((Handler)port_wakeup_sh, p_ptr->ref);
910 } 908 }
911 909
912 void tipc_acknowledge(u32 ref, u32 ack) 910 void tipc_acknowledge(u32 ref, u32 ack)
913 { 911 {
914 struct port *p_ptr; 912 struct port *p_ptr;
915 struct sk_buff *buf = NULL; 913 struct sk_buff *buf = NULL;
916 914
917 p_ptr = tipc_port_lock(ref); 915 p_ptr = tipc_port_lock(ref);
918 if (!p_ptr) 916 if (!p_ptr)
919 return; 917 return;
920 if (p_ptr->publ.connected) { 918 if (p_ptr->publ.connected) {
921 p_ptr->publ.conn_unacked -= ack; 919 p_ptr->publ.conn_unacked -= ack;
922 buf = port_build_proto_msg(port_peerport(p_ptr), 920 buf = port_build_proto_msg(port_peerport(p_ptr),
923 port_peernode(p_ptr), 921 port_peernode(p_ptr),
924 ref, 922 ref,
925 tipc_own_addr, 923 tipc_own_addr,
926 CONN_MANAGER, 924 CONN_MANAGER,
927 CONN_ACK, 925 CONN_ACK,
928 TIPC_OK, 926 TIPC_OK,
929 port_out_seqno(p_ptr), 927 port_out_seqno(p_ptr),
930 ack); 928 ack);
931 } 929 }
932 tipc_port_unlock(p_ptr); 930 tipc_port_unlock(p_ptr);
933 tipc_net_route_msg(buf); 931 tipc_net_route_msg(buf);
934 } 932 }
935 933
936 /* 934 /*
937 * tipc_createport(): user level call. Will add port to 935 * tipc_createport(): user level call.
938 * registry if non-zero user_ref.
939 */ 936 */
940 937
941 int tipc_createport(u32 user_ref, 938 int tipc_createport(void *usr_handle,
942 void *usr_handle,
943 unsigned int importance, 939 unsigned int importance,
944 tipc_msg_err_event error_cb, 940 tipc_msg_err_event error_cb,
945 tipc_named_msg_err_event named_error_cb, 941 tipc_named_msg_err_event named_error_cb,
946 tipc_conn_shutdown_event conn_error_cb, 942 tipc_conn_shutdown_event conn_error_cb,
947 tipc_msg_event msg_cb, 943 tipc_msg_event msg_cb,
948 tipc_named_msg_event named_msg_cb, 944 tipc_named_msg_event named_msg_cb,
949 tipc_conn_msg_event conn_msg_cb, 945 tipc_conn_msg_event conn_msg_cb,
950 tipc_continue_event continue_event_cb,/* May be zero */ 946 tipc_continue_event continue_event_cb,/* May be zero */
951 u32 *portref) 947 u32 *portref)
952 { 948 {
953 struct user_port *up_ptr; 949 struct user_port *up_ptr;
954 struct port *p_ptr; 950 struct port *p_ptr;
955 951
956 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); 952 up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
957 if (!up_ptr) { 953 if (!up_ptr) {
958 warn("Port creation failed, no memory\n"); 954 warn("Port creation failed, no memory\n");
959 return -ENOMEM; 955 return -ENOMEM;
960 } 956 }
961 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher, 957 p_ptr = (struct port *)tipc_createport_raw(NULL, port_dispatcher,
962 port_wakeup, importance); 958 port_wakeup, importance);
963 if (!p_ptr) { 959 if (!p_ptr) {
964 kfree(up_ptr); 960 kfree(up_ptr);
965 return -ENOMEM; 961 return -ENOMEM;
966 } 962 }
967 963
968 p_ptr->user_port = up_ptr; 964 p_ptr->user_port = up_ptr;
969 up_ptr->user_ref = user_ref;
970 up_ptr->usr_handle = usr_handle; 965 up_ptr->usr_handle = usr_handle;
971 up_ptr->ref = p_ptr->publ.ref; 966 up_ptr->ref = p_ptr->publ.ref;
972 up_ptr->err_cb = error_cb; 967 up_ptr->err_cb = error_cb;
973 up_ptr->named_err_cb = named_error_cb; 968 up_ptr->named_err_cb = named_error_cb;
974 up_ptr->conn_err_cb = conn_error_cb; 969 up_ptr->conn_err_cb = conn_error_cb;
975 up_ptr->msg_cb = msg_cb; 970 up_ptr->msg_cb = msg_cb;
976 up_ptr->named_msg_cb = named_msg_cb; 971 up_ptr->named_msg_cb = named_msg_cb;
977 up_ptr->conn_msg_cb = conn_msg_cb; 972 up_ptr->conn_msg_cb = conn_msg_cb;
978 up_ptr->continue_event_cb = continue_event_cb; 973 up_ptr->continue_event_cb = continue_event_cb;
979 INIT_LIST_HEAD(&up_ptr->uport_list);
980 tipc_reg_add_port(up_ptr);
981 *portref = p_ptr->publ.ref; 974 *portref = p_ptr->publ.ref;
982 tipc_port_unlock(p_ptr); 975 tipc_port_unlock(p_ptr);
983 return 0; 976 return 0;
984 } 977 }
985 978
986 int tipc_portimportance(u32 ref, unsigned int *importance) 979 int tipc_portimportance(u32 ref, unsigned int *importance)
987 { 980 {
988 struct port *p_ptr; 981 struct port *p_ptr;
989 982
990 p_ptr = tipc_port_lock(ref); 983 p_ptr = tipc_port_lock(ref);
991 if (!p_ptr) 984 if (!p_ptr)
992 return -EINVAL; 985 return -EINVAL;
993 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); 986 *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr);
994 tipc_port_unlock(p_ptr); 987 tipc_port_unlock(p_ptr);
995 return 0; 988 return 0;
996 } 989 }
997 990
998 int tipc_set_portimportance(u32 ref, unsigned int imp) 991 int tipc_set_portimportance(u32 ref, unsigned int imp)
999 { 992 {
1000 struct port *p_ptr; 993 struct port *p_ptr;
1001 994
1002 if (imp > TIPC_CRITICAL_IMPORTANCE) 995 if (imp > TIPC_CRITICAL_IMPORTANCE)
1003 return -EINVAL; 996 return -EINVAL;
1004 997
1005 p_ptr = tipc_port_lock(ref); 998 p_ptr = tipc_port_lock(ref);
1006 if (!p_ptr) 999 if (!p_ptr)
1007 return -EINVAL; 1000 return -EINVAL;
1008 msg_set_importance(&p_ptr->publ.phdr, (u32)imp); 1001 msg_set_importance(&p_ptr->publ.phdr, (u32)imp);
1009 tipc_port_unlock(p_ptr); 1002 tipc_port_unlock(p_ptr);
1010 return 0; 1003 return 0;
1011 } 1004 }
1012 1005
1013 1006
1014 int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 1007 int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1015 { 1008 {
1016 struct port *p_ptr; 1009 struct port *p_ptr;
1017 struct publication *publ; 1010 struct publication *publ;
1018 u32 key; 1011 u32 key;
1019 int res = -EINVAL; 1012 int res = -EINVAL;
1020 1013
1021 p_ptr = tipc_port_lock(ref); 1014 p_ptr = tipc_port_lock(ref);
1022 if (!p_ptr) 1015 if (!p_ptr)
1023 return -EINVAL; 1016 return -EINVAL;
1024 1017
1025 dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " 1018 dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, "
1026 "lower = %u, upper = %u\n", 1019 "lower = %u, upper = %u\n",
1027 ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper); 1020 ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
1028 if (p_ptr->publ.connected) 1021 if (p_ptr->publ.connected)
1029 goto exit; 1022 goto exit;
1030 if (seq->lower > seq->upper) 1023 if (seq->lower > seq->upper)
1031 goto exit; 1024 goto exit;
1032 if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE)) 1025 if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE))
1033 goto exit; 1026 goto exit;
1034 key = ref + p_ptr->pub_count + 1; 1027 key = ref + p_ptr->pub_count + 1;
1035 if (key == ref) { 1028 if (key == ref) {
1036 res = -EADDRINUSE; 1029 res = -EADDRINUSE;
1037 goto exit; 1030 goto exit;
1038 } 1031 }
1039 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper, 1032 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
1040 scope, p_ptr->publ.ref, key); 1033 scope, p_ptr->publ.ref, key);
1041 if (publ) { 1034 if (publ) {
1042 list_add(&publ->pport_list, &p_ptr->publications); 1035 list_add(&publ->pport_list, &p_ptr->publications);
1043 p_ptr->pub_count++; 1036 p_ptr->pub_count++;
1044 p_ptr->publ.published = 1; 1037 p_ptr->publ.published = 1;
1045 res = 0; 1038 res = 0;
1046 } 1039 }
1047 exit: 1040 exit:
1048 tipc_port_unlock(p_ptr); 1041 tipc_port_unlock(p_ptr);
1049 return res; 1042 return res;
1050 } 1043 }
1051 1044
1052 int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) 1045 int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
1053 { 1046 {
1054 struct port *p_ptr; 1047 struct port *p_ptr;
1055 struct publication *publ; 1048 struct publication *publ;
1056 struct publication *tpubl; 1049 struct publication *tpubl;
1057 int res = -EINVAL; 1050 int res = -EINVAL;
1058 1051
1059 p_ptr = tipc_port_lock(ref); 1052 p_ptr = tipc_port_lock(ref);
1060 if (!p_ptr) 1053 if (!p_ptr)
1061 return -EINVAL; 1054 return -EINVAL;
1062 if (!seq) { 1055 if (!seq) {
1063 list_for_each_entry_safe(publ, tpubl, 1056 list_for_each_entry_safe(publ, tpubl,
1064 &p_ptr->publications, pport_list) { 1057 &p_ptr->publications, pport_list) {
1065 tipc_nametbl_withdraw(publ->type, publ->lower, 1058 tipc_nametbl_withdraw(publ->type, publ->lower,
1066 publ->ref, publ->key); 1059 publ->ref, publ->key);
1067 } 1060 }
1068 res = 0; 1061 res = 0;
1069 } else { 1062 } else {
1070 list_for_each_entry_safe(publ, tpubl, 1063 list_for_each_entry_safe(publ, tpubl,
1071 &p_ptr->publications, pport_list) { 1064 &p_ptr->publications, pport_list) {
1072 if (publ->scope != scope) 1065 if (publ->scope != scope)
1073 continue; 1066 continue;
1074 if (publ->type != seq->type) 1067 if (publ->type != seq->type)
1075 continue; 1068 continue;
1076 if (publ->lower != seq->lower) 1069 if (publ->lower != seq->lower)
1077 continue; 1070 continue;
1078 if (publ->upper != seq->upper) 1071 if (publ->upper != seq->upper)
1079 break; 1072 break;
1080 tipc_nametbl_withdraw(publ->type, publ->lower, 1073 tipc_nametbl_withdraw(publ->type, publ->lower,
1081 publ->ref, publ->key); 1074 publ->ref, publ->key);
1082 res = 0; 1075 res = 0;
1083 break; 1076 break;
1084 } 1077 }
1085 } 1078 }
1086 if (list_empty(&p_ptr->publications)) 1079 if (list_empty(&p_ptr->publications))
1087 p_ptr->publ.published = 0; 1080 p_ptr->publ.published = 0;
1088 tipc_port_unlock(p_ptr); 1081 tipc_port_unlock(p_ptr);
1089 return res; 1082 return res;
1090 } 1083 }
1091 1084
1092 int tipc_connect2port(u32 ref, struct tipc_portid const *peer) 1085 int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1093 { 1086 {
1094 struct port *p_ptr; 1087 struct port *p_ptr;
1095 struct tipc_msg *msg; 1088 struct tipc_msg *msg;
1096 int res = -EINVAL; 1089 int res = -EINVAL;
1097 1090
1098 p_ptr = tipc_port_lock(ref); 1091 p_ptr = tipc_port_lock(ref);
1099 if (!p_ptr) 1092 if (!p_ptr)
1100 return -EINVAL; 1093 return -EINVAL;
1101 if (p_ptr->publ.published || p_ptr->publ.connected) 1094 if (p_ptr->publ.published || p_ptr->publ.connected)
1102 goto exit; 1095 goto exit;
1103 if (!peer->ref) 1096 if (!peer->ref)
1104 goto exit; 1097 goto exit;
1105 1098
1106 msg = &p_ptr->publ.phdr; 1099 msg = &p_ptr->publ.phdr;
1107 msg_set_destnode(msg, peer->node); 1100 msg_set_destnode(msg, peer->node);
1108 msg_set_destport(msg, peer->ref); 1101 msg_set_destport(msg, peer->ref);
1109 msg_set_orignode(msg, tipc_own_addr); 1102 msg_set_orignode(msg, tipc_own_addr);
1110 msg_set_origport(msg, p_ptr->publ.ref); 1103 msg_set_origport(msg, p_ptr->publ.ref);
1111 msg_set_transp_seqno(msg, 42); 1104 msg_set_transp_seqno(msg, 42);
1112 msg_set_type(msg, TIPC_CONN_MSG); 1105 msg_set_type(msg, TIPC_CONN_MSG);
1113 msg_set_hdr_sz(msg, SHORT_H_SIZE); 1106 msg_set_hdr_sz(msg, SHORT_H_SIZE);
1114 1107
1115 p_ptr->probing_interval = PROBING_INTERVAL; 1108 p_ptr->probing_interval = PROBING_INTERVAL;
1116 p_ptr->probing_state = CONFIRMED; 1109 p_ptr->probing_state = CONFIRMED;
1117 p_ptr->publ.connected = 1; 1110 p_ptr->publ.connected = 1;
1118 k_start_timer(&p_ptr->timer, p_ptr->probing_interval); 1111 k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
1119 1112
1120 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node, 1113 tipc_nodesub_subscribe(&p_ptr->subscription,peer->node,
1121 (void *)(unsigned long)ref, 1114 (void *)(unsigned long)ref,
1122 (net_ev_handler)port_handle_node_down); 1115 (net_ev_handler)port_handle_node_down);
1123 res = 0; 1116 res = 0;
1124 exit: 1117 exit:
1125 tipc_port_unlock(p_ptr); 1118 tipc_port_unlock(p_ptr);
1126 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1119 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);
1127 return res; 1120 return res;
1128 } 1121 }
1129 1122
1130 /** 1123 /**
1131 * tipc_disconnect_port - disconnect port from peer 1124 * tipc_disconnect_port - disconnect port from peer
1132 * 1125 *
1133 * Port must be locked. 1126 * Port must be locked.
1134 */ 1127 */
1135 1128
1136 int tipc_disconnect_port(struct tipc_port *tp_ptr) 1129 int tipc_disconnect_port(struct tipc_port *tp_ptr)
1137 { 1130 {
1138 int res; 1131 int res;
1139 1132
1140 if (tp_ptr->connected) { 1133 if (tp_ptr->connected) {
1141 tp_ptr->connected = 0; 1134 tp_ptr->connected = 0;
1142 /* let timer expire on it's own to avoid deadlock! */ 1135 /* let timer expire on it's own to avoid deadlock! */
1143 tipc_nodesub_unsubscribe( 1136 tipc_nodesub_unsubscribe(
1144 &((struct port *)tp_ptr)->subscription); 1137 &((struct port *)tp_ptr)->subscription);
1145 res = 0; 1138 res = 0;
1146 } else { 1139 } else {
1147 res = -ENOTCONN; 1140 res = -ENOTCONN;
1148 } 1141 }
1149 return res; 1142 return res;
1150 } 1143 }
1151 1144
1152 /* 1145 /*
1153 * tipc_disconnect(): Disconnect port form peer. 1146 * tipc_disconnect(): Disconnect port form peer.
1154 * This is a node local operation. 1147 * This is a node local operation.
1155 */ 1148 */
1156 1149
1157 int tipc_disconnect(u32 ref) 1150 int tipc_disconnect(u32 ref)
1158 { 1151 {
1159 struct port *p_ptr; 1152 struct port *p_ptr;
1160 int res; 1153 int res;
1161 1154
1162 p_ptr = tipc_port_lock(ref); 1155 p_ptr = tipc_port_lock(ref);
1163 if (!p_ptr) 1156 if (!p_ptr)
1164 return -EINVAL; 1157 return -EINVAL;
1165 res = tipc_disconnect_port((struct tipc_port *)p_ptr); 1158 res = tipc_disconnect_port((struct tipc_port *)p_ptr);
1166 tipc_port_unlock(p_ptr); 1159 tipc_port_unlock(p_ptr);
1167 return res; 1160 return res;
1168 } 1161 }
1169 1162
1170 /* 1163 /*
1171 * tipc_shutdown(): Send a SHUTDOWN msg to peer and disconnect 1164 * tipc_shutdown(): Send a SHUTDOWN msg to peer and disconnect
1172 */ 1165 */
1173 int tipc_shutdown(u32 ref) 1166 int tipc_shutdown(u32 ref)
1174 { 1167 {
1175 struct port *p_ptr; 1168 struct port *p_ptr;
1176 struct sk_buff *buf = NULL; 1169 struct sk_buff *buf = NULL;
1177 1170
1178 p_ptr = tipc_port_lock(ref); 1171 p_ptr = tipc_port_lock(ref);
1179 if (!p_ptr) 1172 if (!p_ptr)
1180 return -EINVAL; 1173 return -EINVAL;
1181 1174
1182 if (p_ptr->publ.connected) { 1175 if (p_ptr->publ.connected) {
1183 u32 imp = msg_importance(&p_ptr->publ.phdr); 1176 u32 imp = msg_importance(&p_ptr->publ.phdr);
1184 if (imp < TIPC_CRITICAL_IMPORTANCE) 1177 if (imp < TIPC_CRITICAL_IMPORTANCE)
1185 imp++; 1178 imp++;
1186 buf = port_build_proto_msg(port_peerport(p_ptr), 1179 buf = port_build_proto_msg(port_peerport(p_ptr),
1187 port_peernode(p_ptr), 1180 port_peernode(p_ptr),
1188 ref, 1181 ref,
1189 tipc_own_addr, 1182 tipc_own_addr,
1190 imp, 1183 imp,
1191 TIPC_CONN_MSG, 1184 TIPC_CONN_MSG,
1192 TIPC_CONN_SHUTDOWN, 1185 TIPC_CONN_SHUTDOWN,
1193 port_out_seqno(p_ptr), 1186 port_out_seqno(p_ptr),
1194 0); 1187 0);
1195 } 1188 }
1196 tipc_port_unlock(p_ptr); 1189 tipc_port_unlock(p_ptr);
1197 tipc_net_route_msg(buf); 1190 tipc_net_route_msg(buf);
1198 return tipc_disconnect(ref); 1191 return tipc_disconnect(ref);
1199 } 1192 }
1200 1193
1201 /* 1194 /*
1202 * tipc_port_recv_sections(): Concatenate and deliver sectioned 1195 * tipc_port_recv_sections(): Concatenate and deliver sectioned
1203 * message for this node. 1196 * message for this node.
1204 */ 1197 */
1205 1198
1206 static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, 1199 static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,
1207 struct iovec const *msg_sect) 1200 struct iovec const *msg_sect)
1208 { 1201 {
1209 struct sk_buff *buf; 1202 struct sk_buff *buf;
1210 int res; 1203 int res;
1211 1204
1212 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect, 1205 res = tipc_msg_build(&sender->publ.phdr, msg_sect, num_sect,
1213 MAX_MSG_SIZE, !sender->user_port, &buf); 1206 MAX_MSG_SIZE, !sender->user_port, &buf);
1214 if (likely(buf)) 1207 if (likely(buf))
1215 tipc_port_recv_msg(buf); 1208 tipc_port_recv_msg(buf);
1216 return res; 1209 return res;
1217 } 1210 }
1218 1211
1219 /** 1212 /**
1220 * tipc_send - send message sections on connection 1213 * tipc_send - send message sections on connection
1221 */ 1214 */
1222 1215
1223 int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) 1216 int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1224 { 1217 {
1225 struct port *p_ptr; 1218 struct port *p_ptr;
1226 u32 destnode; 1219 u32 destnode;
1227 int res; 1220 int res;
1228 1221
1229 p_ptr = tipc_port_deref(ref); 1222 p_ptr = tipc_port_deref(ref);
1230 if (!p_ptr || !p_ptr->publ.connected) 1223 if (!p_ptr || !p_ptr->publ.connected)
1231 return -EINVAL; 1224 return -EINVAL;
1232 1225
1233 p_ptr->publ.congested = 1; 1226 p_ptr->publ.congested = 1;
1234 if (!tipc_port_congested(p_ptr)) { 1227 if (!tipc_port_congested(p_ptr)) {
1235 destnode = port_peernode(p_ptr); 1228 destnode = port_peernode(p_ptr);
1236 if (likely(destnode != tipc_own_addr)) 1229 if (likely(destnode != tipc_own_addr))
1237 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1230 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1238 destnode); 1231 destnode);
1239 else 1232 else
1240 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1233 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1241 1234
1242 if (likely(res != -ELINKCONG)) { 1235 if (likely(res != -ELINKCONG)) {
1243 port_incr_out_seqno(p_ptr); 1236 port_incr_out_seqno(p_ptr);
1244 p_ptr->publ.congested = 0; 1237 p_ptr->publ.congested = 0;
1245 p_ptr->sent++; 1238 p_ptr->sent++;
1246 return res; 1239 return res;
1247 } 1240 }
1248 } 1241 }
1249 if (port_unreliable(p_ptr)) { 1242 if (port_unreliable(p_ptr)) {
1250 p_ptr->publ.congested = 0; 1243 p_ptr->publ.congested = 0;
1251 /* Just calculate msg length and return */ 1244 /* Just calculate msg length and return */
1252 return tipc_msg_calc_data_size(msg_sect, num_sect); 1245 return tipc_msg_calc_data_size(msg_sect, num_sect);
1253 } 1246 }
1254 return -ELINKCONG; 1247 return -ELINKCONG;
1255 } 1248 }
1256 1249
1257 /** 1250 /**
1258 * tipc_send2name - send message sections to port name 1251 * tipc_send2name - send message sections to port name
1259 */ 1252 */
1260 1253
1261 int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, 1254 int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1262 unsigned int num_sect, struct iovec const *msg_sect) 1255 unsigned int num_sect, struct iovec const *msg_sect)
1263 { 1256 {
1264 struct port *p_ptr; 1257 struct port *p_ptr;
1265 struct tipc_msg *msg; 1258 struct tipc_msg *msg;
1266 u32 destnode = domain; 1259 u32 destnode = domain;
1267 u32 destport; 1260 u32 destport;
1268 int res; 1261 int res;
1269 1262
1270 p_ptr = tipc_port_deref(ref); 1263 p_ptr = tipc_port_deref(ref);
1271 if (!p_ptr || p_ptr->publ.connected) 1264 if (!p_ptr || p_ptr->publ.connected)
1272 return -EINVAL; 1265 return -EINVAL;
1273 1266
1274 msg = &p_ptr->publ.phdr; 1267 msg = &p_ptr->publ.phdr;
1275 msg_set_type(msg, TIPC_NAMED_MSG); 1268 msg_set_type(msg, TIPC_NAMED_MSG);
1276 msg_set_orignode(msg, tipc_own_addr); 1269 msg_set_orignode(msg, tipc_own_addr);
1277 msg_set_origport(msg, ref); 1270 msg_set_origport(msg, ref);
1278 msg_set_hdr_sz(msg, LONG_H_SIZE); 1271 msg_set_hdr_sz(msg, LONG_H_SIZE);
1279 msg_set_nametype(msg, name->type); 1272 msg_set_nametype(msg, name->type);
1280 msg_set_nameinst(msg, name->instance); 1273 msg_set_nameinst(msg, name->instance);
1281 msg_set_lookup_scope(msg, tipc_addr_scope(domain)); 1274 msg_set_lookup_scope(msg, tipc_addr_scope(domain));
1282 destport = tipc_nametbl_translate(name->type, name->instance, &destnode); 1275 destport = tipc_nametbl_translate(name->type, name->instance, &destnode);
1283 msg_set_destnode(msg, destnode); 1276 msg_set_destnode(msg, destnode);
1284 msg_set_destport(msg, destport); 1277 msg_set_destport(msg, destport);
1285 1278
1286 if (likely(destport)) { 1279 if (likely(destport)) {
1287 p_ptr->sent++; 1280 p_ptr->sent++;
1288 if (likely(destnode == tipc_own_addr)) 1281 if (likely(destnode == tipc_own_addr))
1289 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1282 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1290 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1283 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1291 destnode); 1284 destnode);
1292 if (likely(res != -ELINKCONG)) 1285 if (likely(res != -ELINKCONG))
1293 return res; 1286 return res;
1294 if (port_unreliable(p_ptr)) { 1287 if (port_unreliable(p_ptr)) {
1295 /* Just calculate msg length and return */ 1288 /* Just calculate msg length and return */
1296 return tipc_msg_calc_data_size(msg_sect, num_sect); 1289 return tipc_msg_calc_data_size(msg_sect, num_sect);
1297 } 1290 }
1298 return -ELINKCONG; 1291 return -ELINKCONG;
1299 } 1292 }
1300 return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, 1293 return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect,
1301 TIPC_ERR_NO_NAME); 1294 TIPC_ERR_NO_NAME);
1302 } 1295 }
1303 1296
1304 /** 1297 /**
1305 * tipc_send2port - send message sections to port identity 1298 * tipc_send2port - send message sections to port identity
1306 */ 1299 */
1307 1300
1308 int tipc_send2port(u32 ref, struct tipc_portid const *dest, 1301 int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1309 unsigned int num_sect, struct iovec const *msg_sect) 1302 unsigned int num_sect, struct iovec const *msg_sect)
1310 { 1303 {
1311 struct port *p_ptr; 1304 struct port *p_ptr;
1312 struct tipc_msg *msg; 1305 struct tipc_msg *msg;
1313 int res; 1306 int res;
1314 1307
1315 p_ptr = tipc_port_deref(ref); 1308 p_ptr = tipc_port_deref(ref);
1316 if (!p_ptr || p_ptr->publ.connected) 1309 if (!p_ptr || p_ptr->publ.connected)
1317 return -EINVAL; 1310 return -EINVAL;
1318 1311
1319 msg = &p_ptr->publ.phdr; 1312 msg = &p_ptr->publ.phdr;
1320 msg_set_type(msg, TIPC_DIRECT_MSG); 1313 msg_set_type(msg, TIPC_DIRECT_MSG);
1321 msg_set_orignode(msg, tipc_own_addr); 1314 msg_set_orignode(msg, tipc_own_addr);
1322 msg_set_origport(msg, ref); 1315 msg_set_origport(msg, ref);
1323 msg_set_destnode(msg, dest->node); 1316 msg_set_destnode(msg, dest->node);
1324 msg_set_destport(msg, dest->ref); 1317 msg_set_destport(msg, dest->ref);
1325 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1318 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1326 p_ptr->sent++; 1319 p_ptr->sent++;
1327 if (dest->node == tipc_own_addr) 1320 if (dest->node == tipc_own_addr)
1328 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1321 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1329 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node); 1322 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node);
1330 if (likely(res != -ELINKCONG)) 1323 if (likely(res != -ELINKCONG))
1331 return res; 1324 return res;
1332 if (port_unreliable(p_ptr)) { 1325 if (port_unreliable(p_ptr)) {
1333 /* Just calculate msg length and return */ 1326 /* Just calculate msg length and return */
1334 return tipc_msg_calc_data_size(msg_sect, num_sect); 1327 return tipc_msg_calc_data_size(msg_sect, num_sect);
1335 } 1328 }
1336 return -ELINKCONG; 1329 return -ELINKCONG;
1337 } 1330 }
1338 1331
1339 /** 1332 /**
1340 * tipc_send_buf2port - send message buffer to port identity 1333 * tipc_send_buf2port - send message buffer to port identity
1341 */ 1334 */
1342 1335
1343 int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, 1336 int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1344 struct sk_buff *buf, unsigned int dsz) 1337 struct sk_buff *buf, unsigned int dsz)
1345 { 1338 {
1346 struct port *p_ptr; 1339 struct port *p_ptr;
1347 struct tipc_msg *msg; 1340 struct tipc_msg *msg;
1348 int res; 1341 int res;
1349 1342
1350 p_ptr = (struct port *)tipc_ref_deref(ref); 1343 p_ptr = (struct port *)tipc_ref_deref(ref);
1351 if (!p_ptr || p_ptr->publ.connected) 1344 if (!p_ptr || p_ptr->publ.connected)
1352 return -EINVAL; 1345 return -EINVAL;
1353 1346
1354 msg = &p_ptr->publ.phdr; 1347 msg = &p_ptr->publ.phdr;
1355 msg_set_type(msg, TIPC_DIRECT_MSG); 1348 msg_set_type(msg, TIPC_DIRECT_MSG);
1356 msg_set_orignode(msg, tipc_own_addr); 1349 msg_set_orignode(msg, tipc_own_addr);
1357 msg_set_origport(msg, ref); 1350 msg_set_origport(msg, ref);
1358 msg_set_destnode(msg, dest->node); 1351 msg_set_destnode(msg, dest->node);
1359 msg_set_destport(msg, dest->ref); 1352 msg_set_destport(msg, dest->ref);
1360 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1353 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1361 msg_set_size(msg, DIR_MSG_H_SIZE + dsz); 1354 msg_set_size(msg, DIR_MSG_H_SIZE + dsz);
1362 if (skb_cow(buf, DIR_MSG_H_SIZE)) 1355 if (skb_cow(buf, DIR_MSG_H_SIZE))
1363 return -ENOMEM; 1356 return -ENOMEM;
1364 1357
1365 skb_push(buf, DIR_MSG_H_SIZE); 1358 skb_push(buf, DIR_MSG_H_SIZE);
1366 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1359 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1367 msg_dbg(msg, "buf2port: "); 1360 msg_dbg(msg, "buf2port: ");
1368 p_ptr->sent++; 1361 p_ptr->sent++;
1369 if (dest->node == tipc_own_addr) 1362 if (dest->node == tipc_own_addr)
1370 return tipc_port_recv_msg(buf); 1363 return tipc_port_recv_msg(buf);
1371 res = tipc_send_buf_fast(buf, dest->node); 1364 res = tipc_send_buf_fast(buf, dest->node);
1372 if (likely(res != -ELINKCONG)) 1365 if (likely(res != -ELINKCONG))
1373 return res; 1366 return res;
1374 if (port_unreliable(p_ptr)) 1367 if (port_unreliable(p_ptr))
1375 return dsz; 1368 return dsz;
1376 return -ELINKCONG; 1369 return -ELINKCONG;
1377 } 1370 }
1378 1371
1379 1372
1 /* 1 /*
2 * net/tipc/port.h: Include file for TIPC port code 2 * net/tipc/port.h: Include file for TIPC port code
3 * 3 *
4 * Copyright (c) 1994-2007, Ericsson AB 4 * Copyright (c) 1994-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2007, 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
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #ifndef _TIPC_PORT_H 37 #ifndef _TIPC_PORT_H
38 #define _TIPC_PORT_H 38 #define _TIPC_PORT_H
39 39
40 #include "ref.h" 40 #include "ref.h"
41 #include "net.h" 41 #include "net.h"
42 #include "msg.h" 42 #include "msg.h"
43 #include "node_subscr.h" 43 #include "node_subscr.h"
44 44
45 #define TIPC_FLOW_CONTROL_WIN 512 45 #define TIPC_FLOW_CONTROL_WIN 512
46 46
47 typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref, 47 typedef void (*tipc_msg_err_event) (void *usr_handle, u32 portref,
48 struct sk_buff **buf, unsigned char const *data, 48 struct sk_buff **buf, unsigned char const *data,
49 unsigned int size, int reason, 49 unsigned int size, int reason,
50 struct tipc_portid const *attmpt_destid); 50 struct tipc_portid const *attmpt_destid);
51 51
52 typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref, 52 typedef void (*tipc_named_msg_err_event) (void *usr_handle, u32 portref,
53 struct sk_buff **buf, unsigned char const *data, 53 struct sk_buff **buf, unsigned char const *data,
54 unsigned int size, int reason, 54 unsigned int size, int reason,
55 struct tipc_name_seq const *attmpt_dest); 55 struct tipc_name_seq const *attmpt_dest);
56 56
57 typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref, 57 typedef void (*tipc_conn_shutdown_event) (void *usr_handle, u32 portref,
58 struct sk_buff **buf, unsigned char const *data, 58 struct sk_buff **buf, unsigned char const *data,
59 unsigned int size, int reason); 59 unsigned int size, int reason);
60 60
61 typedef void (*tipc_msg_event) (void *usr_handle, u32 portref, 61 typedef void (*tipc_msg_event) (void *usr_handle, u32 portref,
62 struct sk_buff **buf, unsigned char const *data, 62 struct sk_buff **buf, unsigned char const *data,
63 unsigned int size, unsigned int importance, 63 unsigned int size, unsigned int importance,
64 struct tipc_portid const *origin); 64 struct tipc_portid const *origin);
65 65
66 typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref, 66 typedef void (*tipc_named_msg_event) (void *usr_handle, u32 portref,
67 struct sk_buff **buf, unsigned char const *data, 67 struct sk_buff **buf, unsigned char const *data,
68 unsigned int size, unsigned int importance, 68 unsigned int size, unsigned int importance,
69 struct tipc_portid const *orig, 69 struct tipc_portid const *orig,
70 struct tipc_name_seq const *dest); 70 struct tipc_name_seq const *dest);
71 71
72 typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref, 72 typedef void (*tipc_conn_msg_event) (void *usr_handle, u32 portref,
73 struct sk_buff **buf, unsigned char const *data, 73 struct sk_buff **buf, unsigned char const *data,
74 unsigned int size); 74 unsigned int size);
75 75
76 typedef void (*tipc_continue_event) (void *usr_handle, u32 portref); 76 typedef void (*tipc_continue_event) (void *usr_handle, u32 portref);
77 77
78 /** 78 /**
79 * struct user_port - TIPC user port (used with native API) 79 * struct user_port - TIPC user port (used with native API)
80 * @user_ref: id of user who created user port
81 * @usr_handle: user-specified field 80 * @usr_handle: user-specified field
82 * @ref: object reference to associated TIPC port 81 * @ref: object reference to associated TIPC port
83 * <various callback routines> 82 * <various callback routines>
84 * @uport_list: adjacent user ports in list of ports held by user
85 */ 83 */
86 84
87 struct user_port { 85 struct user_port {
88 u32 user_ref;
89 void *usr_handle; 86 void *usr_handle;
90 u32 ref; 87 u32 ref;
91 tipc_msg_err_event err_cb; 88 tipc_msg_err_event err_cb;
92 tipc_named_msg_err_event named_err_cb; 89 tipc_named_msg_err_event named_err_cb;
93 tipc_conn_shutdown_event conn_err_cb; 90 tipc_conn_shutdown_event conn_err_cb;
94 tipc_msg_event msg_cb; 91 tipc_msg_event msg_cb;
95 tipc_named_msg_event named_msg_cb; 92 tipc_named_msg_event named_msg_cb;
96 tipc_conn_msg_event conn_msg_cb; 93 tipc_conn_msg_event conn_msg_cb;
97 tipc_continue_event continue_event_cb; 94 tipc_continue_event continue_event_cb;
98 struct list_head uport_list;
99 }; 95 };
100 96
101 /** 97 /**
102 * struct tipc_port - TIPC port info available to socket API 98 * struct tipc_port - TIPC port info available to socket API
103 * @usr_handle: pointer to additional user-defined information about port 99 * @usr_handle: pointer to additional user-defined information about port
104 * @lock: pointer to spinlock for controlling access to port 100 * @lock: pointer to spinlock for controlling access to port
105 * @connected: non-zero if port is currently connected to a peer port 101 * @connected: non-zero if port is currently connected to a peer port
106 * @conn_type: TIPC type used when connection was established 102 * @conn_type: TIPC type used when connection was established
107 * @conn_instance: TIPC instance used when connection was established 103 * @conn_instance: TIPC instance used when connection was established
108 * @conn_unacked: number of unacknowledged messages received from peer port 104 * @conn_unacked: number of unacknowledged messages received from peer port
109 * @published: non-zero if port has one or more associated names 105 * @published: non-zero if port has one or more associated names
110 * @congested: non-zero if cannot send because of link or port congestion 106 * @congested: non-zero if cannot send because of link or port congestion
111 * @max_pkt: maximum packet size "hint" used when building messages sent by port 107 * @max_pkt: maximum packet size "hint" used when building messages sent by port
112 * @ref: unique reference to port in TIPC object registry 108 * @ref: unique reference to port in TIPC object registry
113 * @phdr: preformatted message header used when sending messages 109 * @phdr: preformatted message header used when sending messages
114 */ 110 */
115 struct tipc_port { 111 struct tipc_port {
116 void *usr_handle; 112 void *usr_handle;
117 spinlock_t *lock; 113 spinlock_t *lock;
118 int connected; 114 int connected;
119 u32 conn_type; 115 u32 conn_type;
120 u32 conn_instance; 116 u32 conn_instance;
121 u32 conn_unacked; 117 u32 conn_unacked;
122 int published; 118 int published;
123 u32 congested; 119 u32 congested;
124 u32 max_pkt; 120 u32 max_pkt;
125 u32 ref; 121 u32 ref;
126 struct tipc_msg phdr; 122 struct tipc_msg phdr;
127 }; 123 };
128 124
129 /** 125 /**
130 * struct port - TIPC port structure 126 * struct port - TIPC port structure
131 * @publ: TIPC port info available to privileged users 127 * @publ: TIPC port info available to privileged users
132 * @port_list: adjacent ports in TIPC's global list of ports 128 * @port_list: adjacent ports in TIPC's global list of ports
133 * @dispatcher: ptr to routine which handles received messages 129 * @dispatcher: ptr to routine which handles received messages
134 * @wakeup: ptr to routine to call when port is no longer congested 130 * @wakeup: ptr to routine to call when port is no longer congested
135 * @user_port: ptr to user port associated with port (if any) 131 * @user_port: ptr to user port associated with port (if any)
136 * @wait_list: adjacent ports in list of ports waiting on link congestion 132 * @wait_list: adjacent ports in list of ports waiting on link congestion
137 * @waiting_pkts: 133 * @waiting_pkts:
138 * @sent: 134 * @sent:
139 * @acked: 135 * @acked:
140 * @publications: list of publications for port 136 * @publications: list of publications for port
141 * @pub_count: total # of publications port has made during its lifetime 137 * @pub_count: total # of publications port has made during its lifetime
142 * @probing_state: 138 * @probing_state:
143 * @probing_interval: 139 * @probing_interval:
144 * @last_in_seqno: 140 * @last_in_seqno:
145 * @timer_ref: 141 * @timer_ref:
146 * @subscription: "node down" subscription used to terminate failed connections 142 * @subscription: "node down" subscription used to terminate failed connections
147 */ 143 */
148 144
149 struct port { 145 struct port {
150 struct tipc_port publ; 146 struct tipc_port publ;
151 struct list_head port_list; 147 struct list_head port_list;
152 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); 148 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *);
153 void (*wakeup)(struct tipc_port *); 149 void (*wakeup)(struct tipc_port *);
154 struct user_port *user_port; 150 struct user_port *user_port;
155 struct list_head wait_list; 151 struct list_head wait_list;
156 u32 waiting_pkts; 152 u32 waiting_pkts;
157 u32 sent; 153 u32 sent;
158 u32 acked; 154 u32 acked;
159 struct list_head publications; 155 struct list_head publications;
160 u32 pub_count; 156 u32 pub_count;
161 u32 probing_state; 157 u32 probing_state;
162 u32 probing_interval; 158 u32 probing_interval;
163 u32 last_in_seqno; 159 u32 last_in_seqno;
164 struct timer_list timer; 160 struct timer_list timer;
165 struct tipc_node_subscr subscription; 161 struct tipc_node_subscr subscription;
166 }; 162 };
167 163
168 extern spinlock_t tipc_port_list_lock; 164 extern spinlock_t tipc_port_list_lock;
169 struct port_list; 165 struct port_list;
170 166
171 /* 167 /*
172 * TIPC port manipulation routines 168 * TIPC port manipulation routines
173 */ 169 */
174 struct tipc_port *tipc_createport_raw(void *usr_handle, 170 struct tipc_port *tipc_createport_raw(void *usr_handle,
175 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), 171 u32 (*dispatcher)(struct tipc_port *, struct sk_buff *),
176 void (*wakeup)(struct tipc_port *), const u32 importance); 172 void (*wakeup)(struct tipc_port *), const u32 importance);
177 173
178 int tipc_reject_msg(struct sk_buff *buf, u32 err); 174 int tipc_reject_msg(struct sk_buff *buf, u32 err);
179 175
180 int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode); 176 int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode);
181 177
182 void tipc_acknowledge(u32 port_ref, u32 ack); 178 void tipc_acknowledge(u32 port_ref, u32 ack);
183 179
184 int tipc_createport(unsigned int tipc_user, void *usr_handle, 180 int tipc_createport(void *usr_handle,
185 unsigned int importance, tipc_msg_err_event error_cb, 181 unsigned int importance, tipc_msg_err_event error_cb,
186 tipc_named_msg_err_event named_error_cb, 182 tipc_named_msg_err_event named_error_cb,
187 tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb, 183 tipc_conn_shutdown_event conn_error_cb, tipc_msg_event msg_cb,
188 tipc_named_msg_event named_msg_cb, 184 tipc_named_msg_event named_msg_cb,
189 tipc_conn_msg_event conn_msg_cb, 185 tipc_conn_msg_event conn_msg_cb,
190 tipc_continue_event continue_event_cb, u32 *portref); 186 tipc_continue_event continue_event_cb, u32 *portref);
191 187
192 int tipc_deleteport(u32 portref); 188 int tipc_deleteport(u32 portref);
193 189
194 int tipc_portimportance(u32 portref, unsigned int *importance); 190 int tipc_portimportance(u32 portref, unsigned int *importance);
195 int tipc_set_portimportance(u32 portref, unsigned int importance); 191 int tipc_set_portimportance(u32 portref, unsigned int importance);
196 192
197 int tipc_portunreliable(u32 portref, unsigned int *isunreliable); 193 int tipc_portunreliable(u32 portref, unsigned int *isunreliable);
198 int tipc_set_portunreliable(u32 portref, unsigned int isunreliable); 194 int tipc_set_portunreliable(u32 portref, unsigned int isunreliable);
199 195
200 int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); 196 int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable);
201 int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); 197 int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable);
202 198
203 int tipc_publish(u32 portref, unsigned int scope, 199 int tipc_publish(u32 portref, unsigned int scope,
204 struct tipc_name_seq const *name_seq); 200 struct tipc_name_seq const *name_seq);
205 int tipc_withdraw(u32 portref, unsigned int scope, 201 int tipc_withdraw(u32 portref, unsigned int scope,
206 struct tipc_name_seq const *name_seq); 202 struct tipc_name_seq const *name_seq);
207 203
208 int tipc_connect2port(u32 portref, struct tipc_portid const *port); 204 int tipc_connect2port(u32 portref, struct tipc_portid const *port);
209 205
210 int tipc_disconnect(u32 portref); 206 int tipc_disconnect(u32 portref);
211 207
212 int tipc_shutdown(u32 ref); 208 int tipc_shutdown(u32 ref);
213 209
214 210
215 /* 211 /*
216 * The following routines require that the port be locked on entry 212 * The following routines require that the port be locked on entry
217 */ 213 */
218 int tipc_disconnect_port(struct tipc_port *tp_ptr); 214 int tipc_disconnect_port(struct tipc_port *tp_ptr);
219 215
220 /* 216 /*
221 * TIPC messaging routines 217 * TIPC messaging routines
222 */ 218 */
223 int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); 219 int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect);
224 220
225 int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, 221 int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
226 unsigned int num_sect, struct iovec const *msg_sect); 222 unsigned int num_sect, struct iovec const *msg_sect);
227 223
228 int tipc_send2port(u32 portref, struct tipc_portid const *dest, 224 int tipc_send2port(u32 portref, struct tipc_portid const *dest,
229 unsigned int num_sect, struct iovec const *msg_sect); 225 unsigned int num_sect, struct iovec const *msg_sect);
230 226
231 int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest, 227 int tipc_send_buf2port(u32 portref, struct tipc_portid const *dest,
232 struct sk_buff *buf, unsigned int dsz); 228 struct sk_buff *buf, unsigned int dsz);
233 229
234 int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, 230 int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
235 unsigned int section_count, struct iovec const *msg); 231 unsigned int section_count, struct iovec const *msg);
236 232
237 int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, 233 int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr,
238 struct iovec const *msg_sect, u32 num_sect, 234 struct iovec const *msg_sect, u32 num_sect,
239 int err); 235 int err);
240 struct sk_buff *tipc_port_get_ports(void); 236 struct sk_buff *tipc_port_get_ports(void);
241 void tipc_port_recv_proto_msg(struct sk_buff *buf); 237 void tipc_port_recv_proto_msg(struct sk_buff *buf);
242 void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp); 238 void tipc_port_recv_mcast(struct sk_buff *buf, struct port_list *dp);
243 void tipc_port_reinit(void); 239 void tipc_port_reinit(void);
244 240
245 /** 241 /**
246 * tipc_port_lock - lock port instance referred to and return its pointer 242 * tipc_port_lock - lock port instance referred to and return its pointer
247 */ 243 */
248 244
249 static inline struct port *tipc_port_lock(u32 ref) 245 static inline struct port *tipc_port_lock(u32 ref)
250 { 246 {
251 return (struct port *)tipc_ref_lock(ref); 247 return (struct port *)tipc_ref_lock(ref);
252 } 248 }
253 249
254 /** 250 /**
255 * tipc_port_unlock - unlock a port instance 251 * tipc_port_unlock - unlock a port instance
256 * 252 *
257 * Can use pointer instead of tipc_ref_unlock() since port is already locked. 253 * Can use pointer instead of tipc_ref_unlock() since port is already locked.
258 */ 254 */
259 255
260 static inline void tipc_port_unlock(struct port *p_ptr) 256 static inline void tipc_port_unlock(struct port *p_ptr)
261 { 257 {
262 spin_unlock_bh(p_ptr->publ.lock); 258 spin_unlock_bh(p_ptr->publ.lock);
263 } 259 }
264 260
265 static inline struct port* tipc_port_deref(u32 ref) 261 static inline struct port* tipc_port_deref(u32 ref)
266 { 262 {
267 return (struct port *)tipc_ref_deref(ref); 263 return (struct port *)tipc_ref_deref(ref);
268 } 264 }
269 265
270 static inline u32 tipc_peer_port(struct port *p_ptr) 266 static inline u32 tipc_peer_port(struct port *p_ptr)
271 { 267 {
272 return msg_destport(&p_ptr->publ.phdr); 268 return msg_destport(&p_ptr->publ.phdr);
273 } 269 }
274 270
275 static inline u32 tipc_peer_node(struct port *p_ptr) 271 static inline u32 tipc_peer_node(struct port *p_ptr)
276 { 272 {
277 return msg_destnode(&p_ptr->publ.phdr); 273 return msg_destnode(&p_ptr->publ.phdr);
278 } 274 }
279 275
280 static inline int tipc_port_congested(struct port *p_ptr) 276 static inline int tipc_port_congested(struct port *p_ptr)
281 { 277 {
282 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); 278 return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2);
283 } 279 }
284 280
285 /** 281 /**
286 * tipc_port_recv_msg - receive message from lower layer and deliver to port user 282 * tipc_port_recv_msg - receive message from lower layer and deliver to port user
287 */ 283 */
288 284
289 static inline int tipc_port_recv_msg(struct sk_buff *buf) 285 static inline int tipc_port_recv_msg(struct sk_buff *buf)
290 { 286 {
291 struct port *p_ptr; 287 struct port *p_ptr;
292 struct tipc_msg *msg = buf_msg(buf); 288 struct tipc_msg *msg = buf_msg(buf);
293 u32 destport = msg_destport(msg); 289 u32 destport = msg_destport(msg);
294 u32 dsz = msg_data_sz(msg); 290 u32 dsz = msg_data_sz(msg);
295 u32 err; 291 u32 err;
296 292
297 /* forward unresolved named message */ 293 /* forward unresolved named message */
298 if (unlikely(!destport)) { 294 if (unlikely(!destport)) {
299 tipc_net_route_msg(buf); 295 tipc_net_route_msg(buf);
300 return dsz; 296 return dsz;
301 } 297 }
302 298
303 /* validate destination & pass to port, otherwise reject message */ 299 /* validate destination & pass to port, otherwise reject message */
304 p_ptr = tipc_port_lock(destport); 300 p_ptr = tipc_port_lock(destport);
305 if (likely(p_ptr)) { 301 if (likely(p_ptr)) {
306 if (likely(p_ptr->publ.connected)) { 302 if (likely(p_ptr->publ.connected)) {
307 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) || 303 if ((unlikely(msg_origport(msg) != tipc_peer_port(p_ptr))) ||
308 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) || 304 (unlikely(msg_orignode(msg) != tipc_peer_node(p_ptr))) ||
309 (unlikely(!msg_connected(msg)))) { 305 (unlikely(!msg_connected(msg)))) {
310 err = TIPC_ERR_NO_PORT; 306 err = TIPC_ERR_NO_PORT;
311 tipc_port_unlock(p_ptr); 307 tipc_port_unlock(p_ptr);
312 goto reject; 308 goto reject;
313 } 309 }
314 } 310 }
315 err = p_ptr->dispatcher(&p_ptr->publ, buf); 311 err = p_ptr->dispatcher(&p_ptr->publ, buf);
316 tipc_port_unlock(p_ptr); 312 tipc_port_unlock(p_ptr);
317 if (likely(!err)) 313 if (likely(!err))
318 return dsz; 314 return dsz;
319 } else { 315 } else {
320 err = TIPC_ERR_NO_PORT; 316 err = TIPC_ERR_NO_PORT;
321 } 317 }
322 reject: 318 reject:
323 dbg("port->rejecting, err = %x..\n",err); 319 dbg("port->rejecting, err = %x..\n",err);
324 return tipc_reject_msg(buf, err); 320 return tipc_reject_msg(buf, err);
325 } 321 }
326 322
327 #endif 323 #endif
328 324
1 /* 1 /*
2 * net/tipc/subscr.c: TIPC network topology service 2 * net/tipc/subscr.c: TIPC network topology service
3 * 3 *
4 * Copyright (c) 2000-2006, Ericsson AB 4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005-2007, Wind River Systems 5 * Copyright (c) 2005-2007, 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
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #include "core.h" 37 #include "core.h"
38 #include "name_table.h" 38 #include "name_table.h"
39 #include "port.h" 39 #include "port.h"
40 #include "subscr.h" 40 #include "subscr.h"
41 41
42 /** 42 /**
43 * struct subscriber - TIPC network topology subscriber 43 * struct subscriber - TIPC network topology subscriber
44 * @port_ref: object reference to server port connecting to subscriber 44 * @port_ref: object reference to server port connecting to subscriber
45 * @lock: pointer to spinlock controlling access to subscriber's server port 45 * @lock: pointer to spinlock controlling access to subscriber's server port
46 * @subscriber_list: adjacent subscribers in top. server's list of subscribers 46 * @subscriber_list: adjacent subscribers in top. server's list of subscribers
47 * @subscription_list: list of subscription objects for this subscriber 47 * @subscription_list: list of subscription objects for this subscriber
48 */ 48 */
49 49
50 struct subscriber { 50 struct subscriber {
51 u32 port_ref; 51 u32 port_ref;
52 spinlock_t *lock; 52 spinlock_t *lock;
53 struct list_head subscriber_list; 53 struct list_head subscriber_list;
54 struct list_head subscription_list; 54 struct list_head subscription_list;
55 }; 55 };
56 56
57 /** 57 /**
58 * struct top_srv - TIPC network topology subscription service 58 * struct top_srv - TIPC network topology subscription service
59 * @user_ref: TIPC userid of subscription service 59 * @user_ref: TIPC userid of subscription service
60 * @setup_port: reference to TIPC port that handles subscription requests 60 * @setup_port: reference to TIPC port that handles subscription requests
61 * @subscription_count: number of active subscriptions (not subscribers!) 61 * @subscription_count: number of active subscriptions (not subscribers!)
62 * @subscriber_list: list of ports subscribing to service 62 * @subscriber_list: list of ports subscribing to service
63 * @lock: spinlock govering access to subscriber list 63 * @lock: spinlock govering access to subscriber list
64 */ 64 */
65 65
66 struct top_srv { 66 struct top_srv {
67 u32 setup_port; 67 u32 setup_port;
68 atomic_t subscription_count; 68 atomic_t subscription_count;
69 struct list_head subscriber_list; 69 struct list_head subscriber_list;
70 spinlock_t lock; 70 spinlock_t lock;
71 }; 71 };
72 72
73 static struct top_srv topsrv = { 0 }; 73 static struct top_srv topsrv = { 0 };
74 74
75 /** 75 /**
76 * htohl - convert value to endianness used by destination 76 * htohl - convert value to endianness used by destination
77 * @in: value to convert 77 * @in: value to convert
78 * @swap: non-zero if endianness must be reversed 78 * @swap: non-zero if endianness must be reversed
79 * 79 *
80 * Returns converted value 80 * Returns converted value
81 */ 81 */
82 82
83 static u32 htohl(u32 in, int swap) 83 static u32 htohl(u32 in, int swap)
84 { 84 {
85 return swap ? swab32(in) : in; 85 return swap ? swab32(in) : in;
86 } 86 }
87 87
88 /** 88 /**
89 * subscr_send_event - send a message containing a tipc_event to the subscriber 89 * subscr_send_event - send a message containing a tipc_event to the subscriber
90 * 90 *
91 * Note: Must not hold subscriber's server port lock, since tipc_send() will 91 * Note: Must not hold subscriber's server port lock, since tipc_send() will
92 * try to take the lock if the message is rejected and returned! 92 * try to take the lock if the message is rejected and returned!
93 */ 93 */
94 94
95 static void subscr_send_event(struct subscription *sub, 95 static void subscr_send_event(struct subscription *sub,
96 u32 found_lower, 96 u32 found_lower,
97 u32 found_upper, 97 u32 found_upper,
98 u32 event, 98 u32 event,
99 u32 port_ref, 99 u32 port_ref,
100 u32 node) 100 u32 node)
101 { 101 {
102 struct iovec msg_sect; 102 struct iovec msg_sect;
103 103
104 msg_sect.iov_base = (void *)&sub->evt; 104 msg_sect.iov_base = (void *)&sub->evt;
105 msg_sect.iov_len = sizeof(struct tipc_event); 105 msg_sect.iov_len = sizeof(struct tipc_event);
106 106
107 sub->evt.event = htohl(event, sub->swap); 107 sub->evt.event = htohl(event, sub->swap);
108 sub->evt.found_lower = htohl(found_lower, sub->swap); 108 sub->evt.found_lower = htohl(found_lower, sub->swap);
109 sub->evt.found_upper = htohl(found_upper, sub->swap); 109 sub->evt.found_upper = htohl(found_upper, sub->swap);
110 sub->evt.port.ref = htohl(port_ref, sub->swap); 110 sub->evt.port.ref = htohl(port_ref, sub->swap);
111 sub->evt.port.node = htohl(node, sub->swap); 111 sub->evt.port.node = htohl(node, sub->swap);
112 tipc_send(sub->server_ref, 1, &msg_sect); 112 tipc_send(sub->server_ref, 1, &msg_sect);
113 } 113 }
114 114
115 /** 115 /**
116 * tipc_subscr_overlap - test for subscription overlap with the given values 116 * tipc_subscr_overlap - test for subscription overlap with the given values
117 * 117 *
118 * Returns 1 if there is overlap, otherwise 0. 118 * Returns 1 if there is overlap, otherwise 0.
119 */ 119 */
120 120
121 int tipc_subscr_overlap(struct subscription *sub, 121 int tipc_subscr_overlap(struct subscription *sub,
122 u32 found_lower, 122 u32 found_lower,
123 u32 found_upper) 123 u32 found_upper)
124 124
125 { 125 {
126 if (found_lower < sub->seq.lower) 126 if (found_lower < sub->seq.lower)
127 found_lower = sub->seq.lower; 127 found_lower = sub->seq.lower;
128 if (found_upper > sub->seq.upper) 128 if (found_upper > sub->seq.upper)
129 found_upper = sub->seq.upper; 129 found_upper = sub->seq.upper;
130 if (found_lower > found_upper) 130 if (found_lower > found_upper)
131 return 0; 131 return 0;
132 return 1; 132 return 1;
133 } 133 }
134 134
135 /** 135 /**
136 * tipc_subscr_report_overlap - issue event if there is subscription overlap 136 * tipc_subscr_report_overlap - issue event if there is subscription overlap
137 * 137 *
138 * Protected by nameseq.lock in name_table.c 138 * Protected by nameseq.lock in name_table.c
139 */ 139 */
140 140
141 void tipc_subscr_report_overlap(struct subscription *sub, 141 void tipc_subscr_report_overlap(struct subscription *sub,
142 u32 found_lower, 142 u32 found_lower,
143 u32 found_upper, 143 u32 found_upper,
144 u32 event, 144 u32 event,
145 u32 port_ref, 145 u32 port_ref,
146 u32 node, 146 u32 node,
147 int must) 147 int must)
148 { 148 {
149 if (!tipc_subscr_overlap(sub, found_lower, found_upper)) 149 if (!tipc_subscr_overlap(sub, found_lower, found_upper))
150 return; 150 return;
151 if (!must && !(sub->filter & TIPC_SUB_PORTS)) 151 if (!must && !(sub->filter & TIPC_SUB_PORTS))
152 return; 152 return;
153 153
154 sub->event_cb(sub, found_lower, found_upper, event, port_ref, node); 154 sub->event_cb(sub, found_lower, found_upper, event, port_ref, node);
155 } 155 }
156 156
157 /** 157 /**
158 * subscr_timeout - subscription timeout has occurred 158 * subscr_timeout - subscription timeout has occurred
159 */ 159 */
160 160
161 static void subscr_timeout(struct subscription *sub) 161 static void subscr_timeout(struct subscription *sub)
162 { 162 {
163 struct port *server_port; 163 struct port *server_port;
164 164
165 /* Validate server port reference (in case subscriber is terminating) */ 165 /* Validate server port reference (in case subscriber is terminating) */
166 166
167 server_port = tipc_port_lock(sub->server_ref); 167 server_port = tipc_port_lock(sub->server_ref);
168 if (server_port == NULL) 168 if (server_port == NULL)
169 return; 169 return;
170 170
171 /* Validate timeout (in case subscription is being cancelled) */ 171 /* Validate timeout (in case subscription is being cancelled) */
172 172
173 if (sub->timeout == TIPC_WAIT_FOREVER) { 173 if (sub->timeout == TIPC_WAIT_FOREVER) {
174 tipc_port_unlock(server_port); 174 tipc_port_unlock(server_port);
175 return; 175 return;
176 } 176 }
177 177
178 /* Unlink subscription from name table */ 178 /* Unlink subscription from name table */
179 179
180 tipc_nametbl_unsubscribe(sub); 180 tipc_nametbl_unsubscribe(sub);
181 181
182 /* Unlink subscription from subscriber */ 182 /* Unlink subscription from subscriber */
183 183
184 list_del(&sub->subscription_list); 184 list_del(&sub->subscription_list);
185 185
186 /* Release subscriber's server port */ 186 /* Release subscriber's server port */
187 187
188 tipc_port_unlock(server_port); 188 tipc_port_unlock(server_port);
189 189
190 /* Notify subscriber of timeout */ 190 /* Notify subscriber of timeout */
191 191
192 subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, 192 subscr_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
193 TIPC_SUBSCR_TIMEOUT, 0, 0); 193 TIPC_SUBSCR_TIMEOUT, 0, 0);
194 194
195 /* Now destroy subscription */ 195 /* Now destroy subscription */
196 196
197 k_term_timer(&sub->timer); 197 k_term_timer(&sub->timer);
198 kfree(sub); 198 kfree(sub);
199 atomic_dec(&topsrv.subscription_count); 199 atomic_dec(&topsrv.subscription_count);
200 } 200 }
201 201
202 /** 202 /**
203 * subscr_del - delete a subscription within a subscription list 203 * subscr_del - delete a subscription within a subscription list
204 * 204 *
205 * Called with subscriber port locked. 205 * Called with subscriber port locked.
206 */ 206 */
207 207
208 static void subscr_del(struct subscription *sub) 208 static void subscr_del(struct subscription *sub)
209 { 209 {
210 tipc_nametbl_unsubscribe(sub); 210 tipc_nametbl_unsubscribe(sub);
211 list_del(&sub->subscription_list); 211 list_del(&sub->subscription_list);
212 kfree(sub); 212 kfree(sub);
213 atomic_dec(&topsrv.subscription_count); 213 atomic_dec(&topsrv.subscription_count);
214 } 214 }
215 215
216 /** 216 /**
217 * subscr_terminate - terminate communication with a subscriber 217 * subscr_terminate - terminate communication with a subscriber
218 * 218 *
219 * Called with subscriber port locked. Routine must temporarily release lock 219 * Called with subscriber port locked. Routine must temporarily release lock
220 * to enable subscription timeout routine(s) to finish without deadlocking; 220 * to enable subscription timeout routine(s) to finish without deadlocking;
221 * the lock is then reclaimed to allow caller to release it upon return. 221 * the lock is then reclaimed to allow caller to release it upon return.
222 * (This should work even in the unlikely event some other thread creates 222 * (This should work even in the unlikely event some other thread creates
223 * a new object reference in the interim that uses this lock; this routine will 223 * a new object reference in the interim that uses this lock; this routine will
224 * simply wait for it to be released, then claim it.) 224 * simply wait for it to be released, then claim it.)
225 */ 225 */
226 226
227 static void subscr_terminate(struct subscriber *subscriber) 227 static void subscr_terminate(struct subscriber *subscriber)
228 { 228 {
229 u32 port_ref; 229 u32 port_ref;
230 struct subscription *sub; 230 struct subscription *sub;
231 struct subscription *sub_temp; 231 struct subscription *sub_temp;
232 232
233 /* Invalidate subscriber reference */ 233 /* Invalidate subscriber reference */
234 234
235 port_ref = subscriber->port_ref; 235 port_ref = subscriber->port_ref;
236 subscriber->port_ref = 0; 236 subscriber->port_ref = 0;
237 spin_unlock_bh(subscriber->lock); 237 spin_unlock_bh(subscriber->lock);
238 238
239 /* Sever connection to subscriber */ 239 /* Sever connection to subscriber */
240 240
241 tipc_shutdown(port_ref); 241 tipc_shutdown(port_ref);
242 tipc_deleteport(port_ref); 242 tipc_deleteport(port_ref);
243 243
244 /* Destroy any existing subscriptions for subscriber */ 244 /* Destroy any existing subscriptions for subscriber */
245 245
246 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, 246 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
247 subscription_list) { 247 subscription_list) {
248 if (sub->timeout != TIPC_WAIT_FOREVER) { 248 if (sub->timeout != TIPC_WAIT_FOREVER) {
249 k_cancel_timer(&sub->timer); 249 k_cancel_timer(&sub->timer);
250 k_term_timer(&sub->timer); 250 k_term_timer(&sub->timer);
251 } 251 }
252 dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n", 252 dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
253 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); 253 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
254 subscr_del(sub); 254 subscr_del(sub);
255 } 255 }
256 256
257 /* Remove subscriber from topology server's subscriber list */ 257 /* Remove subscriber from topology server's subscriber list */
258 258
259 spin_lock_bh(&topsrv.lock); 259 spin_lock_bh(&topsrv.lock);
260 list_del(&subscriber->subscriber_list); 260 list_del(&subscriber->subscriber_list);
261 spin_unlock_bh(&topsrv.lock); 261 spin_unlock_bh(&topsrv.lock);
262 262
263 /* Reclaim subscriber lock */ 263 /* Reclaim subscriber lock */
264 264
265 spin_lock_bh(subscriber->lock); 265 spin_lock_bh(subscriber->lock);
266 266
267 /* Now destroy subscriber */ 267 /* Now destroy subscriber */
268 268
269 kfree(subscriber); 269 kfree(subscriber);
270 } 270 }
271 271
272 /** 272 /**
273 * subscr_cancel - handle subscription cancellation request 273 * subscr_cancel - handle subscription cancellation request
274 * 274 *
275 * Called with subscriber port locked. Routine must temporarily release lock 275 * Called with subscriber port locked. Routine must temporarily release lock
276 * to enable the subscription timeout routine to finish without deadlocking; 276 * to enable the subscription timeout routine to finish without deadlocking;
277 * the lock is then reclaimed to allow caller to release it upon return. 277 * the lock is then reclaimed to allow caller to release it upon return.
278 * 278 *
279 * Note that fields of 's' use subscriber's endianness! 279 * Note that fields of 's' use subscriber's endianness!
280 */ 280 */
281 281
282 static void subscr_cancel(struct tipc_subscr *s, 282 static void subscr_cancel(struct tipc_subscr *s,
283 struct subscriber *subscriber) 283 struct subscriber *subscriber)
284 { 284 {
285 struct subscription *sub; 285 struct subscription *sub;
286 struct subscription *sub_temp; 286 struct subscription *sub_temp;
287 int found = 0; 287 int found = 0;
288 288
289 /* Find first matching subscription, exit if not found */ 289 /* Find first matching subscription, exit if not found */
290 290
291 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, 291 list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
292 subscription_list) { 292 subscription_list) {
293 if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { 293 if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
294 found = 1; 294 found = 1;
295 break; 295 break;
296 } 296 }
297 } 297 }
298 if (!found) 298 if (!found)
299 return; 299 return;
300 300
301 /* Cancel subscription timer (if used), then delete subscription */ 301 /* Cancel subscription timer (if used), then delete subscription */
302 302
303 if (sub->timeout != TIPC_WAIT_FOREVER) { 303 if (sub->timeout != TIPC_WAIT_FOREVER) {
304 sub->timeout = TIPC_WAIT_FOREVER; 304 sub->timeout = TIPC_WAIT_FOREVER;
305 spin_unlock_bh(subscriber->lock); 305 spin_unlock_bh(subscriber->lock);
306 k_cancel_timer(&sub->timer); 306 k_cancel_timer(&sub->timer);
307 k_term_timer(&sub->timer); 307 k_term_timer(&sub->timer);
308 spin_lock_bh(subscriber->lock); 308 spin_lock_bh(subscriber->lock);
309 } 309 }
310 dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", 310 dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
311 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); 311 sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
312 subscr_del(sub); 312 subscr_del(sub);
313 } 313 }
314 314
315 /** 315 /**
316 * subscr_subscribe - create subscription for subscriber 316 * subscr_subscribe - create subscription for subscriber
317 * 317 *
318 * Called with subscriber port locked. 318 * Called with subscriber port locked.
319 */ 319 */
320 320
321 static struct subscription *subscr_subscribe(struct tipc_subscr *s, 321 static struct subscription *subscr_subscribe(struct tipc_subscr *s,
322 struct subscriber *subscriber) 322 struct subscriber *subscriber)
323 { 323 {
324 struct subscription *sub; 324 struct subscription *sub;
325 int swap; 325 int swap;
326 326
327 /* Determine subscriber's endianness */ 327 /* Determine subscriber's endianness */
328 328
329 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); 329 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
330 330
331 /* Detect & process a subscription cancellation request */ 331 /* Detect & process a subscription cancellation request */
332 332
333 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { 333 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
334 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); 334 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
335 subscr_cancel(s, subscriber); 335 subscr_cancel(s, subscriber);
336 return NULL; 336 return NULL;
337 } 337 }
338 338
339 /* Refuse subscription if global limit exceeded */ 339 /* Refuse subscription if global limit exceeded */
340 340
341 if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { 341 if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) {
342 warn("Subscription rejected, subscription limit reached (%u)\n", 342 warn("Subscription rejected, subscription limit reached (%u)\n",
343 tipc_max_subscriptions); 343 tipc_max_subscriptions);
344 subscr_terminate(subscriber); 344 subscr_terminate(subscriber);
345 return NULL; 345 return NULL;
346 } 346 }
347 347
348 /* Allocate subscription object */ 348 /* Allocate subscription object */
349 349
350 sub = kmalloc(sizeof(*sub), GFP_ATOMIC); 350 sub = kmalloc(sizeof(*sub), GFP_ATOMIC);
351 if (!sub) { 351 if (!sub) {
352 warn("Subscription rejected, no memory\n"); 352 warn("Subscription rejected, no memory\n");
353 subscr_terminate(subscriber); 353 subscr_terminate(subscriber);
354 return NULL; 354 return NULL;
355 } 355 }
356 356
357 /* Initialize subscription object */ 357 /* Initialize subscription object */
358 358
359 sub->seq.type = htohl(s->seq.type, swap); 359 sub->seq.type = htohl(s->seq.type, swap);
360 sub->seq.lower = htohl(s->seq.lower, swap); 360 sub->seq.lower = htohl(s->seq.lower, swap);
361 sub->seq.upper = htohl(s->seq.upper, swap); 361 sub->seq.upper = htohl(s->seq.upper, swap);
362 sub->timeout = htohl(s->timeout, swap); 362 sub->timeout = htohl(s->timeout, swap);
363 sub->filter = htohl(s->filter, swap); 363 sub->filter = htohl(s->filter, swap);
364 if ((!(sub->filter & TIPC_SUB_PORTS) == 364 if ((!(sub->filter & TIPC_SUB_PORTS) ==
365 !(sub->filter & TIPC_SUB_SERVICE)) || 365 !(sub->filter & TIPC_SUB_SERVICE)) ||
366 (sub->seq.lower > sub->seq.upper)) { 366 (sub->seq.lower > sub->seq.upper)) {
367 warn("Subscription rejected, illegal request\n"); 367 warn("Subscription rejected, illegal request\n");
368 kfree(sub); 368 kfree(sub);
369 subscr_terminate(subscriber); 369 subscr_terminate(subscriber);
370 return NULL; 370 return NULL;
371 } 371 }
372 sub->event_cb = subscr_send_event; 372 sub->event_cb = subscr_send_event;
373 INIT_LIST_HEAD(&sub->nameseq_list); 373 INIT_LIST_HEAD(&sub->nameseq_list);
374 list_add(&sub->subscription_list, &subscriber->subscription_list); 374 list_add(&sub->subscription_list, &subscriber->subscription_list);
375 sub->server_ref = subscriber->port_ref; 375 sub->server_ref = subscriber->port_ref;
376 sub->swap = swap; 376 sub->swap = swap;
377 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); 377 memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr));
378 atomic_inc(&topsrv.subscription_count); 378 atomic_inc(&topsrv.subscription_count);
379 if (sub->timeout != TIPC_WAIT_FOREVER) { 379 if (sub->timeout != TIPC_WAIT_FOREVER) {
380 k_init_timer(&sub->timer, 380 k_init_timer(&sub->timer,
381 (Handler)subscr_timeout, (unsigned long)sub); 381 (Handler)subscr_timeout, (unsigned long)sub);
382 k_start_timer(&sub->timer, sub->timeout); 382 k_start_timer(&sub->timer, sub->timeout);
383 } 383 }
384 384
385 return sub; 385 return sub;
386 } 386 }
387 387
388 /** 388 /**
389 * subscr_conn_shutdown_event - handle termination request from subscriber 389 * subscr_conn_shutdown_event - handle termination request from subscriber
390 * 390 *
391 * Called with subscriber's server port unlocked. 391 * Called with subscriber's server port unlocked.
392 */ 392 */
393 393
394 static void subscr_conn_shutdown_event(void *usr_handle, 394 static void subscr_conn_shutdown_event(void *usr_handle,
395 u32 port_ref, 395 u32 port_ref,
396 struct sk_buff **buf, 396 struct sk_buff **buf,
397 unsigned char const *data, 397 unsigned char const *data,
398 unsigned int size, 398 unsigned int size,
399 int reason) 399 int reason)
400 { 400 {
401 struct subscriber *subscriber = usr_handle; 401 struct subscriber *subscriber = usr_handle;
402 spinlock_t *subscriber_lock; 402 spinlock_t *subscriber_lock;
403 403
404 if (tipc_port_lock(port_ref) == NULL) 404 if (tipc_port_lock(port_ref) == NULL)
405 return; 405 return;
406 406
407 subscriber_lock = subscriber->lock; 407 subscriber_lock = subscriber->lock;
408 subscr_terminate(subscriber); 408 subscr_terminate(subscriber);
409 spin_unlock_bh(subscriber_lock); 409 spin_unlock_bh(subscriber_lock);
410 } 410 }
411 411
412 /** 412 /**
413 * subscr_conn_msg_event - handle new subscription request from subscriber 413 * subscr_conn_msg_event - handle new subscription request from subscriber
414 * 414 *
415 * Called with subscriber's server port unlocked. 415 * Called with subscriber's server port unlocked.
416 */ 416 */
417 417
418 static void subscr_conn_msg_event(void *usr_handle, 418 static void subscr_conn_msg_event(void *usr_handle,
419 u32 port_ref, 419 u32 port_ref,
420 struct sk_buff **buf, 420 struct sk_buff **buf,
421 const unchar *data, 421 const unchar *data,
422 u32 size) 422 u32 size)
423 { 423 {
424 struct subscriber *subscriber = usr_handle; 424 struct subscriber *subscriber = usr_handle;
425 spinlock_t *subscriber_lock; 425 spinlock_t *subscriber_lock;
426 struct subscription *sub; 426 struct subscription *sub;
427 427
428 /* 428 /*
429 * Lock subscriber's server port (& make a local copy of lock pointer, 429 * Lock subscriber's server port (& make a local copy of lock pointer,
430 * in case subscriber is deleted while processing subscription request) 430 * in case subscriber is deleted while processing subscription request)
431 */ 431 */
432 432
433 if (tipc_port_lock(port_ref) == NULL) 433 if (tipc_port_lock(port_ref) == NULL)
434 return; 434 return;
435 435
436 subscriber_lock = subscriber->lock; 436 subscriber_lock = subscriber->lock;
437 437
438 if (size != sizeof(struct tipc_subscr)) { 438 if (size != sizeof(struct tipc_subscr)) {
439 subscr_terminate(subscriber); 439 subscr_terminate(subscriber);
440 spin_unlock_bh(subscriber_lock); 440 spin_unlock_bh(subscriber_lock);
441 } else { 441 } else {
442 sub = subscr_subscribe((struct tipc_subscr *)data, subscriber); 442 sub = subscr_subscribe((struct tipc_subscr *)data, subscriber);
443 spin_unlock_bh(subscriber_lock); 443 spin_unlock_bh(subscriber_lock);
444 if (sub != NULL) { 444 if (sub != NULL) {
445 445
446 /* 446 /*
447 * We must release the server port lock before adding a 447 * We must release the server port lock before adding a
448 * subscription to the name table since TIPC needs to be 448 * subscription to the name table since TIPC needs to be
449 * able to (re)acquire the port lock if an event message 449 * able to (re)acquire the port lock if an event message
450 * issued by the subscription process is rejected and 450 * issued by the subscription process is rejected and
451 * returned. The subscription cannot be deleted while 451 * returned. The subscription cannot be deleted while
452 * it is being added to the name table because: 452 * it is being added to the name table because:
453 * a) the single-threading of the native API port code 453 * a) the single-threading of the native API port code
454 * ensures the subscription cannot be cancelled and 454 * ensures the subscription cannot be cancelled and
455 * the subscriber connection cannot be broken, and 455 * the subscriber connection cannot be broken, and
456 * b) the name table lock ensures the subscription 456 * b) the name table lock ensures the subscription
457 * timeout code cannot delete the subscription, 457 * timeout code cannot delete the subscription,
458 * so the subscription object is still protected. 458 * so the subscription object is still protected.
459 */ 459 */
460 460
461 tipc_nametbl_subscribe(sub); 461 tipc_nametbl_subscribe(sub);
462 } 462 }
463 } 463 }
464 } 464 }
465 465
466 /** 466 /**
467 * subscr_named_msg_event - handle request to establish a new subscriber 467 * subscr_named_msg_event - handle request to establish a new subscriber
468 */ 468 */
469 469
470 static void subscr_named_msg_event(void *usr_handle, 470 static void subscr_named_msg_event(void *usr_handle,
471 u32 port_ref, 471 u32 port_ref,
472 struct sk_buff **buf, 472 struct sk_buff **buf,
473 const unchar *data, 473 const unchar *data,
474 u32 size, 474 u32 size,
475 u32 importance, 475 u32 importance,
476 struct tipc_portid const *orig, 476 struct tipc_portid const *orig,
477 struct tipc_name_seq const *dest) 477 struct tipc_name_seq const *dest)
478 { 478 {
479 static struct iovec msg_sect = {NULL, 0}; 479 static struct iovec msg_sect = {NULL, 0};
480 480
481 struct subscriber *subscriber; 481 struct subscriber *subscriber;
482 u32 server_port_ref; 482 u32 server_port_ref;
483 483
484 /* Create subscriber object */ 484 /* Create subscriber object */
485 485
486 subscriber = kzalloc(sizeof(struct subscriber), GFP_ATOMIC); 486 subscriber = kzalloc(sizeof(struct subscriber), GFP_ATOMIC);
487 if (subscriber == NULL) { 487 if (subscriber == NULL) {
488 warn("Subscriber rejected, no memory\n"); 488 warn("Subscriber rejected, no memory\n");
489 return; 489 return;
490 } 490 }
491 INIT_LIST_HEAD(&subscriber->subscription_list); 491 INIT_LIST_HEAD(&subscriber->subscription_list);
492 INIT_LIST_HEAD(&subscriber->subscriber_list); 492 INIT_LIST_HEAD(&subscriber->subscriber_list);
493 493
494 /* Create server port & establish connection to subscriber */ 494 /* Create server port & establish connection to subscriber */
495 495
496 tipc_createport(0, 496 tipc_createport(subscriber,
497 subscriber,
498 importance, 497 importance,
499 NULL, 498 NULL,
500 NULL, 499 NULL,
501 subscr_conn_shutdown_event, 500 subscr_conn_shutdown_event,
502 NULL, 501 NULL,
503 NULL, 502 NULL,
504 subscr_conn_msg_event, 503 subscr_conn_msg_event,
505 NULL, 504 NULL,
506 &subscriber->port_ref); 505 &subscriber->port_ref);
507 if (subscriber->port_ref == 0) { 506 if (subscriber->port_ref == 0) {
508 warn("Subscriber rejected, unable to create port\n"); 507 warn("Subscriber rejected, unable to create port\n");
509 kfree(subscriber); 508 kfree(subscriber);
510 return; 509 return;
511 } 510 }
512 tipc_connect2port(subscriber->port_ref, orig); 511 tipc_connect2port(subscriber->port_ref, orig);
513 512
514 /* Lock server port (& save lock address for future use) */ 513 /* Lock server port (& save lock address for future use) */
515 514
516 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock; 515 subscriber->lock = tipc_port_lock(subscriber->port_ref)->publ.lock;
517 516
518 /* Add subscriber to topology server's subscriber list */ 517 /* Add subscriber to topology server's subscriber list */
519 518
520 spin_lock_bh(&topsrv.lock); 519 spin_lock_bh(&topsrv.lock);
521 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); 520 list_add(&subscriber->subscriber_list, &topsrv.subscriber_list);
522 spin_unlock_bh(&topsrv.lock); 521 spin_unlock_bh(&topsrv.lock);
523 522
524 /* Unlock server port */ 523 /* Unlock server port */
525 524
526 server_port_ref = subscriber->port_ref; 525 server_port_ref = subscriber->port_ref;
527 spin_unlock_bh(subscriber->lock); 526 spin_unlock_bh(subscriber->lock);
528 527
529 /* Send an ACK- to complete connection handshaking */ 528 /* Send an ACK- to complete connection handshaking */
530 529
531 tipc_send(server_port_ref, 1, &msg_sect); 530 tipc_send(server_port_ref, 1, &msg_sect);
532 531
533 /* Handle optional subscription request */ 532 /* Handle optional subscription request */
534 533
535 if (size != 0) { 534 if (size != 0) {
536 subscr_conn_msg_event(subscriber, server_port_ref, 535 subscr_conn_msg_event(subscriber, server_port_ref,
537 buf, data, size); 536 buf, data, size);
538 } 537 }
539 } 538 }
540 539
541 int tipc_subscr_start(void) 540 int tipc_subscr_start(void)
542 { 541 {
543 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; 542 struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV};
544 int res; 543 int res;
545 544
546 memset(&topsrv, 0, sizeof (topsrv)); 545 memset(&topsrv, 0, sizeof (topsrv));
547 spin_lock_init(&topsrv.lock); 546 spin_lock_init(&topsrv.lock);
548 INIT_LIST_HEAD(&topsrv.subscriber_list); 547 INIT_LIST_HEAD(&topsrv.subscriber_list);
549 548
550 spin_lock_bh(&topsrv.lock); 549 spin_lock_bh(&topsrv.lock);
551 res = tipc_createport(0, 550 res = tipc_createport(NULL,
552 NULL,
553 TIPC_CRITICAL_IMPORTANCE, 551 TIPC_CRITICAL_IMPORTANCE,
554 NULL, 552 NULL,
555 NULL, 553 NULL,
556 NULL, 554 NULL,
557 NULL, 555 NULL,
558 subscr_named_msg_event, 556 subscr_named_msg_event,
559 NULL, 557 NULL,
560 NULL, 558 NULL,
561 &topsrv.setup_port); 559 &topsrv.setup_port);
562 if (res) 560 if (res)
563 goto failed; 561 goto failed;
564 562
565 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); 563 res = tipc_nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq);
566 if (res) { 564 if (res) {
567 tipc_deleteport(topsrv.setup_port); 565 tipc_deleteport(topsrv.setup_port);
568 topsrv.setup_port = 0; 566 topsrv.setup_port = 0;
569 goto failed; 567 goto failed;
570 } 568 }
571 569
572 spin_unlock_bh(&topsrv.lock); 570 spin_unlock_bh(&topsrv.lock);
573 return 0; 571 return 0;
574 572
575 failed: 573 failed:
576 err("Failed to create subscription service\n"); 574 err("Failed to create subscription service\n");
577 spin_unlock_bh(&topsrv.lock); 575 spin_unlock_bh(&topsrv.lock);
578 return res; 576 return res;
579 } 577 }
580 578
581 void tipc_subscr_stop(void) 579 void tipc_subscr_stop(void)
582 { 580 {
583 struct subscriber *subscriber; 581 struct subscriber *subscriber;
584 struct subscriber *subscriber_temp; 582 struct subscriber *subscriber_temp;
585 spinlock_t *subscriber_lock; 583 spinlock_t *subscriber_lock;
586 584
587 if (topsrv.setup_port) { 585 if (topsrv.setup_port) {
588 tipc_deleteport(topsrv.setup_port); 586 tipc_deleteport(topsrv.setup_port);
589 topsrv.setup_port = 0; 587 topsrv.setup_port = 0;
590 588
591 list_for_each_entry_safe(subscriber, subscriber_temp, 589 list_for_each_entry_safe(subscriber, subscriber_temp,
592 &topsrv.subscriber_list, 590 &topsrv.subscriber_list,
593 subscriber_list) { 591 subscriber_list) {
594 subscriber_lock = subscriber->lock; 592 subscriber_lock = subscriber->lock;
595 spin_lock_bh(subscriber_lock); 593 spin_lock_bh(subscriber_lock);
596 subscr_terminate(subscriber); 594 subscr_terminate(subscriber);
597 spin_unlock_bh(subscriber_lock); 595 spin_unlock_bh(subscriber_lock);
598 } 596 }
599 } 597 }
600 } 598 }
601 599
net/tipc/user_reg.c
1 /* File was deleted
2 * net/tipc/user_reg.c: TIPC user registry code
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #include "core.h"
38 #include "user_reg.h"
39
40 /*
41 * TIPC user registry keeps track of users of the tipc_port interface.
42 *
43 * The registry utilizes an array of "TIPC user" entries;
44 * a user's ID is the index of their associated array entry.
45 * Array entry 0 is not used, so userid 0 is not valid;
46 * TIPC sometimes uses this value to denote an anonymous user.
47 * The list of free entries is initially chained from last entry to entry 1.
48 */
49
50 /**
51 * struct tipc_user - registered TIPC user info
52 * @next: index of next free registry entry (or -1 for an allocated entry)
53 * @ports: list of user ports owned by the user
54 */
55
56 struct tipc_user {
57 int next;
58 struct list_head ports;
59 };
60
61 #define MAX_USERID 64
62 #define USER_LIST_SIZE ((MAX_USERID + 1) * sizeof(struct tipc_user))
63
64 static struct tipc_user *users = NULL;
65 static u32 next_free_user = MAX_USERID + 1;
66 static DEFINE_SPINLOCK(reg_lock);
67
68 /**
69 * reg_init - create TIPC user registry (but don't activate it)
70 *
71 * If registry has been pre-initialized it is left "as is".
72 * NOTE: This routine may be called when TIPC is inactive.
73 */
74
75 static int reg_init(void)
76 {
77 u32 i;
78
79 spin_lock_bh(&reg_lock);
80 if (!users) {
81 users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC);
82 if (users) {
83 for (i = 1; i <= MAX_USERID; i++) {
84 users[i].next = i - 1;
85 }
86 next_free_user = MAX_USERID;
87 }
88 }
89 spin_unlock_bh(&reg_lock);
90 return users ? 0 : -ENOMEM;
91 }
92
93 /**
94 * tipc_reg_start - activate TIPC user registry
95 */
96
97 int tipc_reg_start(void)
98 {
99 return reg_init();
100 }
101
102 /**
103 * tipc_reg_stop - shut down & delete TIPC user registry
104 */
105
106 void tipc_reg_stop(void)
107 {
108 if (!users)
109 return;
110
111 kfree(users);
112 users = NULL;
113 }
114
115 /**
116 * tipc_attach - register a TIPC user
117 *
118 * NOTE: This routine may be called when TIPC is inactive.
119 */
120
121 int tipc_attach(u32 *userid)
122 {
123 struct tipc_user *user_ptr;
124
125 if (!users)
126 reg_init();
127
128 spin_lock_bh(&reg_lock);
129 if (!next_free_user) {
130 spin_unlock_bh(&reg_lock);
131 return -EBUSY;
132 }
133 user_ptr = &users[next_free_user];
134 *userid = next_free_user;
135 next_free_user = user_ptr->next;
136 user_ptr->next = -1;
137 spin_unlock_bh(&reg_lock);
138
139 INIT_LIST_HEAD(&user_ptr->ports);
140 atomic_inc(&tipc_user_count);
141
142 return 0;
143 }
144
145 /**
146 * tipc_detach - deregister a TIPC user
147 */
148
149 void tipc_detach(u32 userid)
150 {
151 struct tipc_user *user_ptr;
152 struct list_head ports_temp;
153 struct user_port *up_ptr, *temp_up_ptr;
154
155 if ((userid == 0) || (userid > MAX_USERID))
156 return;
157
158 spin_lock_bh(&reg_lock);
159 if ((!users) || (users[userid].next >= 0)) {
160 spin_unlock_bh(&reg_lock);
161 return;
162 }
163
164 user_ptr = &users[userid];
165 INIT_LIST_HEAD(&ports_temp);
166 list_splice(&user_ptr->ports, &ports_temp);
167 user_ptr->next = next_free_user;
168 next_free_user = userid;
169 spin_unlock_bh(&reg_lock);
170
171 atomic_dec(&tipc_user_count);
172
173 list_for_each_entry_safe(up_ptr, temp_up_ptr, &ports_temp, uport_list) {
174 tipc_deleteport(up_ptr->ref);
175 }
176 }
177
178 /**
179 * tipc_reg_add_port - register a user's driver port
180 */
181
182 int tipc_reg_add_port(struct user_port *up_ptr)
183 {
184 struct tipc_user *user_ptr;
185
186 if (up_ptr->user_ref == 0)
187 return 0;
188 if (up_ptr->user_ref > MAX_USERID)
189 return -EINVAL;
190 if ((tipc_mode == TIPC_NOT_RUNNING) || !users )
191 return -ENOPROTOOPT;
192
193 spin_lock_bh(&reg_lock);
194 user_ptr = &users[up_ptr->user_ref];
195 list_add(&up_ptr->uport_list, &user_ptr->ports);
196 spin_unlock_bh(&reg_lock);
197 return 0;
198 }
199
200 /**
201 * tipc_reg_remove_port - deregister a user's driver port
202 */
203
204 int tipc_reg_remove_port(struct user_port *up_ptr)
205 {
206 if (up_ptr->user_ref == 0)
207 return 0;
208 if (up_ptr->user_ref > MAX_USERID)
209 return -EINVAL;
210 if (!users )
211 return -ENOPROTOOPT;
212
213 spin_lock_bh(&reg_lock);
214 list_del_init(&up_ptr->uport_list);
215 spin_unlock_bh(&reg_lock);
216 return 0;
217 }
218 1 /*
219 2 * net/tipc/user_reg.c: TIPC user registry code
net/tipc/user_reg.h
1 /* File was deleted
2 * net/tipc/user_reg.h: Include file for TIPC user registry code
3 *
4 * Copyright (c) 2000-2006, Ericsson AB
5 * Copyright (c) 2005, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #ifndef _TIPC_USER_REG_H
38 #define _TIPC_USER_REG_H
39
40 #include "port.h"
41
42 int tipc_reg_start(void);
43 void tipc_reg_stop(void);
44
45 int tipc_attach(unsigned int *userref);
46 void tipc_detach(unsigned int userref);
47
48 int tipc_reg_add_port(struct user_port *up_ptr);
49 int tipc_reg_remove_port(struct user_port *up_ptr);
50
51 #endif
52 1 /*