Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/phonet/sysctl.c
15109 views
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 <[email protected]>
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,
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, 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
.procname = "local_port_range",
88
.data = &local_port_range,
89
.maxlen = sizeof(local_port_range),
90
.mode = 0644,
91
.proc_handler = proc_local_port_range,
92
},
93
{ }
94
};
95
96
static struct ctl_path phonet_ctl_path[] = {
97
{ .procname = "net", },
98
{ .procname = "phonet", },
99
{ },
100
};
101
102
int __init phonet_sysctl_init(void)
103
{
104
phonet_table_hrd = register_sysctl_paths(phonet_ctl_path, phonet_table);
105
return phonet_table_hrd == NULL ? -ENOMEM : 0;
106
}
107
108
void phonet_sysctl_exit(void)
109
{
110
unregister_sysctl_table(phonet_table_hrd);
111
}
112
113