Blame view

net/tipc/config.c 14.6 KB
b97bf3fd8   Per Liden   [TIPC] Initial merge
1
2
  /*
   * net/tipc/config.c: TIPC configuration management code
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
3
   *
593a5f22d   Per Liden   [TIPC] More updat...
4
   * Copyright (c) 2002-2006, Ericsson AB
f831c963b   Allan Stephens   tipc: Eliminate c...
5
   * Copyright (c) 2004-2007, 2010-2011, Wind River Systems
b97bf3fd8   Per Liden   [TIPC] Initial merge
6
7
   * All rights reserved.
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
8
   * Redistribution and use in source and binary forms, with or without
b97bf3fd8   Per Liden   [TIPC] Initial merge
9
10
   * modification, are permitted provided that the following conditions are met:
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
11
12
13
14
15
16
17
18
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 3. Neither the names of the copyright holders nor the names of its
   *    contributors may be used to endorse or promote products derived from
   *    this software without specific prior written permission.
b97bf3fd8   Per Liden   [TIPC] Initial merge
19
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
b97bf3fd8   Per Liden   [TIPC] Initial merge
34
35
36
37
   * POSSIBILITY OF SUCH DAMAGE.
   */
  
  #include "core.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
38
  #include "port.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
39
  #include "name_table.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
40
  #include "config.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
41

7a488fd3d   Allan Stephens   tipc: Eliminate u...
42
  static u32 config_port_ref;
b97bf3fd8   Per Liden   [TIPC] Initial merge
43

34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
44
  static DEFINE_SPINLOCK(config_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
45
46
47
48
  
  static const void *req_tlv_area;	/* request message TLV area */
  static int req_tlv_space;		/* request message TLV area size */
  static int rep_headroom;		/* reply message headroom to use */
4323add67   Per Liden   [TIPC] Avoid poll...
49
  struct sk_buff *tipc_cfg_reply_alloc(int payload_size)
b97bf3fd8   Per Liden   [TIPC] Initial merge
50
51
52
53
54
55
56
57
  {
  	struct sk_buff *buf;
  
  	buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC);
  	if (buf)
  		skb_reserve(buf, rep_headroom);
  	return buf;
  }
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
58
  int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
4323add67   Per Liden   [TIPC] Avoid poll...
59
  			void *tlv_data, int tlv_data_size)
b97bf3fd8   Per Liden   [TIPC] Initial merge
60
  {
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
61
  	struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);
b97bf3fd8   Per Liden   [TIPC] Initial merge
62
  	int new_tlv_space = TLV_SPACE(tlv_data_size);
b29f14284   Allan Stephens   tipc: remove call...
63
  	if (skb_tailroom(buf) < new_tlv_space)
b97bf3fd8   Per Liden   [TIPC] Initial merge
64
  		return 0;
b97bf3fd8   Per Liden   [TIPC] Initial merge
65
66
67
68
69
70
71
  	skb_put(buf, new_tlv_space);
  	tlv->tlv_type = htons(tlv_type);
  	tlv->tlv_len  = htons(TLV_LENGTH(tlv_data_size));
  	if (tlv_data_size && tlv_data)
  		memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size);
  	return 1;
  }
31e3c3f6f   stephen hemminger   tipc: cleanup fun...
72
  static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
b97bf3fd8   Per Liden   [TIPC] Initial merge
73
74
  {
  	struct sk_buff *buf;
3e6c8cd56   Al Viro   [TIPC]: endiannes...
75
  	__be32 value_net;
b97bf3fd8   Per Liden   [TIPC] Initial merge
76

4323add67   Per Liden   [TIPC] Avoid poll...
77
  	buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value)));
b97bf3fd8   Per Liden   [TIPC] Initial merge
78
79
  	if (buf) {
  		value_net = htonl(value);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
80
  		tipc_cfg_append_tlv(buf, tlv_type, &value_net,
4323add67   Per Liden   [TIPC] Avoid poll...
81
  				    sizeof(value_net));
b97bf3fd8   Per Liden   [TIPC] Initial merge
82
83
84
  	}
  	return buf;
  }
31e3c3f6f   stephen hemminger   tipc: cleanup fun...
85
86
87
88
  static struct sk_buff *tipc_cfg_reply_unsigned(u32 value)
  {
  	return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value);
  }
4323add67   Per Liden   [TIPC] Avoid poll...
89
  struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string)
b97bf3fd8   Per Liden   [TIPC] Initial merge
90
91
92
  {
  	struct sk_buff *buf;
  	int string_len = strlen(string) + 1;
4323add67   Per Liden   [TIPC] Avoid poll...
93
  	buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len));
b97bf3fd8   Per Liden   [TIPC] Initial merge
94
  	if (buf)
4323add67   Per Liden   [TIPC] Avoid poll...
95
  		tipc_cfg_append_tlv(buf, tlv_type, string, string_len);
b97bf3fd8   Per Liden   [TIPC] Initial merge
96
97
  	return buf;
  }
107e7be62   Allan Stephens   tipc: Add support...
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  #define MAX_STATS_INFO 2000
  
  static struct sk_buff *tipc_show_stats(void)
  {
  	struct sk_buff *buf;
  	struct tlv_desc *rep_tlv;
  	struct print_buf pb;
  	int str_len;
  	u32 value;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
  
  	value = ntohl(*(u32 *)TLV_DATA(req_tlv_area));
  	if (value != 0)
  		return tipc_cfg_reply_error_string("unsupported argument");
  
  	buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_STATS_INFO));
  	if (buf == NULL)
  		return NULL;
  
  	rep_tlv = (struct tlv_desc *)buf->data;
  	tipc_printbuf_init(&pb, (char *)TLV_DATA(rep_tlv), MAX_STATS_INFO);
  
  	tipc_printf(&pb, "TIPC version " TIPC_MOD_VER "
  ");
  
  	/* Use additional tipc_printf()'s to return more info ... */
  
  	str_len = tipc_printbuf_validate(&pb);
  	skb_put(buf, TLV_SPACE(str_len));
  	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
  
  	return buf;
  }
b97bf3fd8   Per Liden   [TIPC] Initial merge
133
134
135
136
137
  static struct sk_buff *cfg_enable_bearer(void)
  {
  	struct tipc_bearer_config *args;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG))
4323add67   Per Liden   [TIPC] Avoid poll...
138
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
139
140
141
  
  	args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
  	if (tipc_enable_bearer(args->name,
50d3e6399   Allan Stephens   tipc: Correct mis...
142
  			       ntohl(args->disc_domain),
b97bf3fd8   Per Liden   [TIPC] Initial merge
143
  			       ntohl(args->priority)))
4323add67   Per Liden   [TIPC] Avoid poll...
144
  		return tipc_cfg_reply_error_string("unable to enable bearer");
b97bf3fd8   Per Liden   [TIPC] Initial merge
145

4323add67   Per Liden   [TIPC] Avoid poll...
146
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
147
148
149
150
151
  }
  
  static struct sk_buff *cfg_disable_bearer(void)
  {
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME))
4323add67   Per Liden   [TIPC] Avoid poll...
152
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
153
154
  
  	if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))
4323add67   Per Liden   [TIPC] Avoid poll...
155
  		return tipc_cfg_reply_error_string("unable to disable bearer");
b97bf3fd8   Per Liden   [TIPC] Initial merge
156

4323add67   Per Liden   [TIPC] Avoid poll...
157
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
158
159
160
161
162
163
164
  }
  
  static struct sk_buff *cfg_set_own_addr(void)
  {
  	u32 addr;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
4323add67   Per Liden   [TIPC] Avoid poll...
165
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
166

3e6c8cd56   Al Viro   [TIPC]: endiannes...
167
  	addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
b97bf3fd8   Per Liden   [TIPC] Initial merge
168
  	if (addr == tipc_own_addr)
4323add67   Per Liden   [TIPC] Avoid poll...
169
170
171
172
  		return tipc_cfg_reply_none();
  	if (!tipc_addr_node_valid(addr))
  		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
  						   " (node address)");
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
173
  	if (tipc_mode == TIPC_NET_MODE)
4323add67   Per Liden   [TIPC] Avoid poll...
174
175
  		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
  						   " (cannot change node address once assigned)");
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
176

c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
177
  	/*
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
178
179
180
181
182
183
184
185
  	 * Must release all spinlocks before calling start_net() because
  	 * Linux version of TIPC calls eth_media_start() which calls
  	 * register_netdevice_notifier() which may block!
  	 *
  	 * Temporarily releasing the lock should be harmless for non-Linux TIPC,
  	 * but Linux version of eth_media_start() should really be reworked
  	 * so that it can be called with spinlocks held.
  	 */
b97bf3fd8   Per Liden   [TIPC] Initial merge
186
187
  
  	spin_unlock_bh(&config_lock);
03194379a   Allan Stephens   tipc: Fix initial...
188
  	tipc_core_start_net(addr);
b97bf3fd8   Per Liden   [TIPC] Initial merge
189
  	spin_lock_bh(&config_lock);
4323add67   Per Liden   [TIPC] Avoid poll...
190
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
191
192
193
194
195
196
197
  }
  
  static struct sk_buff *cfg_set_remote_mng(void)
  {
  	u32 value;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
4323add67   Per Liden   [TIPC] Avoid poll...
198
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
199

3e6c8cd56   Al Viro   [TIPC]: endiannes...
200
  	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
b97bf3fd8   Per Liden   [TIPC] Initial merge
201
  	tipc_remote_management = (value != 0);
4323add67   Per Liden   [TIPC] Avoid poll...
202
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
203
204
205
206
207
208
209
  }
  
  static struct sk_buff *cfg_set_max_publications(void)
  {
  	u32 value;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
4323add67   Per Liden   [TIPC] Avoid poll...
210
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
211

3e6c8cd56   Al Viro   [TIPC]: endiannes...
212
  	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
b97bf3fd8   Per Liden   [TIPC] Initial merge
213
  	if (value != delimit(value, 1, 65535))
4323add67   Per Liden   [TIPC] Avoid poll...
214
215
  		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
  						   " (max publications must be 1-65535)");
b97bf3fd8   Per Liden   [TIPC] Initial merge
216
  	tipc_max_publications = value;
4323add67   Per Liden   [TIPC] Avoid poll...
217
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
218
219
220
221
222
223
224
  }
  
  static struct sk_buff *cfg_set_max_subscriptions(void)
  {
  	u32 value;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
4323add67   Per Liden   [TIPC] Avoid poll...
225
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
226

3e6c8cd56   Al Viro   [TIPC]: endiannes...
227
  	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
b97bf3fd8   Per Liden   [TIPC] Initial merge
228
  	if (value != delimit(value, 1, 65535))
4323add67   Per Liden   [TIPC] Avoid poll...
229
230
  		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
  						   " (max subscriptions must be 1-65535");
b97bf3fd8   Per Liden   [TIPC] Initial merge
231
  	tipc_max_subscriptions = value;
4323add67   Per Liden   [TIPC] Avoid poll...
232
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
233
234
235
236
  }
  
  static struct sk_buff *cfg_set_max_ports(void)
  {
b97bf3fd8   Per Liden   [TIPC] Initial merge
237
238
239
  	u32 value;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
4323add67   Per Liden   [TIPC] Avoid poll...
240
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
3e6c8cd56   Al Viro   [TIPC]: endiannes...
241
  	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
242
243
  	if (value == tipc_max_ports)
  		return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
244
  	if (value != delimit(value, 127, 65535))
4323add67   Per Liden   [TIPC] Avoid poll...
245
246
  		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
  						   " (max ports must be 127-65535)");
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
247
  	if (tipc_mode != TIPC_NOT_RUNNING)
4323add67   Per Liden   [TIPC] Avoid poll...
248
  		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
249
  			" (cannot change max ports while TIPC is active)");
b97bf3fd8   Per Liden   [TIPC] Initial merge
250
  	tipc_max_ports = value;
4323add67   Per Liden   [TIPC] Avoid poll...
251
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
252
  }
b97bf3fd8   Per Liden   [TIPC] Initial merge
253
254
255
256
257
  static struct sk_buff *cfg_set_netid(void)
  {
  	u32 value;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
4323add67   Per Liden   [TIPC] Avoid poll...
258
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
3e6c8cd56   Al Viro   [TIPC]: endiannes...
259
  	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
260
261
  	if (value == tipc_net_id)
  		return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
262
  	if (value != delimit(value, 1, 9999))
4323add67   Per Liden   [TIPC] Avoid poll...
263
264
  		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
  						   " (network id must be 1-9999)");
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
265
  	if (tipc_mode == TIPC_NET_MODE)
4323add67   Per Liden   [TIPC] Avoid poll...
266
  		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
e100ae92a   Allan Stephens   [TIPC]: Disallow ...
267
268
269
  			" (cannot change network id once TIPC has joined a network)");
  	tipc_net_id = value;
  	return tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
270
  }
4323add67   Per Liden   [TIPC] Avoid poll...
271
272
  struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
  				int request_space, int reply_headroom)
b97bf3fd8   Per Liden   [TIPC] Initial merge
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
  {
  	struct sk_buff *rep_tlv_buf;
  
  	spin_lock_bh(&config_lock);
  
  	/* Save request and reply details in a well-known location */
  
  	req_tlv_area = request_area;
  	req_tlv_space = request_space;
  	rep_headroom = reply_headroom;
  
  	/* Check command authorization */
  
  	if (likely(orig_node == tipc_own_addr)) {
  		/* command is permitted */
  	} else if (cmd >= 0x8000) {
4323add67   Per Liden   [TIPC] Avoid poll...
289
290
  		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
  							  " (cannot be done remotely)");
b97bf3fd8   Per Liden   [TIPC] Initial merge
291
292
  		goto exit;
  	} else if (!tipc_remote_management) {
4323add67   Per Liden   [TIPC] Avoid poll...
293
  		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
b97bf3fd8   Per Liden   [TIPC] Initial merge
294
  		goto exit;
0e65967e3   Allan Stephens   tipc: cleanup var...
295
  	} else if (cmd >= 0x4000) {
b97bf3fd8   Per Liden   [TIPC] Initial merge
296
  		u32 domain = 0;
4323add67   Per Liden   [TIPC] Avoid poll...
297
  		if ((tipc_nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
b97bf3fd8   Per Liden   [TIPC] Initial merge
298
  		    (domain != orig_node)) {
4323add67   Per Liden   [TIPC] Avoid poll...
299
  			rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
300
301
302
303
304
305
306
307
  			goto exit;
  		}
  	}
  
  	/* Call appropriate processing routine */
  
  	switch (cmd) {
  	case TIPC_CMD_NOOP:
4323add67   Per Liden   [TIPC] Avoid poll...
308
  		rep_tlv_buf = tipc_cfg_reply_none();
b97bf3fd8   Per Liden   [TIPC] Initial merge
309
310
  		break;
  	case TIPC_CMD_GET_NODES:
4323add67   Per Liden   [TIPC] Avoid poll...
311
  		rep_tlv_buf = tipc_node_get_nodes(req_tlv_area, req_tlv_space);
b97bf3fd8   Per Liden   [TIPC] Initial merge
312
313
  		break;
  	case TIPC_CMD_GET_LINKS:
4323add67   Per Liden   [TIPC] Avoid poll...
314
  		rep_tlv_buf = tipc_node_get_links(req_tlv_area, req_tlv_space);
b97bf3fd8   Per Liden   [TIPC] Initial merge
315
316
  		break;
  	case TIPC_CMD_SHOW_LINK_STATS:
4323add67   Per Liden   [TIPC] Avoid poll...
317
  		rep_tlv_buf = tipc_link_cmd_show_stats(req_tlv_area, req_tlv_space);
b97bf3fd8   Per Liden   [TIPC] Initial merge
318
319
  		break;
  	case TIPC_CMD_RESET_LINK_STATS:
4323add67   Per Liden   [TIPC] Avoid poll...
320
  		rep_tlv_buf = tipc_link_cmd_reset_stats(req_tlv_area, req_tlv_space);
b97bf3fd8   Per Liden   [TIPC] Initial merge
321
322
  		break;
  	case TIPC_CMD_SHOW_NAME_TABLE:
4323add67   Per Liden   [TIPC] Avoid poll...
323
  		rep_tlv_buf = tipc_nametbl_get(req_tlv_area, req_tlv_space);
b97bf3fd8   Per Liden   [TIPC] Initial merge
324
325
  		break;
  	case TIPC_CMD_GET_BEARER_NAMES:
4323add67   Per Liden   [TIPC] Avoid poll...
326
  		rep_tlv_buf = tipc_bearer_get_names();
b97bf3fd8   Per Liden   [TIPC] Initial merge
327
328
  		break;
  	case TIPC_CMD_GET_MEDIA_NAMES:
4323add67   Per Liden   [TIPC] Avoid poll...
329
  		rep_tlv_buf = tipc_media_get_names();
b97bf3fd8   Per Liden   [TIPC] Initial merge
330
331
  		break;
  	case TIPC_CMD_SHOW_PORTS:
4323add67   Per Liden   [TIPC] Avoid poll...
332
  		rep_tlv_buf = tipc_port_get_ports();
b97bf3fd8   Per Liden   [TIPC] Initial merge
333
  		break;
b97bf3fd8   Per Liden   [TIPC] Initial merge
334
  	case TIPC_CMD_SET_LOG_SIZE:
025adbe8e   Allan Stephens   tipc: Simplify lo...
335
  		rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space);
b97bf3fd8   Per Liden   [TIPC] Initial merge
336
337
  		break;
  	case TIPC_CMD_DUMP_LOG:
4323add67   Per Liden   [TIPC] Avoid poll...
338
  		rep_tlv_buf = tipc_log_dump();
b97bf3fd8   Per Liden   [TIPC] Initial merge
339
  		break;
107e7be62   Allan Stephens   tipc: Add support...
340
341
342
  	case TIPC_CMD_SHOW_STATS:
  		rep_tlv_buf = tipc_show_stats();
  		break;
b97bf3fd8   Per Liden   [TIPC] Initial merge
343
344
345
  	case TIPC_CMD_SET_LINK_TOL:
  	case TIPC_CMD_SET_LINK_PRI:
  	case TIPC_CMD_SET_LINK_WINDOW:
4323add67   Per Liden   [TIPC] Avoid poll...
346
  		rep_tlv_buf = tipc_link_cmd_config(req_tlv_area, req_tlv_space, cmd);
b97bf3fd8   Per Liden   [TIPC] Initial merge
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  		break;
  	case TIPC_CMD_ENABLE_BEARER:
  		rep_tlv_buf = cfg_enable_bearer();
  		break;
  	case TIPC_CMD_DISABLE_BEARER:
  		rep_tlv_buf = cfg_disable_bearer();
  		break;
  	case TIPC_CMD_SET_NODE_ADDR:
  		rep_tlv_buf = cfg_set_own_addr();
  		break;
  	case TIPC_CMD_SET_REMOTE_MNG:
  		rep_tlv_buf = cfg_set_remote_mng();
  		break;
  	case TIPC_CMD_SET_MAX_PORTS:
  		rep_tlv_buf = cfg_set_max_ports();
  		break;
  	case TIPC_CMD_SET_MAX_PUBL:
  		rep_tlv_buf = cfg_set_max_publications();
  		break;
  	case TIPC_CMD_SET_MAX_SUBSCR:
  		rep_tlv_buf = cfg_set_max_subscriptions();
  		break;
b97bf3fd8   Per Liden   [TIPC] Initial merge
369
370
371
372
  	case TIPC_CMD_SET_NETID:
  		rep_tlv_buf = cfg_set_netid();
  		break;
  	case TIPC_CMD_GET_REMOTE_MNG:
4323add67   Per Liden   [TIPC] Avoid poll...
373
  		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_remote_management);
b97bf3fd8   Per Liden   [TIPC] Initial merge
374
375
  		break;
  	case TIPC_CMD_GET_MAX_PORTS:
4323add67   Per Liden   [TIPC] Avoid poll...
376
  		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_ports);
b97bf3fd8   Per Liden   [TIPC] Initial merge
377
378
  		break;
  	case TIPC_CMD_GET_MAX_PUBL:
4323add67   Per Liden   [TIPC] Avoid poll...
379
  		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_publications);
b97bf3fd8   Per Liden   [TIPC] Initial merge
380
381
  		break;
  	case TIPC_CMD_GET_MAX_SUBSCR:
4323add67   Per Liden   [TIPC] Avoid poll...
382
  		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_max_subscriptions);
b97bf3fd8   Per Liden   [TIPC] Initial merge
383
  		break;
b97bf3fd8   Per Liden   [TIPC] Initial merge
384
  	case TIPC_CMD_GET_NETID:
4323add67   Per Liden   [TIPC] Avoid poll...
385
  		rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
b97bf3fd8   Per Liden   [TIPC] Initial merge
386
  		break;
59f0c4523   Allan Stephens   tipc: Fix skb_und...
387
388
389
390
  	case TIPC_CMD_NOT_NET_ADMIN:
  		rep_tlv_buf =
  			tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
  		break;
51f98a8d7   Allan Stephens   tipc: Remove prot...
391
392
  	case TIPC_CMD_SET_MAX_ZONES:
  	case TIPC_CMD_GET_MAX_ZONES:
08c80e9a0   Allan Stephens   tipc: Remove prot...
393
394
  	case TIPC_CMD_SET_MAX_SLAVES:
  	case TIPC_CMD_GET_MAX_SLAVES:
8f92df6ad   Allan Stephens   tipc: Remove prot...
395
396
  	case TIPC_CMD_SET_MAX_CLUSTERS:
  	case TIPC_CMD_GET_MAX_CLUSTERS:
f831c963b   Allan Stephens   tipc: Eliminate c...
397
398
  	case TIPC_CMD_SET_MAX_NODES:
  	case TIPC_CMD_GET_MAX_NODES:
51f98a8d7   Allan Stephens   tipc: Remove prot...
399
400
401
  		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
  							  " (obsolete command)");
  		break;
b97bf3fd8   Per Liden   [TIPC] Initial merge
402
  	default:
53cfd1e10   Allan Stephens   [TIPC]: Unrecogni...
403
404
  		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
  							  " (unknown command)");
b97bf3fd8   Per Liden   [TIPC] Initial merge
405
406
407
408
409
410
411
412
413
414
415
416
417
418
  		break;
  	}
  
  	/* Return reply buffer */
  exit:
  	spin_unlock_bh(&config_lock);
  	return rep_tlv_buf;
  }
  
  static void cfg_named_msg_event(void *userdata,
  				u32 port_ref,
  				struct sk_buff **buf,
  				const unchar *msg,
  				u32 size,
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
419
  				u32 importance,
b97bf3fd8   Per Liden   [TIPC] Initial merge
420
421
422
423
424
425
426
427
428
429
430
431
432
  				struct tipc_portid const *orig,
  				struct tipc_name_seq const *dest)
  {
  	struct tipc_cfg_msg_hdr *req_hdr;
  	struct tipc_cfg_msg_hdr *rep_hdr;
  	struct sk_buff *rep_buf;
  
  	/* Validate configuration message header (ignore invalid message) */
  
  	req_hdr = (struct tipc_cfg_msg_hdr *)msg;
  	if ((size < sizeof(*req_hdr)) ||
  	    (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
  	    (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
a10bd924a   Allan Stephens   [TIPC]: Enhanced ...
433
434
  		warn("Invalid configuration message discarded
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
435
436
437
438
  		return;
  	}
  
  	/* Generate reply for request (if can't, return request) */
4323add67   Per Liden   [TIPC] Avoid poll...
439
  	rep_buf = tipc_cfg_do_cmd(orig->node,
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
440
  				  ntohs(req_hdr->tcm_type),
4323add67   Per Liden   [TIPC] Avoid poll...
441
442
443
  				  msg + sizeof(*req_hdr),
  				  size - sizeof(*req_hdr),
  				  BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
b97bf3fd8   Per Liden   [TIPC] Initial merge
444
445
446
447
448
449
450
451
452
453
454
455
456
457
  	if (rep_buf) {
  		skb_push(rep_buf, sizeof(*rep_hdr));
  		rep_hdr = (struct tipc_cfg_msg_hdr *)rep_buf->data;
  		memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
  		rep_hdr->tcm_len = htonl(rep_buf->len);
  		rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
  	} else {
  		rep_buf = *buf;
  		*buf = NULL;
  	}
  
  	/* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */
  	tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len);
  }
4323add67   Per Liden   [TIPC] Avoid poll...
458
  int tipc_cfg_init(void)
b97bf3fd8   Per Liden   [TIPC] Initial merge
459
460
461
  {
  	struct tipc_name_seq seq;
  	int res;
b0c1e928c   Allan Stephens   tipc: Remove user...
462
  	res = tipc_createport(NULL, TIPC_CRITICAL_IMPORTANCE,
b97bf3fd8   Per Liden   [TIPC] Initial merge
463
464
  			      NULL, NULL, NULL,
  			      NULL, cfg_named_msg_event, NULL,
7a488fd3d   Allan Stephens   tipc: Eliminate u...
465
  			      NULL, &config_port_ref);
b97bf3fd8   Per Liden   [TIPC] Initial merge
466
467
468
469
470
  	if (res)
  		goto failed;
  
  	seq.type = TIPC_CFG_SRV;
  	seq.lower = seq.upper = tipc_own_addr;
7a488fd3d   Allan Stephens   tipc: Eliminate u...
471
  	res = tipc_nametbl_publish_rsv(config_port_ref, TIPC_ZONE_SCOPE, &seq);
b97bf3fd8   Per Liden   [TIPC] Initial merge
472
473
474
475
476
477
478
479
  	if (res)
  		goto failed;
  
  	return 0;
  
  failed:
  	err("Unable to create configuration service
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
480
481
  	return res;
  }
4323add67   Per Liden   [TIPC] Avoid poll...
482
  void tipc_cfg_stop(void)
b97bf3fd8   Per Liden   [TIPC] Initial merge
483
  {
7a488fd3d   Allan Stephens   tipc: Eliminate u...
484
485
486
  	if (config_port_ref) {
  		tipc_deleteport(config_port_ref);
  		config_port_ref = 0;
b97bf3fd8   Per Liden   [TIPC] Initial merge
487
488
  	}
  }