diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/phonet/Makefile | 1 | ||||
-rw-r--r-- | net/phonet/af_phonet.c | 3 | ||||
-rw-r--r-- | net/phonet/socket.c | 3 | ||||
-rw-r--r-- | net/phonet/sysctl.c | 113 |
4 files changed, 119 insertions, 1 deletions
diff --git a/net/phonet/Makefile b/net/phonet/Makefile index d218abc3f06a..ae9c3ed5be83 100644 --- a/net/phonet/Makefile +++ b/net/phonet/Makefile | |||
@@ -5,4 +5,5 @@ phonet-objs := \ | |||
5 | pn_netlink.o \ | 5 | pn_netlink.o \ |
6 | socket.o \ | 6 | socket.o \ |
7 | datagram.o \ | 7 | datagram.o \ |
8 | sysctl.o \ | ||
8 | af_phonet.o | 9 | af_phonet.o |
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 51397ff308bd..50dc258d5aa2 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c | |||
@@ -350,6 +350,7 @@ static int __init phonet_init(void) | |||
350 | phonet_device_init(); | 350 | phonet_device_init(); |
351 | dev_add_pack(&phonet_packet_type); | 351 | dev_add_pack(&phonet_packet_type); |
352 | phonet_netlink_register(); | 352 | phonet_netlink_register(); |
353 | phonet_sysctl_init(); | ||
353 | 354 | ||
354 | err = isi_register(); | 355 | err = isi_register(); |
355 | if (err) | 356 | if (err) |
@@ -357,6 +358,7 @@ static int __init phonet_init(void) | |||
357 | return 0; | 358 | return 0; |
358 | 359 | ||
359 | err: | 360 | err: |
361 | phonet_sysctl_exit(); | ||
360 | sock_unregister(AF_PHONET); | 362 | sock_unregister(AF_PHONET); |
361 | dev_remove_pack(&phonet_packet_type); | 363 | dev_remove_pack(&phonet_packet_type); |
362 | phonet_device_exit(); | 364 | phonet_device_exit(); |
@@ -366,6 +368,7 @@ err: | |||
366 | static void __exit phonet_exit(void) | 368 | static void __exit phonet_exit(void) |
367 | { | 369 | { |
368 | isi_unregister(); | 370 | isi_unregister(); |
371 | phonet_sysctl_exit(); | ||
369 | sock_unregister(AF_PHONET); | 372 | sock_unregister(AF_PHONET); |
370 | dev_remove_pack(&phonet_packet_type); | 373 | dev_remove_pack(&phonet_packet_type); |
371 | phonet_device_exit(); | 374 | phonet_device_exit(); |
diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 99a4945d565d..dfd4061646db 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c | |||
@@ -273,8 +273,9 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport) | |||
273 | 273 | ||
274 | if (!sport) { | 274 | if (!sport) { |
275 | /* search free port */ | 275 | /* search free port */ |
276 | int port, pmin = 0x40, pmax = 0x7f; | 276 | int port, pmin, pmax; |
277 | 277 | ||
278 | phonet_get_local_port_range(&pmin, &pmax); | ||
278 | for (port = pmin; port <= pmax; port++) { | 279 | for (port = pmin; port <= pmax; port++) { |
279 | port_cur++; | 280 | port_cur++; |
280 | if (port_cur < pmin || port_cur > pmax) | 281 | if (port_cur < pmin || port_cur > pmax) |
diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c new file mode 100644 index 000000000000..600a4309b8c8 --- /dev/null +++ b/net/phonet/sysctl.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * File: sysctl.c | ||
3 | * | ||
4 | * Phonet /proc/sys/net/phonet interface implementation | ||
5 | * | ||
6 | * Copyright (C) 2008 Nokia Corporation. | ||
7 | * | ||
8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * version 2 as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
22 | * 02110-1301 USA | ||
23 | */ | ||
24 | |||
25 | #include <linux/seqlock.h> | ||
26 | #include <linux/sysctl.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | |||
30 | #define DYNAMIC_PORT_MIN 0x40 | ||
31 | #define DYNAMIC_PORT_MAX 0x7f | ||
32 | |||
33 | static DEFINE_SEQLOCK(local_port_range_lock); | ||
34 | static int local_port_range_min[2] = {0, 0}; | ||
35 | static int local_port_range_max[2] = {1023, 1023}; | ||
36 | static int local_port_range[2] = {DYNAMIC_PORT_MIN, DYNAMIC_PORT_MAX}; | ||
37 | static struct ctl_table_header *phonet_table_hrd; | ||
38 | |||
39 | static void set_local_port_range(int range[2]) | ||
40 | { | ||
41 | write_seqlock(&local_port_range_lock); | ||
42 | local_port_range[0] = range[0]; | ||
43 | local_port_range[1] = range[1]; | ||
44 | write_sequnlock(&local_port_range_lock); | ||
45 | } | ||
46 | |||
47 | void phonet_get_local_port_range(int *min, int *max) | ||
48 | { | ||
49 | unsigned seq; | ||
50 | do { | ||
51 | seq = read_seqbegin(&local_port_range_lock); | ||
52 | if (min) | ||
53 | *min = local_port_range[0]; | ||
54 | if (max) | ||
55 | *max = local_port_range[1]; | ||
56 | } while (read_seqretry(&local_port_range_lock, seq)); | ||
57 | } | ||
58 | |||
59 | static int proc_local_port_range(ctl_table *table, int write, struct file *filp, | ||
60 | void __user *buffer, | ||
61 | size_t *lenp, loff_t *ppos) | ||
62 | { | ||
63 | int ret; | ||
64 | int range[2] = {local_port_range[0], local_port_range[1]}; | ||
65 | ctl_table tmp = { | ||
66 | .data = &range, | ||
67 | .maxlen = sizeof(range), | ||
68 | .mode = table->mode, | ||
69 | .extra1 = &local_port_range_min, | ||
70 | .extra2 = &local_port_range_max, | ||
71 | }; | ||
72 | |||
73 | ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos); | ||
74 | |||
75 | if (write && ret == 0) { | ||
76 | if (range[1] < range[0]) | ||
77 | ret = -EINVAL; | ||
78 | else | ||
79 | set_local_port_range(range); | ||
80 | } | ||
81 | |||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static struct ctl_table phonet_table[] = { | ||
86 | { | ||
87 | .ctl_name = CTL_UNNUMBERED, | ||
88 | .procname = "local_port_range", | ||
89 | .data = &local_port_range, | ||
90 | .maxlen = sizeof(local_port_range), | ||
91 | .mode = 0644, | ||
92 | .proc_handler = &proc_local_port_range, | ||
93 | .strategy = NULL, | ||
94 | }, | ||
95 | { .ctl_name = 0 } | ||
96 | }; | ||
97 | |||
98 | struct ctl_path phonet_ctl_path[] = { | ||
99 | { .procname = "net", .ctl_name = CTL_NET, }, | ||
100 | { .procname = "phonet", .ctl_name = CTL_UNNUMBERED, }, | ||
101 | { }, | ||
102 | }; | ||
103 | |||
104 | int __init phonet_sysctl_init(void) | ||
105 | { | ||
106 | phonet_table_hrd = register_sysctl_paths(phonet_ctl_path, phonet_table); | ||
107 | return phonet_table_hrd == NULL ? -ENOMEM : 0; | ||
108 | } | ||
109 | |||
110 | void phonet_sysctl_exit(void) | ||
111 | { | ||
112 | unregister_sysctl_table(phonet_table_hrd); | ||
113 | } | ||