Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
4500e917
Commit
4500e917
authored
Jan 19, 2004
by
Hideaki Yoshifuji
Committed by
David S. Miller
Jan 19, 2004
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[NET]: Add proc_dointvec_userhz_jiffies, use it for proper handling of neighbour sysctls.
parent
33e9809b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
212 additions
and
126 deletions
+212
-126
include/linux/sysctl.h
include/linux/sysctl.h
+2
-0
kernel/sysctl.c
kernel/sysctl.c
+205
-122
net/core/neighbour.c
net/core/neighbour.c
+5
-4
No files found.
include/linux/sysctl.h
View file @
4500e917
...
...
@@ -738,6 +738,8 @@ extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
void
__user
*
,
size_t
*
);
extern
int
proc_dointvec_jiffies
(
ctl_table
*
,
int
,
struct
file
*
,
void
__user
*
,
size_t
*
);
extern
int
proc_dointvec_userhz_jiffies
(
ctl_table
*
,
int
,
struct
file
*
,
void
__user
*
,
size_t
*
);
extern
int
proc_doulongvec_minmax
(
ctl_table
*
,
int
,
struct
file
*
,
void
__user
*
,
size_t
*
);
extern
int
proc_doulongvec_ms_jiffies_minmax
(
ctl_table
*
table
,
int
,
...
...
kernel/sysctl.c
View file @
4500e917
...
...
@@ -37,6 +37,7 @@
#include <linux/hugetlb.h>
#include <linux/security.h>
#include <linux/initrd.h>
#include <linux/times.h>
#include <asm/uaccess.h>
#ifdef CONFIG_ROOT_NFS
...
...
@@ -1070,8 +1071,8 @@ int do_sysctl_strategy (ctl_table *table,
* cover common cases -
*
* proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
* proc_dointvec_
minmax(), proc_doulongvec_ms_jiffies_minmax(),
* proc_doulongvec_minmax()
* proc_dointvec_
userhz_jiffies(), proc_dointvec_minmax(),
* proc_doulongvec_m
s_jiffies_minmax(), proc_doulongvec_m
inmax()
*
* It is the handler's job to read the input buffer from user memory
* and process it. The handler should return 0 on success.
...
...
@@ -1342,19 +1343,36 @@ static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
return
r
;
}
#define OP_SET 0
#define OP_AND 1
#define OP_OR 2
#define OP_MAX 3
#define OP_MIN 4
static
int
do_proc_dointvec_conv
(
int
*
negp
,
unsigned
long
*
lvalp
,
int
*
valp
,
int
write
,
void
*
data
)
{
if
(
write
)
{
*
valp
=
*
negp
?
-*
lvalp
:
*
lvalp
;
}
else
{
int
val
=
*
valp
;
if
(
val
<
0
)
{
*
negp
=
-
1
;
*
lvalp
=
(
unsigned
long
)
-
val
;
}
else
{
*
negp
=
0
;
*
lvalp
=
(
unsigned
long
)
val
;
}
}
return
0
;
}
static
int
do_proc_dointvec
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
,
int
conv
,
int
op
)
void
__user
*
buffer
,
size_t
*
lenp
,
int
(
*
conv
)(
int
*
negp
,
unsigned
long
*
lvalp
,
int
*
valp
,
int
write
,
void
*
data
),
void
*
data
)
{
#define TMPBUFLEN 20
int
*
i
,
vleft
,
first
=
1
,
neg
,
val
;
unsigned
long
lval
;
size_t
left
,
len
;
#define TMPBUFLEN 20
char
buf
[
TMPBUFLEN
],
*
p
;
if
(
!
table
->
data
||
!
table
->
maxlen
||
!*
lenp
||
...
...
@@ -1364,9 +1382,12 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
}
i
=
(
int
*
)
table
->
data
;
vleft
=
table
->
maxlen
/
sizeof
(
int
);
vleft
=
table
->
maxlen
/
sizeof
(
*
i
);
left
=
*
lenp
;
if
(
!
conv
)
conv
=
do_proc_dointvec_conv
;
for
(;
left
&&
vleft
--
;
i
++
,
first
=
0
)
{
if
(
write
)
{
while
(
left
)
{
...
...
@@ -1382,8 +1403,8 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
break
;
neg
=
0
;
len
=
left
;
if
(
len
>
TMPBUFLEN
-
1
)
len
=
TMPBUFLEN
-
1
;
if
(
len
>
sizeof
(
buf
)
-
1
)
len
=
sizeof
(
buf
)
-
1
;
if
(
copy_from_user
(
buf
,
buffer
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
0
;
...
...
@@ -1394,7 +1415,9 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
}
if
(
*
p
<
'0'
||
*
p
>
'9'
)
break
;
val
=
simple_strtoul
(
p
,
&
p
,
0
)
*
conv
;
lval
=
simple_strtoul
(
p
,
&
p
,
0
);
len
=
p
-
buf
;
if
((
len
<
left
)
&&
*
p
&&
!
isspace
(
*
p
))
break
;
...
...
@@ -1402,22 +1425,18 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
val
=
-
val
;
buffer
+=
len
;
left
-=
len
;
switch
(
op
)
{
case
OP_SET
:
*
i
=
val
;
break
;
case
OP_AND
:
*
i
&=
val
;
break
;
case
OP_OR
:
*
i
|=
val
;
break
;
case
OP_MAX
:
if
(
*
i
<
val
)
*
i
=
val
;
break
;
case
OP_MIN
:
if
(
*
i
>
val
)
*
i
=
val
;
break
;
}
if
(
conv
(
&
neg
,
&
lval
,
i
,
1
,
data
))
break
;
}
else
{
p
=
buf
;
if
(
!
first
)
*
p
++
=
'\t'
;
sprintf
(
p
,
"%d"
,
(
*
i
)
/
conv
);
if
(
conv
(
&
neg
,
&
lval
,
i
,
0
,
data
))
break
;
sprintf
(
p
,
"%s%lu"
,
neg
?
"-"
:
""
,
lval
);
len
=
strlen
(
buf
);
if
(
len
>
left
)
len
=
left
;
...
...
@@ -1449,6 +1468,7 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
*
lenp
-=
left
;
filp
->
f_pos
+=
*
lenp
;
return
0
;
#undef TMPBUFLEN
}
/**
...
...
@@ -1467,7 +1487,45 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
int
proc_dointvec
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
)
{
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
1
,
OP_SET
);
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
NULL
,
NULL
);
}
#define OP_SET 0
#define OP_AND 1
#define OP_OR 2
#define OP_MAX 3
#define OP_MIN 4
static
int
do_proc_dointvec_bset_conv
(
int
*
negp
,
unsigned
long
*
lvalp
,
int
*
valp
,
int
write
,
void
*
data
)
{
int
op
=
*
(
int
*
)
data
;
if
(
write
)
{
int
val
=
*
negp
?
-*
lvalp
:
*
lvalp
;
switch
(
op
)
{
case
OP_SET
:
*
valp
=
val
;
break
;
case
OP_AND
:
*
valp
&=
val
;
break
;
case
OP_OR
:
*
valp
|=
val
;
break
;
case
OP_MAX
:
if
(
*
valp
<
val
)
*
valp
=
val
;
break
;
case
OP_MIN
:
if
(
*
valp
>
val
)
*
valp
=
val
;
break
;
}
}
else
{
int
val
=
*
valp
;
if
(
val
<
0
)
{
*
negp
=
-
1
;
*
lvalp
=
(
unsigned
long
)
-
val
;
}
else
{
*
negp
=
0
;
*
lvalp
=
(
unsigned
long
)
val
;
}
}
return
0
;
}
/*
...
...
@@ -1477,11 +1535,44 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp,
int
proc_dointvec_bset
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
)
{
int
op
;
if
(
!
capable
(
CAP_SYS_MODULE
))
{
return
-
EPERM
;
}
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
1
,
(
current
->
pid
==
1
)
?
OP_SET
:
OP_AND
);
op
=
(
current
->
pid
==
1
)
?
OP_SET
:
OP_AND
;
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
do_proc_dointvec_bset_conv
,
&
op
);
}
struct
do_proc_dointvec_minmax_conv_param
{
int
*
min
;
int
*
max
;
};
static
int
do_proc_dointvec_minmax_conv
(
int
*
negp
,
unsigned
long
*
lvalp
,
int
*
valp
,
int
write
,
void
*
data
)
{
struct
do_proc_dointvec_minmax_conv_param
*
param
=
data
;
if
(
write
)
{
int
val
=
*
negp
?
-*
lvalp
:
*
lvalp
;
if
((
param
->
min
&&
*
param
->
min
>
val
)
||
(
param
->
max
&&
*
param
->
max
<
val
))
return
-
EINVAL
;
*
valp
=
val
;
}
else
{
int
val
=
*
valp
;
if
(
val
<
0
)
{
*
negp
=
-
1
;
*
lvalp
=
(
unsigned
long
)
-
val
;
}
else
{
*
negp
=
0
;
*
lvalp
=
(
unsigned
long
)
val
;
}
}
return
0
;
}
/**
...
...
@@ -1503,98 +1594,12 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
int
proc_dointvec_minmax
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
)
{
int
*
i
,
*
min
,
*
max
,
vleft
,
first
=
1
,
neg
,
val
;
size_t
len
,
left
;
#define TMPBUFLEN 20
char
buf
[
TMPBUFLEN
],
*
p
;
if
(
!
table
->
data
||
!
table
->
maxlen
||
!*
lenp
||
(
filp
->
f_pos
&&
!
write
))
{
*
lenp
=
0
;
return
0
;
}
i
=
(
int
*
)
table
->
data
;
min
=
(
int
*
)
table
->
extra1
;
max
=
(
int
*
)
table
->
extra2
;
vleft
=
table
->
maxlen
/
sizeof
(
int
);
left
=
*
lenp
;
for
(;
left
&&
vleft
--
;
i
++
,
min
++
,
max
++
,
first
=
0
)
{
if
(
write
)
{
while
(
left
)
{
char
c
;
if
(
get_user
(
c
,
(
char
*
)
buffer
))
return
-
EFAULT
;
if
(
!
isspace
(
c
))
break
;
left
--
;
buffer
++
;
}
if
(
!
left
)
break
;
neg
=
0
;
len
=
left
;
if
(
len
>
TMPBUFLEN
-
1
)
len
=
TMPBUFLEN
-
1
;
if
(
copy_from_user
(
buf
,
buffer
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
0
;
p
=
buf
;
if
(
*
p
==
'-'
&&
left
>
1
)
{
neg
=
1
;
left
--
,
p
++
;
}
if
(
*
p
<
'0'
||
*
p
>
'9'
)
break
;
val
=
simple_strtoul
(
p
,
&
p
,
0
);
len
=
p
-
buf
;
if
((
len
<
left
)
&&
*
p
&&
!
isspace
(
*
p
))
break
;
if
(
neg
)
val
=
-
val
;
buffer
+=
len
;
left
-=
len
;
if
((
min
&&
val
<
*
min
)
||
(
max
&&
val
>
*
max
))
continue
;
*
i
=
val
;
}
else
{
p
=
buf
;
if
(
!
first
)
*
p
++
=
'\t'
;
sprintf
(
p
,
"%d"
,
*
i
);
len
=
strlen
(
buf
);
if
(
len
>
left
)
len
=
left
;
if
(
copy_to_user
(
buffer
,
buf
,
len
))
return
-
EFAULT
;
left
-=
len
;
buffer
+=
len
;
}
}
if
(
!
write
&&
!
first
&&
left
)
{
if
(
put_user
(
'\n'
,
(
char
*
)
buffer
))
return
-
EFAULT
;
left
--
,
buffer
++
;
}
if
(
write
)
{
p
=
(
char
*
)
buffer
;
while
(
left
)
{
char
c
;
if
(
get_user
(
c
,
p
++
))
return
-
EFAULT
;
if
(
!
isspace
(
c
))
break
;
left
--
;
}
}
if
(
write
&&
first
)
return
-
EINVAL
;
*
lenp
-=
left
;
filp
->
f_pos
+=
*
lenp
;
return
0
;
struct
do_proc_dointvec_minmax_conv_param
param
=
{
.
min
=
(
int
*
)
table
->
extra1
,
.
max
=
(
int
*
)
table
->
extra2
,
};
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
do_proc_dointvec_minmax_conv
,
&
param
);
}
static
int
do_proc_doulongvec_minmax
(
ctl_table
*
table
,
int
write
,
...
...
@@ -1749,6 +1754,48 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
}
static
int
do_proc_dointvec_jiffies_conv
(
int
*
negp
,
unsigned
long
*
lvalp
,
int
*
valp
,
int
write
,
void
*
data
)
{
if
(
write
)
{
*
valp
=
*
negp
?
-
(
*
lvalp
*
HZ
)
:
(
*
lvalp
*
HZ
);
}
else
{
int
val
=
*
valp
;
unsigned
long
lval
;
if
(
val
<
0
)
{
*
negp
=
-
1
;
lval
=
(
unsigned
long
)
-
val
;
}
else
{
*
negp
=
0
;
lval
=
(
unsigned
long
)
val
;
}
*
lvalp
=
lval
/
HZ
;
}
return
0
;
}
static
int
do_proc_dointvec_userhz_jiffies_conv
(
int
*
negp
,
unsigned
long
*
lvalp
,
int
*
valp
,
int
write
,
void
*
data
)
{
if
(
write
)
{
*
valp
=
clock_t_to_jiffies
(
*
negp
?
-*
lvalp
:
*
lvalp
);
}
else
{
int
val
=
*
valp
;
unsigned
long
lval
;
if
(
val
<
0
)
{
*
negp
=
-
1
;
lval
=
(
unsigned
long
)
-
val
;
}
else
{
*
negp
=
0
;
lval
=
(
unsigned
long
)
val
;
}
*
lvalp
=
jiffies_to_clock_t
(
lval
);
}
return
0
;
}
/**
* proc_dointvec_jiffies - read a vector of integers as seconds
* @table: the sysctl table
...
...
@@ -1767,7 +1814,30 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
int
proc_dointvec_jiffies
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
)
{
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
HZ
,
OP_SET
);
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
do_proc_dointvec_jiffies_conv
,
NULL
);
}
/**
* proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
* @table: the sysctl table
* @write: %TRUE if this is a write to the sysctl file
* @filp: the file structure
* @buffer: the user buffer
* @lenp: the size of the user buffer
*
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
* values from/to the user buffer, treated as an ASCII string.
* The values read are assumed to be in 1/USER_HZ seconds, and
* are converted into jiffies.
*
* Returns 0 on success.
*/
int
proc_dointvec_userhz_jiffies
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
)
{
return
do_proc_dointvec
(
table
,
write
,
filp
,
buffer
,
lenp
,
do_proc_dointvec_userhz_jiffies_conv
,
NULL
);
}
#else
/* CONFIG_PROC_FS */
...
...
@@ -1808,6 +1878,12 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
return
-
ENOSYS
;
}
int
proc_dointvec_userhz_jiffies
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
)
{
return
-
ENOSYS
;
}
int
proc_doulongvec_minmax
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
)
{
...
...
@@ -1995,6 +2071,12 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
return
-
ENOSYS
;
}
int
proc_dointvec_userhz_jiffies
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
)
{
return
-
ENOSYS
;
}
int
proc_doulongvec_minmax
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
__user
*
buffer
,
size_t
*
lenp
)
{
...
...
@@ -2027,6 +2109,7 @@ void unregister_sysctl_table(struct ctl_table_header * table)
EXPORT_SYMBOL
(
proc_dointvec
);
EXPORT_SYMBOL
(
proc_dointvec_jiffies
);
EXPORT_SYMBOL
(
proc_dointvec_minmax
);
EXPORT_SYMBOL
(
proc_dointvec_userhz_jiffies
);
EXPORT_SYMBOL
(
proc_dostring
);
EXPORT_SYMBOL
(
proc_doulongvec_minmax
);
EXPORT_SYMBOL
(
proc_doulongvec_ms_jiffies_minmax
);
...
...
net/core/neighbour.c
View file @
4500e917
...
...
@@ -24,6 +24,7 @@
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
#include <linux/times.h>
#include <net/neighbour.h>
#include <net/dst.h>
#include <net/sock.h>
...
...
@@ -1510,7 +1511,7 @@ struct neigh_sysctl_table {
.
procname
=
"retrans_time"
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
.
proc_handler
=
&
proc_dointvec
_userhz_jiffies
,
},
{
.
ctl_name
=
NET_NEIGH_REACHABLE_TIME
,
...
...
@@ -1555,21 +1556,21 @@ struct neigh_sysctl_table {
.
procname
=
"anycast_delay"
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
.
proc_handler
=
&
proc_dointvec
_userhz_jiffies
,
},
{
.
ctl_name
=
NET_NEIGH_PROXY_DELAY
,
.
procname
=
"proxy_delay"
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
.
proc_handler
=
&
proc_dointvec
_userhz_jiffies
,
},
{
.
ctl_name
=
NET_NEIGH_LOCKTIME
,
.
procname
=
"locktime"
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
,
.
proc_handler
=
&
proc_dointvec
_userhz_jiffies
,
},
{
.
ctl_name
=
NET_NEIGH_GC_INTERVAL
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment