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
6ccc3e25
Commit
6ccc3e25
authored
Nov 13, 2002
by
Andy Grover
Browse files
Options
Browse Files
Download
Plain Diff
Merge groveronline.com:/root/bk/linux-2.5
into groveronline.com:/root/bk/linux-acpi
parents
8270dc79
2c0889e4
Changes
36
Show whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1606 additions
and
295 deletions
+1606
-295
arch/i386/kernel/entry.S
arch/i386/kernel/entry.S
+24
-0
arch/sparc/kernel/module.c
arch/sparc/kernel/module.c
+2
-2
arch/sparc64/kernel/module.c
arch/sparc64/kernel/module.c
+114
-4
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sparc32.c
+6
-12
crypto/api.c
crypto/api.c
+1
-2
include/linux/in.h
include/linux/in.h
+1
-0
include/linux/module.h
include/linux/module.h
+9
-0
include/linux/udp.h
include/linux/udp.h
+0
-3
include/linux/xfrm.h
include/linux/xfrm.h
+50
-3
include/net/ip_fib.h
include/net/ip_fib.h
+0
-3
include/net/udp.h
include/net/udp.h
+0
-2
include/net/xfrm.h
include/net/xfrm.h
+3
-20
kernel/exec_domain.c
kernel/exec_domain.c
+2
-7
net/802/tr.c
net/802/tr.c
+1
-1
net/atm/mpc.c
net/atm/mpc.c
+1
-1
net/core/neighbour.c
net/core/neighbour.c
+1
-1
net/ipv4/Kconfig
net/ipv4/Kconfig
+8
-0
net/ipv4/Makefile
net/ipv4/Makefile
+1
-0
net/ipv4/af_inet.c
net/ipv4/af_inet.c
+10
-6
net/ipv4/ah.c
net/ipv4/ah.c
+1
-1
net/ipv4/esp.c
net/ipv4/esp.c
+15
-10
net/ipv4/fib_hash.c
net/ipv4/fib_hash.c
+0
-12
net/ipv4/ip_sockglue.c
net/ipv4/ip_sockglue.c
+1
-0
net/ipv4/netfilter/ip_nat_helper.c
net/ipv4/netfilter/ip_nat_helper.c
+3
-7
net/ipv4/proc.c
net/ipv4/proc.c
+113
-97
net/ipv4/raw.c
net/ipv4/raw.c
+156
-59
net/ipv4/udp.c
net/ipv4/udp.c
+1
-13
net/ipv4/xfrm_input.c
net/ipv4/xfrm_input.c
+1
-1
net/ipv4/xfrm_state.c
net/ipv4/xfrm_state.c
+5
-4
net/ipv4/xfrm_user.c
net/ipv4/xfrm_user.c
+1045
-0
net/ipv6/mcast.c
net/ipv6/mcast.c
+1
-0
net/irda/af_irda.c
net/irda/af_irda.c
+1
-0
net/key/af_key.c
net/key/af_key.c
+16
-7
net/llc/llc_main.c
net/llc/llc_main.c
+5
-0
net/sched/sch_sfq.c
net/sched/sch_sfq.c
+1
-1
net/socket.c
net/socket.c
+7
-16
No files found.
arch/i386/kernel/entry.S
View file @
6ccc3e25
...
...
@@ -66,7 +66,9 @@ OLDESP = 0x34
OLDSS
=
0x38
CF_MASK
=
0x00000001
TF_MASK
=
0x00000100
IF_MASK
=
0x00000200
DF_MASK
=
0x00000400
NT_MASK
=
0x00004000
VM_MASK
=
0x00020000
...
...
@@ -134,6 +136,17 @@ ENTRY(lcall7)
movl
%
eax
,
EFLAGS
(%
esp
)
#
movl
%
edx
,
EIP
(%
esp
)
#
Now
we
move
them
to
their
"normal"
places
movl
%
ecx
,
CS
(%
esp
)
#
#
#
Call
gates
don
't clear TF and NT in eflags like
#
traps
do
,
so
we
need
to
do
it
ourselves
.
#
%
eax
already
contains
eflags
(
but
it
may
have
#
DF
set
,
clear
that
also
)
#
andl
$~
(
DF_MASK
| TF_MASK |
NT_MASK
),%
eax
pushl
%
eax
popfl
movl
%
esp
,
%
ebx
pushl
%
ebx
andl
$
-
8192
,
%
ebx
#
GET_THREAD_INFO
...
...
@@ -156,6 +169,17 @@ ENTRY(lcall27)
movl
%
eax
,
EFLAGS
(%
esp
)
#
movl
%
edx
,
EIP
(%
esp
)
#
Now
we
move
them
to
their
"normal"
places
movl
%
ecx
,
CS
(%
esp
)
#
#
#
Call
gates
don
't clear TF and NT in eflags like
#
traps
do
,
so
we
need
to
do
it
ourselves
.
#
%
eax
already
contains
eflags
(
but
it
may
have
#
DF
set
,
clear
that
also
)
#
andl
$~
(
DF_MASK
| TF_MASK |
NT_MASK
),%
eax
pushl
%
eax
popfl
movl
%
esp
,
%
ebx
pushl
%
ebx
andl
$
-
8192
,
%
ebx
#
GET_THREAD_INFO
...
...
arch/sparc/kernel/module.c
View file @
6ccc3e25
...
...
@@ -90,7 +90,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
me
->
name
,
strtab
+
sym
->
st_name
);
return
-
ENOENT
;
}
v
+=
rel
->
r_addend
;
v
+=
rel
[
i
].
r_addend
;
switch
(
ELF32_R_TYPE
(
rel
[
i
].
r_info
))
{
case
R_SPARC_32
:
...
...
@@ -126,7 +126,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
me
->
name
,
(
int
)
(
ELF32_R_TYPE
(
rel
[
i
].
r_info
)
&
0xff
));
return
-
ENOEXEC
;
}
}
;
}
return
0
;
}
...
...
arch/sparc64/kernel/module.c
View file @
6ccc3e25
...
...
@@ -10,6 +10,113 @@
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
static
struct
vm_struct
*
modvmlist
=
NULL
;
static
void
module_unmap
(
void
*
addr
)
{
struct
vm_struct
**
p
,
*
tmp
;
int
i
;
if
(
!
addr
)
return
;
if
((
PAGE_SIZE
-
1
)
&
(
unsigned
long
)
addr
)
{
printk
(
"Trying to unmap module with bad address (%p)
\n
"
,
addr
);
return
;
}
for
(
p
=
&
modvmlist
;
(
tmp
=
*
p
)
;
p
=
&
tmp
->
next
)
{
if
(
tmp
->
addr
==
addr
)
{
*
p
=
tmp
->
next
;
goto
found
;
}
}
printk
(
"Trying to unmap nonexistent module vm area (%p)
\n
"
,
addr
);
return
;
found:
unmap_vm_area
(
tmp
);
for
(
i
=
0
;
i
<
tmp
->
nr_pages
;
i
++
)
{
if
(
unlikely
(
!
tmp
->
pages
[
i
]))
BUG
();
__free_page
(
tmp
->
pages
[
i
]);
}
kfree
(
tmp
->
pages
);
kfree
(
tmp
);
}
static
void
*
module_map
(
unsigned
long
size
)
{
struct
vm_struct
**
p
,
*
tmp
,
*
area
;
struct
page
**
pages
;
void
*
addr
;
unsigned
int
nr_pages
,
array_size
,
i
;
size
=
PAGE_ALIGN
(
size
);
if
(
!
size
||
size
>
MODULES_LEN
)
return
NULL
;
addr
=
(
void
*
)
MODULES_VADDR
;
for
(
p
=
&
modvmlist
;
(
tmp
=
*
p
)
;
p
=
&
tmp
->
next
)
{
if
(
size
+
(
unsigned
long
)
addr
<
(
unsigned
long
)
tmp
->
addr
)
break
;
addr
=
(
void
*
)
(
tmp
->
size
+
(
unsigned
long
)
tmp
->
addr
);
}
if
((
unsigned
long
)
addr
+
size
>=
MODULES_END
)
return
NULL
;
area
=
(
struct
vm_struct
*
)
kmalloc
(
sizeof
(
*
area
),
GFP_KERNEL
);
if
(
!
area
)
return
NULL
;
area
->
size
=
size
+
PAGE_SIZE
;
area
->
addr
=
addr
;
area
->
next
=
*
p
;
area
->
pages
=
NULL
;
area
->
nr_pages
=
0
;
area
->
phys_addr
=
0
;
*
p
=
area
;
nr_pages
=
size
>>
PAGE_SHIFT
;
array_size
=
(
nr_pages
*
sizeof
(
struct
page
*
));
area
->
nr_pages
=
nr_pages
;
area
->
pages
=
pages
=
kmalloc
(
array_size
,
GFP_KERNEL
);
if
(
!
area
->
pages
)
goto
fail
;
memset
(
area
->
pages
,
0
,
array_size
);
for
(
i
=
0
;
i
<
area
->
nr_pages
;
i
++
)
{
area
->
pages
[
i
]
=
alloc_page
(
GFP_KERNEL
);
if
(
unlikely
(
!
area
->
pages
[
i
]))
goto
fail
;
}
if
(
map_vm_area
(
area
,
PAGE_KERNEL
,
&
pages
))
{
unmap_vm_area
(
area
);
goto
fail
;
}
return
area
->
addr
;
fail:
if
(
area
->
pages
)
{
for
(
i
=
0
;
i
<
area
->
nr_pages
;
i
++
)
{
if
(
area
->
pages
[
i
])
__free_page
(
area
->
pages
[
i
]);
}
kfree
(
area
->
pages
);
}
kfree
(
area
);
return
NULL
;
}
static
void
*
alloc_and_zero
(
unsigned
long
size
)
{
...
...
@@ -19,7 +126,7 @@ static void *alloc_and_zero(unsigned long size)
if
(
size
==
0
)
return
NULL
;
ret
=
vmalloc
(
size
);
ret
=
module_map
(
size
);
if
(
!
ret
)
ret
=
ERR_PTR
(
-
ENOMEM
);
else
...
...
@@ -31,7 +138,7 @@ static void *alloc_and_zero(unsigned long size)
/* Free memory returned from module_core_alloc/module_init_alloc */
void
module_free
(
struct
module
*
mod
,
void
*
module_region
)
{
vfree
(
module_region
);
module_unmap
(
module_region
);
/* FIXME: If module_region == mod->init_region, trim exception
table entries. */
}
...
...
@@ -82,6 +189,9 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
location
=
(
u8
*
)
sechdrs
[
sechdrs
[
relsec
].
sh_info
].
sh_offset
+
rel
[
i
].
r_offset
;
loc32
=
(
u32
*
)
location
;
BUG_ON
(((
u64
)
location
>>
(
u64
)
32
)
!=
(
u64
)
0
);
/* This is the symbol it is referring to */
sym
=
(
Elf64_Sym
*
)
sechdrs
[
symindex
].
sh_offset
+
ELF64_R_SYM
(
rel
[
i
].
r_info
);
...
...
@@ -90,7 +200,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
me
->
name
,
strtab
+
sym
->
st_name
);
return
-
ENOENT
;
}
v
+=
rel
->
r_addend
;
v
+=
rel
[
i
].
r_addend
;
switch
(
ELF64_R_TYPE
(
rel
[
i
].
r_info
)
&
0xff
)
{
case
R_SPARC_64
:
...
...
@@ -137,7 +247,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
me
->
name
,
(
int
)
(
ELF64_R_TYPE
(
rel
[
i
].
r_info
)
&
0xff
));
return
-
ENOEXEC
;
}
}
;
}
return
0
;
}
...
...
arch/sparc64/kernel/sys_sparc32.c
View file @
6ccc3e25
...
...
@@ -3113,24 +3113,18 @@ asmlinkage int sparc32_execve(struct pt_regs *regs)
#ifdef CONFIG_MODULES
extern
asmlinkage
long
sys_init_module
(
const
char
*
name_user
,
struct
module
*
mod_user
);
extern
asmlinkage
long
sys_init_module
(
void
*
,
unsigned
long
,
const
char
*
);
/* Hey, when you're trying to init module, take time and prepare us a nice
* 64bit module structure, even if from 32bit modutils... Why to pollute
* kernel... :))
*/
asmlinkage
int
sys32_init_module
(
const
char
*
name_user
,
struct
module
*
mod_user
)
asmlinkage
int
sys32_init_module
(
void
*
umod
,
u32
len
,
const
char
*
uargs
)
{
return
sys_init_module
(
name_user
,
mod_user
);
return
sys_init_module
(
umod
,
len
,
uargs
);
}
extern
asmlinkage
long
sys_delete_module
(
const
char
*
name_user
);
extern
asmlinkage
long
sys_delete_module
(
const
char
*
,
unsigned
int
);
asmlinkage
int
sys32_delete_module
(
const
char
*
name_user
)
asmlinkage
int
sys32_delete_module
(
const
char
*
name_user
,
unsigned
int
flags
)
{
return
sys_delete_module
(
name_user
);
return
sys_delete_module
(
name_user
,
flags
);
}
#else
/* CONFIG_MODULES */
...
...
crypto/api.c
View file @
6ccc3e25
...
...
@@ -263,8 +263,7 @@ static int c_show(struct seq_file *m, void *p)
struct
crypto_alg
*
alg
=
(
struct
crypto_alg
*
)
p
;
seq_printf
(
m
,
"name : %s
\n
"
,
alg
->
cra_name
);
seq_printf
(
m
,
"module : %s
\n
"
,
alg
->
cra_module
?
alg
->
cra_module
->
name
:
"[static]"
);
seq_printf
(
m
,
"module : %s
\n
"
,
module_name
(
alg
->
cra_module
));
seq_printf
(
m
,
"blocksize : %u
\n
"
,
alg
->
cra_blocksize
);
switch
(
alg
->
cra_flags
&
CRYPTO_ALG_TYPE_MASK
)
{
...
...
include/linux/in.h
View file @
6ccc3e25
...
...
@@ -70,6 +70,7 @@ struct in_addr {
#define IP_MTU 14
#define IP_FREEBIND 15
#define IP_IPSEC_POLICY 16
#define IP_XFRM_POLICY 17
/* BSD compatibility */
#define IP_RECVRETOPTS IP_RETOPTS
...
...
include/linux/module.h
View file @
6ccc3e25
...
...
@@ -242,6 +242,13 @@ static inline void module_put(struct module *module)
#endif
/* CONFIG_MODULE_UNLOAD */
/* This is a #define so the string doesn't get put in every .o file */
#define module_name(mod) \
({ \
struct module *__mod = (mod); \
__mod ? __mod->name : "kernel"; \
})
#define __unsafe(mod) \
do { \
if (mod && !(mod)->unsafe) { \
...
...
@@ -265,6 +272,8 @@ do { \
#define try_module_get(module) 1
#define module_put(module) do { } while(0)
#define module_name(mod) "kernel"
#define __unsafe(mod)
#endif
/* CONFIG_MODULES */
...
...
include/linux/udp.h
View file @
6ccc3e25
...
...
@@ -57,7 +57,4 @@ struct udp_sock {
#define udp_sk(__sk) (&((struct udp_sock *)__sk)->udp)
extern
int
udp_proc_init
(
void
);
extern
void
udp_proc_exit
(
void
);
#endif
/* _LINUX_UDP_H */
include/linux/xfrm.h
View file @
6ccc3e25
...
...
@@ -91,6 +91,22 @@ struct xfrm_stats {
__u32
integrity_failed
;
};
enum
{
XFRM_POLICY_IN
=
0
,
XFRM_POLICY_OUT
=
1
,
XFRM_POLICY_FWD
=
2
,
XFRM_POLICY_MAX
=
3
};
enum
{
XFRM_SHARE_ANY
,
/* No limitations */
XFRM_SHARE_SESSION
,
/* For this session only */
XFRM_SHARE_USER
,
/* For this user only */
XFRM_SHARE_UNIQUE
/* Use once */
};
/* Netlink configuration messages. */
#define XFRM_MSG_BASE 0x10
...
...
@@ -104,8 +120,9 @@ struct xfrm_stats {
#define XFRM_MSG_ALLOCSPI (RTM_BASE + 6)
#define XFRM_MSG_ACQUIRE (RTM_BASE + 7)
#define XFRM_MSG_EXPIRE (RTM_BASE + 8)
#define XFRM_MSG_MAX (XFRM_MSG_
ACQU
IRE+1)
#define XFRM_MSG_MAX (XFRM_MSG_
EXP
IRE+1)
struct
xfrm_user_tmpl
{
struct
xfrm_id
id
;
...
...
@@ -113,6 +130,7 @@ struct xfrm_user_tmpl {
__u16
reqid
;
__u8
mode
;
__u8
share
;
__u8
optional
;
__u32
aalgos
;
__u32
ealgos
;
__u32
calgos
;
...
...
@@ -135,9 +153,9 @@ struct xfrm_usersa_info {
struct
xfrm_lifetime_cfg
lft
;
struct
xfrm_lifetime_cur
curlft
;
struct
xfrm_stats
stats
;
__u32
seq
;
__u16
family
;
__u16
reqid
;
__u8
sa_type
;
__u8
mode
;
/* 0=transport,1=tunnel */
__u8
replay_window
;
};
...
...
@@ -148,15 +166,26 @@ struct xfrm_usersa_id {
__u8
proto
;
};
struct
xfrm_userspi_info
{
struct
xfrm_usersa_info
info
;
u32
min
;
u32
max
;
};
struct
xfrm_userpolicy_info
{
struct
xfrm_selector
sel
;
struct
xfrm_id
id
;
struct
xfrm_lifetime_cfg
lft
;
struct
xfrm_lifetime_cur
curlft
;
__u32
priority
;
__u32
index
;
__u16
family
;
__u8
dir
;
__u8
action
;
#define XFRM_POLICY_ALLOW 0
#define XFRM_POLICY_BLOCK 1
__u8
flags
;
#define XFRM_POLICY_LOCALOK 1
/* Allow user to override global policy */
__u8
share
;
};
struct
xfrm_userpolicy_id
{
...
...
@@ -165,4 +194,22 @@ struct xfrm_userpolicy_id {
__u8
dir
;
};
struct
xfrm_user_acquire
{
struct
xfrm_id
id
;
xfrm_address_t
saddr
;
struct
xfrm_userpolicy_info
policy
;
__u32
aalgos
;
__u32
ealgos
;
__u32
calgos
;
__u32
seq
;
};
struct
xfrm_user_expire
{
struct
xfrm_usersa_info
state
;
__u8
hard
;
};
#define XFRMGRP_ACQUIRE 1
#define XFRMGRP_EXPIRE 2
#endif
/* _LINUX_XFRM_H */
include/net/ip_fib.h
View file @
6ccc3e25
...
...
@@ -276,7 +276,4 @@ static inline void fib_res_put(struct fib_result *res)
#endif
}
extern
int
fib_proc_init
(
void
);
extern
void
fib_proc_exit
(
void
);
#endif
/* _NET_FIB_H */
include/net/udp.h
View file @
6ccc3e25
...
...
@@ -76,6 +76,4 @@ extern struct udp_mib udp_statistics[NR_CPUS*2];
#define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
#define UDP_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_statistics, field)
extern
int
udp_proc_init
(
void
);
#endif
/* _UDP_H */
include/net/xfrm.h
View file @
6ccc3e25
...
...
@@ -96,6 +96,7 @@ struct xfrm_state
u8
replay_window
;
u8
aalgo
,
ealgo
,
calgo
;
u16
reqid
;
u16
family
;
xfrm_address_t
saddr
;
int
header_len
;
int
trailer_len
;
...
...
@@ -187,22 +188,6 @@ struct xfrm_tmpl
#define XFRM_MAX_DEPTH 3
enum
{
XFRM_SHARE_ANY
,
/* No limitations */
XFRM_SHARE_SESSION
,
/* For this session only */
XFRM_SHARE_USER
,
/* For this user only */
XFRM_SHARE_UNIQUE
/* Use once */
};
enum
{
XFRM_POLICY_IN
=
0
,
XFRM_POLICY_OUT
=
1
,
XFRM_POLICY_FWD
=
2
,
XFRM_POLICY_MAX
=
3
};
struct
xfrm_policy
{
struct
xfrm_policy
*
next
;
...
...
@@ -217,11 +202,9 @@ struct xfrm_policy
struct
xfrm_lifetime_cfg
lft
;
struct
xfrm_lifetime_cur
curlft
;
struct
dst_entry
*
bundles
;
__u16
family
;
__u8
action
;
#define XFRM_POLICY_ALLOW 0
#define XFRM_POLICY_BLOCK 1
__u8
flags
;
#define XFRM_POLICY_LOCALOK 1
/* Allow user to override global policy */
__u8
dead
;
__u8
xfrm_nr
;
struct
xfrm_tmpl
xfrm_vec
[
XFRM_MAX_DEPTH
];
...
...
@@ -390,7 +373,7 @@ struct xfrm_policy *xfrm_policy_delete(int dir, struct xfrm_selector *sel);
struct
xfrm_policy
*
xfrm_policy_byid
(
int
dir
,
u32
id
,
int
delete
);
void
xfrm_policy_flush
(
void
);
void
xfrm_alloc_spi
(
struct
xfrm_state
*
x
,
u32
minspi
,
u32
maxspi
);
struct
xfrm_state
*
xfrm_find_acq
(
u8
mode
,
u16
reqid
,
u8
proto
,
u32
daddr
,
u32
saddr
);
struct
xfrm_state
*
xfrm_find_acq
(
u8
mode
,
u16
reqid
,
u8
proto
,
u32
daddr
,
u32
saddr
,
int
create
);
extern
void
xfrm_policy_flush
(
void
);
extern
void
xfrm_policy_kill
(
struct
xfrm_policy
*
);
extern
int
xfrm_sk_policy_insert
(
struct
sock
*
sk
,
int
dir
,
struct
xfrm_policy
*
pol
);
...
...
kernel/exec_domain.c
View file @
6ccc3e25
...
...
@@ -211,12 +211,7 @@ get_exec_domain_list(char *page)
for
(
ep
=
exec_domains
;
ep
&&
len
<
PAGE_SIZE
-
80
;
ep
=
ep
->
next
)
len
+=
sprintf
(
page
+
len
,
"%d-%d
\t
%-16s
\t
[%s]
\n
"
,
ep
->
pers_low
,
ep
->
pers_high
,
ep
->
name
,
#ifdef CONFIG_MODULES
ep
->
module
?
ep
->
module
->
name
:
"kernel"
#else
"kernel"
#endif
);
module_name
(
ep
->
module
));
read_unlock
(
&
exec_domains_lock
);
return
(
len
);
}
...
...
net/802/tr.c
View file @
6ccc3e25
...
...
@@ -541,10 +541,10 @@ static int rif_get_info(char *buffer,char **start, off_t offset, int length)
static
int
__init
rif_init
(
void
)
{
init_timer
(
&
rif_timer
);
rif_timer
.
expires
=
RIF_TIMEOUT
;
rif_timer
.
data
=
0L
;
rif_timer
.
function
=
rif_check_expire
;
init_timer
(
&
rif_timer
);
add_timer
(
&
rif_timer
);
proc_net_create
(
"tr_rif"
,
0
,
rif_get_info
);
...
...
net/atm/mpc.c
View file @
6ccc3e25
...
...
@@ -104,7 +104,7 @@ extern void mpc_proc_clean(void);
struct
mpoa_client
*
mpcs
=
NULL
;
/* FIXME */
static
struct
atm_mpoa_qos
*
qos_head
=
NULL
;
static
struct
timer_list
mpc_timer
;
static
struct
timer_list
mpc_timer
=
TIMER_INITIALIZER
(
NULL
,
0
,
0
)
;
static
struct
mpoa_client
*
find_mpc_by_itfnum
(
int
itf
)
...
...
net/core/neighbour.c
View file @
6ccc3e25
...
...
@@ -1151,8 +1151,8 @@ void neigh_table_init(struct neigh_table *tbl)
tasklet_init
(
&
tbl
->
gc_task
,
SMP_TIMER_NAME
(
neigh_periodic_timer
),
(
unsigned
long
)
tbl
);
#endif
init_timer
(
&
tbl
->
gc_timer
);
tbl
->
lock
=
RW_LOCK_UNLOCKED
;
init_timer
(
&
tbl
->
gc_timer
);
tbl
->
gc_timer
.
data
=
(
unsigned
long
)
tbl
;
tbl
->
gc_timer
.
function
=
neigh_periodic_timer
;
tbl
->
gc_timer
.
expires
=
now
+
tbl
->
gc_interval
+
...
...
net/ipv4/Kconfig
View file @
6ccc3e25
...
...
@@ -362,5 +362,13 @@ config INET_ESP
If unsure, say Y.
config XFRM_USER
tristate "IP: IPsec user configuration interface"
---help---
Support for IPsec user configuration interface used
by native Linux tools.
If unsure, say Y.
source "net/ipv4/netfilter/Kconfig"
net/ipv4/Makefile
View file @
6ccc3e25
...
...
@@ -20,6 +20,7 @@ obj-$(CONFIG_INET_AH) += ah.o
obj-$(CONFIG_INET_ESP)
+=
esp.o
obj-$(CONFIG_IP_PNP)
+=
ipconfig.o
obj-$(CONFIG_NETFILTER)
+=
netfilter/
obj-$(CONFIG_XFRM_USER)
+=
xfrm_user.o
obj-y
+=
xfrm_policy.o xfrm_state.o xfrm_input.o
...
...
net/ipv4/af_inet.c
View file @
6ccc3e25
...
...
@@ -1160,16 +1160,20 @@ module_init(inet_init);
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
extern
int
fib_proc_init
(
void
);
extern
void
fib_proc_exit
(
void
);
extern
int
ip_misc_proc_init
(
void
);
extern
int
raw_get_info
(
char
*
,
char
**
,
off_t
,
int
);
extern
int
tcp_get_info
(
char
*
,
char
**
,
off_t
,
int
);
extern
int
raw_proc_init
(
void
);
extern
void
raw_proc_exit
(
void
);
extern
int
tcp_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
);
extern
int
udp_proc_init
(
void
);
extern
void
udp_proc_exit
(
void
);
int
__init
ipv4_proc_init
(
void
)
{
int
rc
=
0
;
if
(
!
proc_net_create
(
"raw"
,
0
,
raw_get_info
))
if
(
raw_proc_init
(
))
goto
out_raw
;
if
(
!
proc_net_create
(
"tcp"
,
0
,
tcp_get_info
))
goto
out_tcp
;
...
...
@@ -1188,7 +1192,7 @@ int __init ipv4_proc_init(void)
out_udp:
proc_net_remove
(
"tcp"
);
out_tcp:
proc_net_remove
(
"raw"
);
raw_proc_exit
(
);
out_raw:
rc
=
-
ENOMEM
;
goto
out
;
...
...
net/ipv4/ah.c
View file @
6ccc3e25
...
...
@@ -189,7 +189,7 @@ int ah_output(struct sk_buff *skb)
top_iph
->
saddr
=
x
->
props
.
saddr
.
xfrm4_addr
;
top_iph
->
daddr
=
x
->
id
.
daddr
.
xfrm4_addr
;
ah
=
(
struct
ip_auth_hdr
*
)(
top_iph
+
1
);
ah
->
nexthdr
=
IPPROTO_IP
;
ah
->
nexthdr
=
IPPROTO_IP
IP
;
}
else
{
memcpy
(
&
tmp_iph
,
skb
->
data
,
iph
->
ihl
*
4
);
top_iph
=
(
struct
iphdr
*
)
skb_push
(
skb
,
x
->
props
.
header_len
);
...
...
net/ipv4/esp.c
View file @
6ccc3e25
...
...
@@ -190,11 +190,10 @@ esp_hmac_digest(struct esp_data *esp, struct sk_buff *skb, int offset,
struct
crypto_tfm
*
tfm
=
esp
->
auth
.
tfm
;
char
*
digest
=
esp
->
auth
.
work_digest
;
memset
(
auth_data
,
0
,
esp
->
auth
.
authlen
);
crypto_hmac_init
(
tfm
,
esp
->
auth
.
key
,
&
esp
->
auth
.
key_len
);
skb_digest_walk
(
skb
,
tfm
,
offset
,
len
);
crypto_hmac_final
(
tfm
,
esp
->
auth
.
key
,
&
esp
->
auth
.
key_len
,
digest
);
memcpy
(
auth_data
,
digest
,
crypto_tfm_alg_digestsize
(
tfm
)
);
memcpy
(
auth_data
,
digest
,
esp
->
auth
.
authlen
);
}
/* Check that skb data bits are writable. If they are not, copy data
...
...
@@ -370,7 +369,7 @@ int esp_output(struct sk_buff *skb)
if
(
x
->
props
.
mode
)
{
top_iph
=
(
struct
iphdr
*
)
skb_push
(
skb
,
x
->
props
.
header_len
);
esph
=
(
struct
ip_esp_hdr
*
)(
top_iph
+
1
);
*
(
u8
*
)(
trailer
->
tail
-
1
)
=
IPPROTO_IP
;
*
(
u8
*
)(
trailer
->
tail
-
1
)
=
IPPROTO_IP
IP
;
top_iph
->
ihl
=
5
;
top_iph
->
version
=
4
;
top_iph
->
tos
=
iph
->
tos
;
/* DS disclosed */
...
...
@@ -463,16 +462,16 @@ int esp_input(struct xfrm_state *x, struct sk_buff *skb)
/* If integrity check is required, do this. */
if
(
esp
->
auth
.
authlen
)
{
int
icvsize
=
crypto_tfm_alg_digestsize
(
esp
->
auth
.
tfm
);
u8
sum
[
icvsize
];
u8
sum1
[
icvsize
];
u8
sum
[
esp
->
auth
.
authlen
];
u8
sum1
[
esp
->
auth
.
authlen
];
esp
->
auth
.
digest
(
esp
,
skb
,
0
,
skb
->
len
-
esp
->
auth
.
authlen
,
sum
);
if
(
skb_copy_bits
(
skb
,
skb
->
len
-
esp
->
auth
.
authlen
,
sum1
,
icvsize
))
if
(
skb_copy_bits
(
skb
,
skb
->
len
-
esp
->
auth
.
authlen
,
sum1
,
esp
->
auth
.
authlen
))
BUG
();
if
(
unlikely
(
memcmp
(
sum
,
sum1
,
icvsize
)))
{
if
(
unlikely
(
memcmp
(
sum
,
sum1
,
esp
->
auth
.
authlen
)))
{
x
->
stats
.
integrity_failed
++
;
goto
out
;
}
...
...
@@ -605,14 +604,20 @@ int esp_init_state(struct xfrm_state *x, void *args)
memset
(
esp
,
0
,
sizeof
(
*
esp
));
if
(
x
->
aalg
)
{
int
digestsize
;
esp
->
auth
.
key
=
x
->
aalg
->
alg_key
;
esp
->
auth
.
key_len
=
(
x
->
aalg
->
alg_key_len
+
7
)
/
8
;
esp
->
auth
.
tfm
=
crypto_alloc_tfm
(
x
->
aalg
->
alg_name
,
0
);
if
(
esp
->
auth
.
tfm
==
NULL
)
goto
error
;
esp
->
auth
.
digest
=
esp_hmac_digest
;
esp
->
auth
.
authlen
=
crypto_tfm_alg_digestsize
(
esp
->
auth
.
tfm
);
esp
->
auth
.
work_digest
=
kmalloc
(
esp
->
auth
.
authlen
,
GFP_KERNEL
);
digestsize
=
crypto_tfm_alg_digestsize
(
esp
->
auth
.
tfm
);
/* XXX RFC2403 and RFC 2404 truncate auth to 96 bit */
esp
->
auth
.
authlen
=
12
;
if
(
esp
->
auth
.
authlen
>
digestsize
)
/* XXX */
BUG
();
esp
->
auth
.
work_digest
=
kmalloc
(
digestsize
,
GFP_KERNEL
);
if
(
!
esp
->
auth
.
work_digest
)
goto
error
;
}
...
...
net/ipv4/fib_hash.c
View file @
6ccc3e25
...
...
@@ -1092,16 +1092,4 @@ void __init fib_proc_exit(void)
{
remove_proc_entry
(
"route"
,
proc_net
);
}
#else
/* CONFIG_PROC_FS */
int
__init
fib_proc_init
(
void
)
{
return
0
;
}
void
__init
fib_proc_exit
(
void
)
{
return
0
;
}
#endif
/* CONFIG_PROC_FS */
net/ipv4/ip_sockglue.c
View file @
6ccc3e25
...
...
@@ -626,6 +626,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
break
;
case
IP_IPSEC_POLICY
:
case
IP_XFRM_POLICY
:
err
=
xfrm_user_policy
(
sk
,
optname
,
optval
,
optlen
);
break
;
...
...
net/ipv4/netfilter/ip_nat_helper.c
View file @
6ccc3e25
...
...
@@ -361,8 +361,6 @@ helper_cmp(const struct ip_nat_helper *helper,
return
ip_ct_tuple_mask_cmp
(
tuple
,
&
helper
->
tuple
,
&
helper
->
mask
);
}
#define MODULE_MAX_NAMELEN 32
int
ip_nat_helper_register
(
struct
ip_nat_helper
*
me
)
{
int
ret
=
0
;
...
...
@@ -374,14 +372,13 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
&&
ct_helper
->
me
)
{
__MOD_INC_USE_COUNT
(
ct_helper
->
me
);
}
else
{
#ifdef CONFIG_MODULES
/* We are a NAT helper for protocol X. If we need
* respective conntrack helper for protoccol X, compute
* conntrack helper name and try to load module */
char
name
[
MODULE_
MAX_NAME
LEN
];
const
char
*
tmp
=
m
e
->
me
->
name
;
char
name
[
MODULE_
NAME_
LEN
];
const
char
*
tmp
=
m
odule_name
(
me
->
me
)
;
if
(
strlen
(
tmp
)
+
6
>
MODULE_
MAX_NAME
LEN
)
{
if
(
strlen
(
tmp
)
+
6
>
MODULE_
NAME_
LEN
)
{
printk
(
"%s: unable to "
"compute conntrack helper name "
"from %s
\n
"
,
__FUNCTION__
,
tmp
);
...
...
@@ -403,7 +400,6 @@ int ip_nat_helper_register(struct ip_nat_helper *me)
"because kernel was compiled without kernel "
"module loader support
\n
"
,
name
);
return
-
EBUSY
;
#endif
#endif
}
}
...
...
net/ipv4/proc.c
View file @
6ccc3e25
...
...
@@ -26,27 +26,18 @@
* Andi Kleen : Add support for open_requests and
* split functions for more readibility.
* Andi Kleen : Add support for /proc/net/netstat
* Arnaldo C. Melo : Convert to seq_file
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <asm/system.h>
#include <linux/sched.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/un.h>
#include <linux/in.h>
#include <linux/param.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <net/ip.h>
#include <linux/types.h>
#include <net/icmp.h>
#include <net/protocol.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/sock.h>
...
...
@@ -57,7 +48,7 @@ static int fold_prot_inuse(struct proto *proto)
int
res
=
0
;
int
cpu
;
for
(
cpu
=
0
;
cpu
<
NR_CPUS
;
cpu
++
)
for
(
cpu
=
0
;
cpu
<
NR_CPUS
;
cpu
++
)
res
+=
proto
->
stats
[
cpu
].
inuse
;
return
res
;
...
...
@@ -66,38 +57,35 @@ static int fold_prot_inuse(struct proto *proto)
/*
* Report socket allocation statistics [mea@utu.fi]
*/
int
afinet_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
static
int
sockstat_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
/* From net/socket.c */
extern
int
socket_get_info
(
char
*
,
char
**
,
off_t
,
int
);
extern
void
socket_seq_show
(
struct
seq_file
*
seq
);
int
len
=
socket_get_info
(
buffer
,
start
,
offset
,
length
);
len
+=
sprintf
(
buffer
+
len
,
"TCP: inuse %d orphan %d tw %d alloc %d mem %d
\n
"
,
fold_prot_inuse
(
&
tcp_prot
),
atomic_read
(
&
tcp_orphan_count
),
tcp_tw_count
,
atomic_read
(
&
tcp_sockets_allocated
),
socket_seq_show
(
seq
);
seq_printf
(
seq
,
"TCP: inuse %d orphan %d tw %d alloc %d mem %d
\n
"
,
fold_prot_inuse
(
&
tcp_prot
),
atomic_read
(
&
tcp_orphan_count
),
tcp_tw_count
,
atomic_read
(
&
tcp_sockets_allocated
),
atomic_read
(
&
tcp_memory_allocated
));
len
+=
sprintf
(
buffer
+
len
,
"UDP: inuse %d
\n
"
,
fold_prot_inuse
(
&
udp_prot
));
len
+=
sprintf
(
buffer
+
len
,
"RAW: inuse %d
\n
"
,
fold_prot_inuse
(
&
raw_prot
));
len
+=
sprintf
(
buffer
+
len
,
"FRAG: inuse %d memory %d
\n
"
,
ip_frag_nqueues
,
atomic_read
(
&
ip_frag_mem
));
if
(
offset
>=
len
)
{
*
start
=
buffer
;
seq_printf
(
seq
,
"UDP: inuse %d
\n
"
,
fold_prot_inuse
(
&
udp_prot
));
seq_printf
(
seq
,
"RAW: inuse %d
\n
"
,
fold_prot_inuse
(
&
raw_prot
));
seq_printf
(
seq
,
"FRAG: inuse %d memory %d
\n
"
,
ip_frag_nqueues
,
atomic_read
(
&
ip_frag_mem
));
return
0
;
}
*
start
=
buffer
+
offset
;
len
-=
offset
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
static
int
sockstat_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
sockstat_seq_show
,
NULL
);
}
static
struct
file_operations
sockstat_seq_fops
=
{
.
open
=
sockstat_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
unsigned
long
fold_field
(
unsigned
long
*
begin
,
int
sz
,
int
nr
)
{
unsigned
long
res
=
0
;
...
...
@@ -105,9 +93,9 @@ static unsigned long fold_field(unsigned long *begin, int sz, int nr)
sz
/=
sizeof
(
unsigned
long
);
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
res
+=
begin
[
2
*
i
*
sz
+
nr
];
res
+=
begin
[(
2
*
i
+
1
)
*
sz
+
nr
];
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
res
+=
begin
[
2
*
i
*
sz
+
nr
];
res
+=
begin
[(
2
*
i
+
1
)
*
sz
+
nr
];
}
return
res
;
}
...
...
@@ -115,52 +103,73 @@ static unsigned long fold_field(unsigned long *begin, int sz, int nr)
/*
* Called from the PROCfs module. This outputs /proc/net/snmp.
*/
int
snmp_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
static
int
snmp_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
extern
int
sysctl_ip_default_ttl
;
int
len
,
i
;
len
=
sprintf
(
buffer
,
"Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
\n
"
"Ip: %d %d"
,
ipv4_devconf
.
forwarding
?
1
:
2
,
sysctl_ip_default_ttl
);
for
(
i
=
0
;
i
<
offsetof
(
struct
ip_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
len
+=
sprintf
(
buffer
+
len
,
" %lu"
,
fold_field
((
unsigned
long
*
)
ip_statistics
,
sizeof
(
struct
ip_mib
),
i
));
len
+=
sprintf
(
buffer
+
len
,
"
\n
Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
\n
"
"Icmp:"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
icmp_mib
,
dummy
)
/
sizeof
(
unsigned
long
);
i
++
)
len
+=
sprintf
(
buffer
+
len
,
" %lu"
,
fold_field
((
unsigned
long
*
)
icmp_statistics
,
sizeof
(
struct
icmp_mib
),
i
));
len
+=
sprintf
(
buffer
+
len
,
"
\n
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts
\n
"
"Tcp:"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
tcp_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
len
+=
sprintf
(
buffer
+
len
,
" %lu"
,
fold_field
((
unsigned
long
*
)
tcp_statistics
,
sizeof
(
struct
tcp_mib
),
i
));
len
+=
sprintf
(
buffer
+
len
,
"
\n
Udp: InDatagrams NoPorts InErrors OutDatagrams
\n
"
int
i
;
seq_printf
(
seq
,
"Ip: Forwarding DefaultTTL InReceives InHdrErrors "
"InAddrErrors ForwDatagrams InUnknownProtos "
"InDiscards InDelivers OutRequests OutDiscards "
"OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs "
"ReasmFails FragOKs FragFails FragCreates
\n
Ip: %d %d"
,
ipv4_devconf
.
forwarding
?
1
:
2
,
sysctl_ip_default_ttl
);
for
(
i
=
0
;
i
<
offsetof
(
struct
ip_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
seq_printf
(
seq
,
" %lu"
,
fold_field
((
unsigned
long
*
)
ip_statistics
,
sizeof
(
struct
ip_mib
),
i
));
seq_printf
(
seq
,
"
\n
Icmp: InMsgs InErrors InDestUnreachs InTimeExcds "
"InParmProbs InSrcQuenchs InRedirects InEchos "
"InEchoReps InTimestamps InTimestampReps InAddrMasks "
"InAddrMaskReps OutMsgs OutErrors OutDestUnreachs "
"OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects "
"OutEchos OutEchoReps OutTimestamps OutTimestampReps "
"OutAddrMasks OutAddrMaskReps
\n
Icmp:"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
icmp_mib
,
dummy
)
/
sizeof
(
unsigned
long
);
i
++
)
seq_printf
(
seq
,
" %lu"
,
fold_field
((
unsigned
long
*
)
icmp_statistics
,
sizeof
(
struct
icmp_mib
),
i
));
seq_printf
(
seq
,
"
\n
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens "
"PassiveOpens AttemptFails EstabResets CurrEstab "
"InSegs OutSegs RetransSegs InErrs OutRsts
\n
Tcp:"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
tcp_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
seq_printf
(
seq
,
" %lu"
,
fold_field
((
unsigned
long
*
)
tcp_statistics
,
sizeof
(
struct
tcp_mib
),
i
));
seq_printf
(
seq
,
"
\n
Udp: InDatagrams NoPorts InErrors OutDatagrams
\n
"
"Udp:"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
udp_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
len
+=
sprintf
(
buffer
+
len
,
" %lu"
,
fold_field
((
unsigned
long
*
)
udp_statistics
,
sizeof
(
struct
udp_mib
),
i
));
len
+=
sprintf
(
buffer
+
len
,
"
\n
"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
udp_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
seq_printf
(
seq
,
" %lu"
,
fold_field
((
unsigned
long
*
)
udp_statistics
,
sizeof
(
struct
udp_mib
),
i
));
if
(
offset
>=
len
)
{
*
start
=
buffer
;
seq_putc
(
seq
,
'\n'
);
return
0
;
}
*
start
=
buffer
+
offset
;
len
-=
offset
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
static
int
snmp_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
snmp_seq_show
,
NULL
);
}
static
struct
file_operations
snmp_seq_fops
=
{
.
open
=
snmp_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
/*
* Output /proc/net/netstat
*/
...
...
@@ -181,7 +190,8 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
" TCPPureAcks TCPHPAcks"
" TCPRenoRecovery TCPSackRecovery"
" TCPSACKReneging"
" TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder"
" TCPFACKReorder TCPSACKReorder TCPRenoReorder"
" TCPTSReorder"
" TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo"
" TCPLoss TCPLostRetransmit"
" TCPRenoFailures TCPSackFailures TCPLossFailures"
...
...
@@ -189,14 +199,14 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
" TCPTimeouts"
" TCPRenoRecoveryFail TCPSackRecoveryFail"
" TCPSchedulerFailed TCPRcvCollapsed"
" TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv"
" TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv"
" TCPDSACKOfoRecv"
" TCPAbortOnSyn TCPAbortOnData TCPAbortOnClose"
" TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger"
" TCPAbortFailed TCPMemoryPressures
\n
"
"TcpExt:"
);
for
(
i
=
0
;
i
<
offsetof
(
struct
linux_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
i
<
offsetof
(
struct
linux_mib
,
__pad
)
/
sizeof
(
unsigned
long
);
i
++
)
seq_printf
(
seq
,
" %lu"
,
fold_field
((
unsigned
long
*
)
net_statistics
,
sizeof
(
struct
linux_mib
),
i
));
...
...
@@ -219,20 +229,26 @@ static struct file_operations netstat_seq_fops = {
int
__init
ip_misc_proc_init
(
void
)
{
int
rc
=
0
;
struct
proc_dir_entry
*
p
=
create_proc_entry
(
"netstat"
,
S_IRUGO
,
proc_net
)
;
struct
proc_dir_entry
*
p
;
p
=
create_proc_entry
(
"netstat"
,
S_IRUGO
,
proc_net
);
if
(
!
p
)
goto
out_netstat
;
p
->
proc_fops
=
&
netstat_seq_fops
;
if
(
!
proc_net_create
(
"snmp"
,
0
,
snmp_get_info
))
p
=
create_proc_entry
(
"snmp"
,
S_IRUGO
,
proc_net
);
if
(
!
p
)
goto
out_snmp
;
if
(
!
proc_net_create
(
"sockstat"
,
0
,
afinet_get_info
))
p
->
proc_fops
=
&
snmp_seq_fops
;
p
=
create_proc_entry
(
"sockstat"
,
S_IRUGO
,
proc_net
);
if
(
!
p
)
goto
out_sockstat
;
p
->
proc_fops
=
&
sockstat_seq_fops
;
out:
return
rc
;
out_sockstat:
proc_net_remove
(
"snmp"
);
remove_proc_entry
(
"snmp"
,
proc_net
);
out_snmp:
remove_proc_entry
(
"netstat"
,
proc_net
);
out_netstat:
...
...
net/ipv4/raw.c
View file @
6ccc3e25
...
...
@@ -40,31 +40,42 @@
*/
#include <linux/config.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/byteorder.h>
#include <asm/current.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/aio.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
#include <linux/spinlock.h>
#include <linux/sockios.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/
m
route.h>
#include <
net/tcp
.h>
#include <
net/protocol
.h>
#include <linux/
in_
route.h>
#include <
linux/route
.h>
#include <
linux/tcp
.h>
#include <linux/skbuff.h>
#include <net/dst.h>
#include <net/sock.h>
#include <linux/gfp.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <net/icmp.h>
#include <net/udp.h>
#include <net/raw.h>
#include <net/snmp.h>
#include <net/inet_common.h>
#include <net/checksum.h>
#include <net/xfrm.h>
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
struct
sock
*
raw_v4_htable
[
RAWV4_HTABLE_SIZE
];
...
...
@@ -656,7 +667,95 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
}
}
static
void
get_raw_sock
(
struct
sock
*
sp
,
char
*
tmpbuf
,
int
i
)
struct
proto
raw_prot
=
{
.
name
=
"RAW"
,
.
close
=
raw_close
,
.
connect
=
udp_connect
,
.
disconnect
=
udp_disconnect
,
.
ioctl
=
raw_ioctl
,
.
init
=
raw_init
,
.
setsockopt
=
raw_setsockopt
,
.
getsockopt
=
raw_getsockopt
,
.
sendmsg
=
raw_sendmsg
,
.
recvmsg
=
raw_recvmsg
,
.
bind
=
raw_bind
,
.
backlog_rcv
=
raw_rcv_skb
,
.
hash
=
raw_v4_hash
,
.
unhash
=
raw_v4_unhash
,
};
#ifdef CONFIG_PROC_FS
struct
raw_iter_state
{
int
bucket
;
};
#define raw_seq_private(seq) ((struct raw_iter_state *)&seq->private)
static
struct
sock
*
raw_get_first
(
struct
seq_file
*
seq
)
{
struct
sock
*
sk
=
NULL
;
struct
raw_iter_state
*
state
=
raw_seq_private
(
seq
);
for
(
state
->
bucket
=
0
;
state
->
bucket
<
RAWV4_HTABLE_SIZE
;
++
state
->
bucket
)
{
sk
=
raw_v4_htable
[
state
->
bucket
];
while
(
sk
&&
sk
->
family
!=
PF_INET
)
sk
=
sk
->
next
;
if
(
sk
)
break
;
}
return
sk
;
}
static
struct
sock
*
raw_get_next
(
struct
seq_file
*
seq
,
struct
sock
*
sk
)
{
struct
raw_iter_state
*
state
=
raw_seq_private
(
seq
);
do
{
sk
=
sk
->
next
;
try_again:
}
while
(
sk
&&
sk
->
family
!=
PF_INET
);
if
(
!
sk
&&
++
state
->
bucket
<
RAWV4_HTABLE_SIZE
)
{
sk
=
raw_v4_htable
[
state
->
bucket
];
goto
try_again
;
}
return
sk
;
}
static
struct
sock
*
raw_get_idx
(
struct
seq_file
*
seq
,
loff_t
pos
)
{
struct
sock
*
sk
=
raw_get_first
(
seq
);
if
(
sk
)
while
(
pos
&&
(
sk
=
raw_get_next
(
seq
,
sk
))
!=
NULL
)
--
pos
;
return
pos
?
NULL
:
sk
;
}
static
void
*
raw_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
read_lock
(
&
raw_v4_lock
);
return
*
pos
?
raw_get_idx
(
seq
,
*
pos
)
:
(
void
*
)
1
;
}
static
void
*
raw_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
struct
sock
*
sk
;
if
(
v
==
(
void
*
)
1
)
sk
=
raw_get_first
(
seq
);
else
sk
=
raw_get_next
(
seq
,
v
);
++*
pos
;
return
sk
;
}
static
void
raw_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
read_unlock
(
&
raw_v4_lock
);
}
static
__inline__
char
*
get_raw_sock
(
struct
sock
*
sp
,
char
*
tmpbuf
,
int
i
)
{
struct
inet_opt
*
inet
=
inet_sk
(
sp
);
unsigned
int
dest
=
inet
->
daddr
,
...
...
@@ -668,65 +767,63 @@ static void get_raw_sock(struct sock *sp, char *tmpbuf, int i)
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p"
,
i
,
src
,
srcp
,
dest
,
destp
,
sp
->
state
,
atomic_read
(
&
sp
->
wmem_alloc
),
atomic_read
(
&
sp
->
rmem_alloc
),
0
,
0L
,
0
,
sock_i_uid
(
sp
),
0
,
sock_i_ino
(
sp
),
0
,
0L
,
0
,
sock_i_uid
(
sp
),
0
,
sock_i_ino
(
sp
),
atomic_read
(
&
sp
->
refcnt
),
sp
);
return
tmpbuf
;
}
int
raw_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
static
int
raw_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
int
len
=
0
,
num
=
0
,
i
;
off_t
pos
=
128
;
off_t
begin
;
char
tmpbuf
[
129
];
if
(
offset
<
128
)
len
+=
sprintf
(
buffer
,
"%-127s
\n
"
,
if
(
v
==
(
void
*
)
1
)
seq_printf
(
seq
,
"%-127s
\n
"
,
" sl local_address rem_address st tx_queue "
"rx_queue tr tm->when retrnsmt uid timeout "
"inode"
);
read_lock
(
&
raw_v4_lock
);
for
(
i
=
0
;
i
<
RAWV4_HTABLE_SIZE
;
i
++
)
{
struct
sock
*
sk
;
else
{
struct
raw_iter_state
*
state
=
raw_seq_private
(
seq
);
for
(
sk
=
raw_v4_htable
[
i
];
sk
;
sk
=
sk
->
next
,
num
++
)
{
if
(
sk
->
family
!=
PF_INET
)
continue
;
pos
+=
128
;
if
(
pos
<=
offset
)
continue
;
get_raw_sock
(
sk
,
tmpbuf
,
i
);
len
+=
sprintf
(
buffer
+
len
,
"%-127s
\n
"
,
tmpbuf
);
if
(
len
>=
length
)
goto
out
;
}
seq_printf
(
seq
,
"%-127s
\n
"
,
get_raw_sock
(
v
,
tmpbuf
,
state
->
bucket
));
}
out:
read_unlock
(
&
raw_v4_lock
);
begin
=
len
-
(
pos
-
offset
);
*
start
=
buffer
+
begin
;
len
-=
begin
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
return
0
;
}
struct
proto
raw_prot
=
{
.
name
=
"RAW"
,
.
close
=
raw_close
,
.
connect
=
udp_connect
,
.
disconnect
=
udp_disconnect
,
.
ioctl
=
raw_ioctl
,
.
init
=
raw_init
,
.
setsockopt
=
raw_setsockopt
,
.
getsockopt
=
raw_getsockopt
,
.
sendmsg
=
raw_sendmsg
,
.
recvmsg
=
raw_recvmsg
,
.
bind
=
raw_bind
,
.
backlog_rcv
=
raw_rcv_skb
,
.
hash
=
raw_v4_hash
,
.
unhash
=
raw_v4_unhash
,
static
struct
seq_operations
raw_seq_ops
=
{
.
start
=
raw_seq_start
,
.
next
=
raw_seq_next
,
.
stop
=
raw_seq_stop
,
.
show
=
raw_seq_show
,
};
static
int
raw_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_open
(
file
,
&
raw_seq_ops
);
}
static
struct
file_operations
raw_seq_fops
=
{
.
open
=
raw_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release
,
};
int
__init
raw_proc_init
(
void
)
{
struct
proc_dir_entry
*
p
;
int
rc
=
0
;
p
=
create_proc_entry
(
"raw"
,
S_IRUGO
,
proc_net
);
if
(
p
)
p
->
proc_fops
=
&
raw_seq_fops
;
else
rc
=
-
ENOMEM
;
return
rc
;
}
void
__init
raw_proc_exit
(
void
)
{
remove_proc_entry
(
"raw"
,
proc_net
);
}
#endif
/* CONFIG_PROC_FS */
net/ipv4/udp.c
View file @
6ccc3e25
...
...
@@ -944,7 +944,7 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
/*
* Charge it to the socket, dropping if the queue is full.
*/
if
(
!
xfrm_policy_check
(
NULL
,
XFRM_POLICY_IN
,
skb
))
{
if
(
!
xfrm_policy_check
(
sk
,
XFRM_POLICY_IN
,
skb
))
{
kfree_skb
(
skb
);
return
-
1
;
}
...
...
@@ -1377,16 +1377,4 @@ void __init udp_proc_exit(void)
{
remove_proc_entry
(
"udp"
,
proc_net
);
}
#else
/* CONFIG_PROC_FS */
int
__init
udp_proc_init
(
void
)
{
return
0
;
}
void
__init
udp_proc_exit
(
void
)
{
return
0
;
}
#endif
/* CONFIG_PROC_FS */
net/ipv4/xfrm_input.c
View file @
6ccc3e25
...
...
@@ -91,7 +91,7 @@ int xfrm4_rcv(struct sk_buff *skb)
iph
=
skb
->
nh
.
iph
;
if
(
x
->
props
.
mode
)
{
if
(
iph
->
protocol
!=
IPPROTO_IP
)
if
(
iph
->
protocol
!=
IPPROTO_IP
IP
)
goto
drop
;
skb
->
nh
.
raw
=
skb
->
data
;
iph
=
skb
->
nh
.
iph
;
...
...
net/ipv4/xfrm_state.c
View file @
6ccc3e25
...
...
@@ -386,7 +386,7 @@ xfrm_state_lookup(u32 daddr, u32 spi, u8 proto)
}
struct
xfrm_state
*
xfrm_find_acq
(
u8
mode
,
u16
reqid
,
u8
proto
,
u32
daddr
,
u32
saddr
)
xfrm_find_acq
(
u8
mode
,
u16
reqid
,
u8
proto
,
u32
daddr
,
u32
saddr
,
int
create
)
{
struct
xfrm_state
*
x
,
*
x0
;
unsigned
h
=
ntohl
(
daddr
);
...
...
@@ -400,10 +400,11 @@ xfrm_find_acq(u8 mode, u16 reqid, u8 proto, u32 daddr, u32 saddr)
mode
==
x
->
props
.
mode
&&
proto
==
x
->
id
.
proto
&&
saddr
==
x
->
props
.
saddr
.
xfrm4_addr
&&
reqid
==
x
->
props
.
reqid
)
{
reqid
==
x
->
props
.
reqid
&&
x
->
km
.
state
==
XFRM_STATE_ACQ
)
{
if
(
!
x0
)
x0
=
x
;
if
(
x
->
km
.
state
!=
XFRM_STATE_ACQ
)
if
(
x
->
id
.
spi
)
continue
;
x0
=
x
;
break
;
...
...
@@ -411,7 +412,7 @@ xfrm_find_acq(u8 mode, u16 reqid, u8 proto, u32 daddr, u32 saddr)
}
if
(
x0
)
{
atomic_inc
(
&
x0
->
refcnt
);
}
else
if
((
x0
=
xfrm_state_alloc
())
!=
NULL
)
{
}
else
if
(
create
&&
(
x0
=
xfrm_state_alloc
())
!=
NULL
)
{
x0
->
sel
.
daddr
.
xfrm4_addr
=
daddr
;
x0
->
sel
.
daddr
.
xfrm4_mask
=
~
0
;
x0
->
sel
.
saddr
.
xfrm4_addr
=
saddr
;
...
...
net/ipv4/xfrm_user.c
0 → 100644
View file @
6ccc3e25
/* xfrm_user.c: User interface to configure xfrm engine.
*
* Copyright (C) 2002 David S. Miller (davem@redhat.com)
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/string.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
#include <linux/init.h>
#include <net/sock.h>
#include <net/xfrm.h>
static
struct
sock
*
xfrm_nl
;
static
int
verify_one_alg
(
struct
rtattr
**
xfrma
,
enum
xfrm_attr_type_t
type
)
{
struct
rtattr
*
rt
=
xfrma
[
type
];
struct
xfrm_algo
*
algp
;
if
(
!
rt
)
return
0
;
if
((
rt
->
rta_len
-
sizeof
(
*
rt
))
<
sizeof
(
*
algp
))
return
-
EINVAL
;
algp
=
RTA_DATA
(
rt
);
switch
(
type
)
{
case
XFRMA_ALG_AUTH
:
case
XFRMA_ALG_CRYPT
:
if
(
!
algp
->
alg_key_len
)
return
-
EINVAL
;
break
;
case
XFRMA_ALG_COMP
:
/* Zero length keys are legal. */
break
;
default:
return
-
EINVAL
;
};
algp
->
alg_name
[
CRYPTO_MAX_ALG_NAME
-
1
]
=
'\0'
;
return
0
;
}
static
int
verify_newsa_info
(
struct
xfrm_usersa_info
*
p
,
struct
rtattr
**
xfrma
)
{
int
err
;
err
=
-
EINVAL
;
switch
(
p
->
family
)
{
case
AF_INET
:
break
;
case
AF_INET6
:
/* XXX */
err
=
-
EAFNOSUPPORT
;
/* fallthru */
default:
goto
out
;
};
err
=
-
EINVAL
;
switch
(
p
->
id
.
proto
)
{
case
IPPROTO_AH
:
if
(
!
xfrma
[
XFRMA_ALG_AUTH
]
||
xfrma
[
XFRMA_ALG_CRYPT
]
||
xfrma
[
XFRMA_ALG_COMP
])
goto
out
;
break
;
case
IPPROTO_ESP
:
if
((
!
xfrma
[
XFRMA_ALG_AUTH
]
&&
!
xfrma
[
XFRMA_ALG_CRYPT
])
||
xfrma
[
XFRMA_ALG_COMP
])
goto
out
;
break
;
case
IPPROTO_COMP
:
if
(
!
xfrma
[
XFRMA_ALG_COMP
]
||
xfrma
[
XFRMA_ALG_AUTH
]
||
xfrma
[
XFRMA_ALG_CRYPT
])
goto
out
;
break
;
default:
goto
out
;
};
if
((
err
=
verify_one_alg
(
xfrma
,
XFRMA_ALG_AUTH
)))
goto
out
;
if
((
err
=
verify_one_alg
(
xfrma
,
XFRMA_ALG_CRYPT
)))
goto
out
;
if
((
err
=
verify_one_alg
(
xfrma
,
XFRMA_ALG_COMP
)))
goto
out
;
err
=
-
EINVAL
;
switch
(
p
->
mode
)
{
case
0
:
case
1
:
break
;
default:
goto
out
;
};
err
=
0
;
out:
return
err
;
}
static
int
attach_one_algo
(
struct
xfrm_algo
**
algpp
,
struct
rtattr
*
u_arg
)
{
struct
rtattr
*
rta
=
u_arg
;
struct
xfrm_algo
*
p
,
*
ualg
;
if
(
!
rta
)
return
0
;
ualg
=
RTA_DATA
(
rta
);
p
=
kmalloc
(
sizeof
(
*
ualg
)
+
ualg
->
alg_key_len
,
GFP_KERNEL
);
if
(
!
p
)
return
-
ENOMEM
;
memcpy
(
p
,
ualg
,
sizeof
(
*
ualg
)
+
ualg
->
alg_key_len
);
*
algpp
=
p
;
return
0
;
}
static
void
copy_from_user_state
(
struct
xfrm_state
*
x
,
struct
xfrm_usersa_info
*
p
)
{
memcpy
(
&
x
->
id
,
&
p
->
id
,
sizeof
(
x
->
id
));
memcpy
(
&
x
->
sel
,
&
p
->
sel
,
sizeof
(
x
->
sel
));
memcpy
(
&
x
->
lft
,
&
p
->
lft
,
sizeof
(
x
->
lft
));
x
->
props
.
mode
=
p
->
mode
;
x
->
props
.
replay_window
=
p
->
replay_window
;
x
->
props
.
reqid
=
p
->
reqid
;
x
->
props
.
family
=
p
->
family
;
x
->
props
.
saddr
=
x
->
sel
.
saddr
;
}
static
struct
xfrm_state
*
xfrm_state_construct
(
struct
xfrm_usersa_info
*
p
,
struct
rtattr
**
xfrma
,
int
*
errp
)
{
struct
xfrm_state
*
x
=
xfrm_state_alloc
();
int
err
=
-
ENOMEM
;
if
(
!
x
)
goto
error_no_put
;
copy_from_user_state
(
x
,
p
);
if
((
err
=
attach_one_algo
(
&
x
->
aalg
,
xfrma
[
XFRMA_ALG_AUTH
])))
goto
error
;
if
((
err
=
attach_one_algo
(
&
x
->
ealg
,
xfrma
[
XFRMA_ALG_CRYPT
])))
goto
error
;
if
((
err
=
attach_one_algo
(
&
x
->
calg
,
xfrma
[
XFRMA_ALG_COMP
])))
goto
error
;
err
=
-
ENOENT
;
x
->
type
=
xfrm_get_type
(
x
->
id
.
proto
);
if
(
x
->
type
==
NULL
)
goto
error
;
err
=
x
->
type
->
init_state
(
x
,
NULL
);
if
(
err
)
goto
error
;
x
->
curlft
.
add_time
=
(
unsigned
long
)
xtime
.
tv_sec
;
x
->
km
.
state
=
XFRM_STATE_VALID
;
x
->
km
.
seq
=
p
->
seq
;
return
x
;
error:
xfrm_state_put
(
x
);
error_no_put:
*
errp
=
err
;
return
NULL
;
}
static
int
xfrm_add_sa
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_usersa_info
*
p
=
NLMSG_DATA
(
nlh
);
struct
xfrm_state
*
x
,
*
x1
;
int
err
;
err
=
verify_newsa_info
(
p
,
(
struct
rtattr
**
)
xfrma
);
if
(
err
)
return
err
;
x
=
xfrm_state_construct
(
p
,
(
struct
rtattr
**
)
xfrma
,
&
err
);
if
(
!
x
)
return
err
;
x1
=
xfrm_state_lookup
(
x
->
props
.
saddr
.
xfrm4_addr
,
x
->
id
.
spi
,
x
->
id
.
proto
);
if
(
x1
)
{
xfrm_state_put
(
x
);
xfrm_state_put
(
x1
);
return
-
EEXIST
;
}
xfrm_state_insert
(
x
);
return
0
;
}
static
int
xfrm_del_sa
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_state
*
x
;
struct
xfrm_usersa_id
*
p
=
NLMSG_DATA
(
nlh
);
x
=
xfrm_state_lookup
(
p
->
saddr
.
xfrm4_addr
,
p
->
spi
,
p
->
proto
);
if
(
x
==
NULL
)
return
-
ESRCH
;
xfrm_state_delete
(
x
);
xfrm_state_put
(
x
);
return
0
;
}
static
void
copy_to_user_state
(
struct
xfrm_state
*
x
,
struct
xfrm_usersa_info
*
p
)
{
memcpy
(
&
p
->
id
,
&
x
->
id
,
sizeof
(
p
->
id
));
memcpy
(
&
p
->
sel
,
&
x
->
sel
,
sizeof
(
p
->
sel
));
memcpy
(
&
p
->
lft
,
&
x
->
lft
,
sizeof
(
p
->
lft
));
memcpy
(
&
p
->
curlft
,
&
x
->
curlft
,
sizeof
(
p
->
curlft
));
memcpy
(
&
p
->
stats
,
&
x
->
stats
,
sizeof
(
p
->
stats
));
p
->
mode
=
x
->
props
.
mode
;
p
->
replay_window
=
x
->
props
.
replay_window
;
p
->
reqid
=
x
->
props
.
reqid
;
p
->
family
=
x
->
props
.
family
;
p
->
seq
=
x
->
km
.
seq
;
}
struct
xfrm_dump_info
{
struct
sk_buff
*
in_skb
;
struct
sk_buff
*
out_skb
;
u32
nlmsg_seq
;
int
start_idx
;
int
this_idx
;
};
static
int
dump_one_state
(
struct
xfrm_state
*
x
,
int
count
,
void
*
ptr
)
{
struct
xfrm_dump_info
*
sp
=
ptr
;
struct
sk_buff
*
in_skb
=
sp
->
in_skb
;
struct
sk_buff
*
skb
=
sp
->
out_skb
;
struct
xfrm_usersa_info
*
p
;
struct
nlmsghdr
*
nlh
;
unsigned
char
*
b
=
skb
->
tail
;
if
(
sp
->
this_idx
<
sp
->
start_idx
)
goto
out
;
nlh
=
NLMSG_PUT
(
skb
,
NETLINK_CB
(
in_skb
).
pid
,
sp
->
nlmsg_seq
,
XFRM_MSG_NEWSA
,
sizeof
(
*
p
));
nlh
->
nlmsg_flags
=
0
;
p
=
NLMSG_DATA
(
nlh
);
copy_to_user_state
(
x
,
p
);
if
(
x
->
aalg
)
RTA_PUT
(
skb
,
XFRMA_ALG_AUTH
,
sizeof
(
*
(
x
->
aalg
)),
x
->
aalg
);
if
(
x
->
ealg
)
RTA_PUT
(
skb
,
XFRMA_ALG_CRYPT
,
sizeof
(
*
(
x
->
ealg
)),
x
->
ealg
);
if
(
x
->
calg
)
RTA_PUT
(
skb
,
XFRMA_ALG_COMP
,
sizeof
(
*
(
x
->
calg
)),
x
->
calg
);
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
out:
sp
->
this_idx
++
;
return
0
;
nlmsg_failure:
rtattr_failure:
skb_trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
static
int
xfrm_dump_sa
(
struct
sk_buff
*
skb
,
struct
netlink_callback
*
cb
)
{
struct
xfrm_dump_info
info
;
info
.
in_skb
=
cb
->
skb
;
info
.
out_skb
=
skb
;
info
.
nlmsg_seq
=
cb
->
nlh
->
nlmsg_seq
;
info
.
this_idx
=
0
;
info
.
start_idx
=
cb
->
args
[
0
];
(
void
)
xfrm_state_walk
(
IPSEC_PROTO_ANY
,
dump_one_state
,
&
info
);
cb
->
args
[
0
]
=
info
.
this_idx
;
return
skb
->
len
;
}
static
struct
sk_buff
*
xfrm_state_netlink
(
struct
sk_buff
*
in_skb
,
struct
xfrm_state
*
x
,
u32
seq
)
{
struct
xfrm_dump_info
info
;
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
NLMSG_GOODSIZE
,
GFP_ATOMIC
);
if
(
!
skb
)
return
ERR_PTR
(
-
ENOMEM
);
NETLINK_CB
(
skb
).
dst_pid
=
NETLINK_CB
(
in_skb
).
pid
;
info
.
in_skb
=
in_skb
;
info
.
out_skb
=
skb
;
info
.
nlmsg_seq
=
seq
;
info
.
this_idx
=
info
.
start_idx
=
0
;
if
(
dump_one_state
(
x
,
0
,
&
info
))
{
kfree_skb
(
skb
);
return
NULL
;
}
return
skb
;
}
static
int
xfrm_get_sa
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_usersa_id
*
p
=
NLMSG_DATA
(
nlh
);
struct
xfrm_state
*
x
;
struct
sk_buff
*
resp_skb
;
int
err
;
x
=
xfrm_state_lookup
(
p
->
saddr
.
xfrm4_addr
,
p
->
spi
,
p
->
proto
);
err
=
-
ESRCH
;
if
(
x
==
NULL
)
goto
out_noput
;
resp_skb
=
xfrm_state_netlink
(
skb
,
x
,
nlh
->
nlmsg_seq
);
if
(
IS_ERR
(
resp_skb
))
{
err
=
PTR_ERR
(
resp_skb
);
}
else
{
err
=
netlink_unicast
(
xfrm_nl
,
resp_skb
,
NETLINK_CB
(
skb
).
pid
,
MSG_DONTWAIT
);
}
xfrm_state_put
(
x
);
out_noput:
return
err
;
}
static
int
verify_userspi_info
(
struct
xfrm_userspi_info
*
p
)
{
switch
(
p
->
info
.
id
.
proto
)
{
case
IPPROTO_AH
:
case
IPPROTO_ESP
:
break
;
case
IPPROTO_COMP
:
/* IPCOMP spi is 16-bits. */
if
(
p
->
min
>=
0x10000
||
p
->
max
>=
0x10000
)
return
-
EINVAL
;
default:
return
-
EINVAL
;
};
if
(
p
->
min
>
p
->
max
)
return
-
EINVAL
;
return
0
;
}
static
int
xfrm_alloc_userspi
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_state
*
x
;
struct
xfrm_userspi_info
*
p
;
struct
sk_buff
*
resp_skb
;
int
err
;
p
=
NLMSG_DATA
(
nlh
);
err
=
verify_userspi_info
(
p
);
if
(
err
)
goto
out_noput
;
x
=
xfrm_find_acq
(
p
->
info
.
mode
,
p
->
info
.
reqid
,
p
->
info
.
id
.
proto
,
p
->
info
.
sel
.
daddr
.
xfrm4_addr
,
p
->
info
.
sel
.
saddr
.
xfrm4_addr
,
1
);
err
=
-
ENOENT
;
if
(
x
==
NULL
)
goto
out_noput
;
resp_skb
=
ERR_PTR
(
-
ENOENT
);
spin_lock_bh
(
&
x
->
lock
);
if
(
x
->
km
.
state
!=
XFRM_STATE_DEAD
)
{
xfrm_alloc_spi
(
x
,
p
->
min
,
p
->
max
);
if
(
x
->
id
.
spi
)
resp_skb
=
xfrm_state_netlink
(
skb
,
x
,
nlh
->
nlmsg_seq
);
}
spin_unlock_bh
(
&
x
->
lock
);
if
(
IS_ERR
(
resp_skb
))
{
err
=
PTR_ERR
(
resp_skb
);
goto
out
;
}
err
=
netlink_unicast
(
xfrm_nl
,
resp_skb
,
NETLINK_CB
(
skb
).
pid
,
MSG_DONTWAIT
);
out:
xfrm_state_put
(
x
);
out_noput:
return
err
;
}
static
int
verify_policy_dir
(
__u8
dir
)
{
switch
(
dir
)
{
case
XFRM_POLICY_IN
:
case
XFRM_POLICY_OUT
:
case
XFRM_POLICY_FWD
:
break
;
default:
return
-
EINVAL
;
};
return
0
;
}
static
int
verify_newpolicy_info
(
struct
xfrm_userpolicy_info
*
p
)
{
switch
(
p
->
share
)
{
case
XFRM_SHARE_ANY
:
case
XFRM_SHARE_SESSION
:
case
XFRM_SHARE_USER
:
case
XFRM_SHARE_UNIQUE
:
break
;
default:
return
-
EINVAL
;
};
switch
(
p
->
action
)
{
case
XFRM_POLICY_ALLOW
:
case
XFRM_POLICY_BLOCK
:
break
;
default:
return
-
EINVAL
;
};
return
verify_policy_dir
(
p
->
dir
);
}
static
void
copy_templates
(
struct
xfrm_policy
*
xp
,
struct
xfrm_user_tmpl
*
ut
,
int
nr
)
{
int
i
;
xp
->
xfrm_nr
=
nr
;
for
(
i
=
0
;
i
<
nr
;
i
++
,
ut
++
)
{
struct
xfrm_tmpl
*
t
=
&
xp
->
xfrm_vec
[
i
];
memcpy
(
&
t
->
id
,
&
ut
->
id
,
sizeof
(
struct
xfrm_id
));
memcpy
(
&
t
->
saddr
,
&
ut
->
saddr
,
sizeof
(
xfrm_address_t
));
t
->
reqid
=
ut
->
reqid
;
t
->
mode
=
ut
->
mode
;
t
->
share
=
ut
->
share
;
t
->
optional
=
ut
->
optional
;
t
->
aalgos
=
ut
->
aalgos
;
t
->
ealgos
=
ut
->
ealgos
;
t
->
calgos
=
ut
->
calgos
;
}
}
static
int
copy_user_tmpl
(
struct
xfrm_policy
*
pol
,
struct
rtattr
**
xfrma
)
{
struct
rtattr
*
rt
=
xfrma
[
XFRMA_TMPL
];
struct
xfrm_user_tmpl
*
utmpl
;
int
nr
;
if
(
!
rt
)
{
pol
->
xfrm_nr
=
0
;
}
else
{
nr
=
(
rt
->
rta_len
-
sizeof
(
*
rt
))
/
sizeof
(
*
utmpl
);
if
(
nr
>
XFRM_MAX_DEPTH
)
return
-
EINVAL
;
copy_templates
(
pol
,
RTA_DATA
(
rt
),
nr
);
}
return
0
;
}
static
void
copy_from_user_policy
(
struct
xfrm_policy
*
xp
,
struct
xfrm_userpolicy_info
*
p
)
{
xp
->
priority
=
p
->
priority
;
xp
->
index
=
p
->
index
;
memcpy
(
&
xp
->
selector
,
&
p
->
sel
,
sizeof
(
xp
->
selector
));
memcpy
(
&
xp
->
lft
,
&
p
->
lft
,
sizeof
(
xp
->
lft
));
xp
->
action
=
p
->
action
;
xp
->
flags
=
p
->
flags
;
xp
->
family
=
p
->
family
;
/* XXX xp->share = p->share; */
}
static
void
copy_to_user_policy
(
struct
xfrm_policy
*
xp
,
struct
xfrm_userpolicy_info
*
p
,
int
dir
)
{
memcpy
(
&
p
->
sel
,
&
xp
->
selector
,
sizeof
(
p
->
sel
));
memcpy
(
&
p
->
lft
,
&
xp
->
lft
,
sizeof
(
p
->
lft
));
memcpy
(
&
p
->
curlft
,
&
xp
->
curlft
,
sizeof
(
p
->
curlft
));
p
->
priority
=
xp
->
priority
;
p
->
index
=
xp
->
index
;
p
->
family
=
xp
->
family
;
p
->
dir
=
dir
;
p
->
action
=
xp
->
action
;
p
->
flags
=
xp
->
flags
;
p
->
share
=
XFRM_SHARE_ANY
;
/* XXX xp->share */
}
static
struct
xfrm_policy
*
xfrm_policy_construct
(
struct
xfrm_userpolicy_info
*
p
,
struct
rtattr
**
xfrma
,
int
*
errp
)
{
struct
xfrm_policy
*
xp
=
xfrm_policy_alloc
(
GFP_KERNEL
);
int
err
;
if
(
!
xp
)
{
*
errp
=
-
ENOMEM
;
return
NULL
;
}
copy_from_user_policy
(
xp
,
p
);
err
=
copy_user_tmpl
(
xp
,
xfrma
);
if
(
err
)
{
*
errp
=
err
;
kfree
(
xp
);
xp
=
NULL
;
}
return
xp
;
}
static
int
xfrm_add_policy
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_userpolicy_info
*
p
=
NLMSG_DATA
(
nlh
);
struct
xfrm_policy
*
xp
;
int
err
;
err
=
verify_newpolicy_info
(
p
);
if
(
err
)
return
err
;
xp
=
xfrm_policy_construct
(
p
,
(
struct
rtattr
**
)
xfrma
,
&
err
);
if
(
!
xp
)
return
err
;
err
=
xfrm_policy_insert
(
p
->
dir
,
xp
,
1
);
if
(
err
)
{
kfree
(
xp
);
return
err
;
}
xfrm_pol_put
(
xp
);
return
0
;
}
static
int
xfrm_del_policy
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_policy
*
xp
;
struct
xfrm_userpolicy_id
*
p
;
int
err
;
p
=
NLMSG_DATA
(
nlh
);
err
=
verify_policy_dir
(
p
->
dir
);
if
(
err
)
return
err
;
xp
=
xfrm_policy_delete
(
p
->
dir
,
&
p
->
sel
);
if
(
xp
==
NULL
)
return
-
ENOENT
;
xfrm_policy_kill
(
xp
);
xfrm_pol_put
(
xp
);
return
0
;
}
static
int
dump_one_policy
(
struct
xfrm_policy
*
xp
,
int
dir
,
int
count
,
void
*
ptr
)
{
struct
xfrm_dump_info
*
sp
=
ptr
;
struct
xfrm_userpolicy_info
*
p
;
struct
sk_buff
*
in_skb
=
sp
->
in_skb
;
struct
sk_buff
*
skb
=
sp
->
out_skb
;
struct
nlmsghdr
*
nlh
;
unsigned
char
*
b
=
skb
->
tail
;
if
(
sp
->
this_idx
<
sp
->
start_idx
)
goto
out
;
nlh
=
NLMSG_PUT
(
skb
,
NETLINK_CB
(
in_skb
).
pid
,
sp
->
nlmsg_seq
,
XFRM_MSG_NEWPOLICY
,
sizeof
(
*
p
));
p
=
NLMSG_DATA
(
nlh
);
nlh
->
nlmsg_flags
=
0
;
copy_to_user_policy
(
xp
,
p
,
dir
);
if
(
xp
->
xfrm_nr
)
{
struct
xfrm_user_tmpl
vec
[
XFRM_MAX_DEPTH
];
int
i
;
for
(
i
=
0
;
i
<
xp
->
xfrm_nr
;
i
++
)
{
struct
xfrm_user_tmpl
*
up
=
&
vec
[
i
];
struct
xfrm_tmpl
*
kp
=
&
xp
->
xfrm_vec
[
i
];
memcpy
(
&
up
->
id
,
&
kp
->
id
,
sizeof
(
up
->
id
));
memcpy
(
&
up
->
saddr
,
&
kp
->
saddr
,
sizeof
(
up
->
saddr
));
up
->
reqid
=
kp
->
reqid
;
up
->
mode
=
kp
->
mode
;
up
->
share
=
kp
->
share
;
up
->
optional
=
kp
->
optional
;
up
->
aalgos
=
kp
->
aalgos
;
up
->
ealgos
=
kp
->
ealgos
;
up
->
calgos
=
kp
->
calgos
;
}
RTA_PUT
(
skb
,
XFRMA_TMPL
,
(
sizeof
(
struct
xfrm_user_tmpl
)
*
xp
->
xfrm_nr
),
vec
);
}
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
out:
sp
->
this_idx
++
;
return
0
;
nlmsg_failure:
rtattr_failure:
skb_trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
static
int
xfrm_dump_policy
(
struct
sk_buff
*
skb
,
struct
netlink_callback
*
cb
)
{
struct
xfrm_dump_info
info
;
info
.
in_skb
=
cb
->
skb
;
info
.
out_skb
=
skb
;
info
.
nlmsg_seq
=
cb
->
nlh
->
nlmsg_seq
;
info
.
start_idx
=
cb
->
args
[
0
];
(
void
)
xfrm_policy_walk
(
dump_one_policy
,
&
info
);
cb
->
args
[
0
]
=
info
.
this_idx
;
return
skb
->
len
;
}
static
struct
sk_buff
*
xfrm_policy_netlink
(
struct
sk_buff
*
in_skb
,
struct
xfrm_policy
*
xp
,
int
dir
,
u32
seq
)
{
struct
xfrm_dump_info
info
;
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
NLMSG_GOODSIZE
,
GFP_KERNEL
);
if
(
!
skb
)
return
ERR_PTR
(
-
ENOMEM
);
NETLINK_CB
(
skb
).
dst_pid
=
NETLINK_CB
(
in_skb
).
pid
;
info
.
in_skb
=
in_skb
;
info
.
out_skb
=
skb
;
info
.
nlmsg_seq
=
seq
;
info
.
this_idx
=
info
.
start_idx
=
0
;
if
(
dump_one_policy
(
xp
,
dir
,
0
,
&
info
)
<
0
)
{
kfree_skb
(
skb
);
return
NULL
;
}
return
skb
;
}
static
int
xfrm_get_policy
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
**
xfrma
)
{
struct
xfrm_policy
*
xp
;
struct
xfrm_userpolicy_id
*
p
;
struct
sk_buff
*
resp_skb
;
int
err
;
p
=
NLMSG_DATA
(
nlh
);
xp
=
xfrm_policy_byid
(
p
->
dir
,
p
->
index
,
0
);
if
(
xp
==
NULL
)
return
-
ENOENT
;
resp_skb
=
xfrm_policy_netlink
(
skb
,
xp
,
p
->
dir
,
nlh
->
nlmsg_seq
);
if
(
IS_ERR
(
resp_skb
))
{
err
=
PTR_ERR
(
resp_skb
);
}
else
{
err
=
netlink_unicast
(
xfrm_nl
,
resp_skb
,
NETLINK_CB
(
skb
).
pid
,
MSG_DONTWAIT
);
}
xfrm_pol_put
(
xp
);
return
err
;
}
static
const
int
xfrm_msg_min
[(
XFRM_MSG_MAX
+
1
-
XFRM_MSG_BASE
)]
=
{
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_usersa_info
)),
/* NEW SA */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_usersa_id
)),
/* DEL SA */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_usersa_id
)),
/* GET SA */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_userpolicy_info
)),
/* NEW POLICY */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_userpolicy_id
)),
/* DEL POLICY */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_userpolicy_id
)),
/* GET POLICY */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_userspi_info
)),
/* ALLOC SPI */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_user_acquire
)),
/* ACQUIRE */
NLMSG_LENGTH
(
sizeof
(
struct
xfrm_user_expire
)),
/* EXPIRE */
};
static
struct
xfrm_link
{
int
(
*
doit
)(
struct
sk_buff
*
,
struct
nlmsghdr
*
,
void
**
);
int
(
*
dump
)(
struct
sk_buff
*
,
struct
netlink_callback
*
);
}
xfrm_dispatch
[]
=
{
{
.
doit
=
xfrm_add_sa
,
},
{
.
doit
=
xfrm_del_sa
,
},
{
.
doit
=
xfrm_get_sa
,
.
dump
=
xfrm_dump_sa
,
},
{
.
doit
=
xfrm_add_policy
},
{
.
doit
=
xfrm_del_policy
},
{
.
doit
=
xfrm_get_policy
,
.
dump
=
xfrm_dump_policy
,
},
{
.
doit
=
xfrm_alloc_userspi
},
};
static
int
xfrm_done
(
struct
netlink_callback
*
cb
)
{
return
0
;
}
static
int
xfrm_user_rcv_msg
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
int
*
errp
)
{
struct
rtattr
*
xfrma
[
XFRMA_MAX
];
struct
xfrm_link
*
link
;
int
type
,
min_len
,
kind
;
if
(
!
(
nlh
->
nlmsg_flags
&
NLM_F_REQUEST
))
return
0
;
type
=
nlh
->
nlmsg_type
;
/* A control message: ignore them */
if
(
type
<
XFRM_MSG_BASE
)
return
0
;
/* Unknown message: reply with EINVAL */
if
(
type
>
XFRM_MSG_MAX
)
goto
err_einval
;
type
-=
XFRM_MSG_BASE
;
kind
=
(
type
&
3
);
link
=
&
xfrm_dispatch
[
type
];
/* All operations require privileges, even GET */
if
(
!
cap_raised
(
NETLINK_CB
(
skb
).
eff_cap
,
CAP_NET_ADMIN
))
{
*
errp
=
-
EPERM
;
return
-
1
;
}
if
(
kind
==
2
&&
(
nlh
->
nlmsg_flags
&
NLM_F_DUMP
))
{
u32
rlen
;
if
(
link
->
dump
==
NULL
)
goto
err_einval
;
if
((
*
errp
=
netlink_dump_start
(
xfrm_nl
,
skb
,
nlh
,
link
->
dump
,
xfrm_done
))
!=
0
)
{
return
-
1
;
}
rlen
=
NLMSG_ALIGN
(
nlh
->
nlmsg_len
);
if
(
rlen
>
skb
->
len
)
rlen
=
skb
->
len
;
skb_pull
(
skb
,
rlen
);
return
-
1
;
}
memset
(
xfrma
,
0
,
sizeof
(
xfrma
));
if
(
nlh
->
nlmsg_len
<
(
min_len
=
xfrm_msg_min
[
type
]))
goto
err_einval
;
if
(
nlh
->
nlmsg_len
>
min_len
)
{
int
attrlen
=
nlh
->
nlmsg_len
-
NLMSG_ALIGN
(
min_len
);
struct
rtattr
*
attr
=
(
void
*
)
nlh
+
NLMSG_ALIGN
(
min_len
);
while
(
RTA_OK
(
attr
,
attrlen
))
{
unsigned
short
flavor
=
attr
->
rta_type
;
if
(
flavor
)
{
if
(
flavor
>
XFRMA_MAX
)
goto
err_einval
;
xfrma
[
flavor
-
1
]
=
attr
;
}
attr
=
RTA_NEXT
(
attr
,
attrlen
);
}
}
if
(
link
->
doit
==
NULL
)
goto
err_einval
;
*
errp
=
link
->
doit
(
skb
,
nlh
,
(
void
**
)
&
xfrma
);
return
*
errp
;
err_einval:
*
errp
=
-
EINVAL
;
return
-
1
;
}
static
int
xfrm_user_rcv_skb
(
struct
sk_buff
*
skb
)
{
int
err
;
struct
nlmsghdr
*
nlh
;
while
(
skb
->
len
>=
NLMSG_SPACE
(
0
))
{
u32
rlen
;
nlh
=
(
struct
nlmsghdr
*
)
skb
->
data
;
if
(
nlh
->
nlmsg_len
<
sizeof
(
*
nlh
)
||
skb
->
len
<
nlh
->
nlmsg_len
)
return
0
;
rlen
=
NLMSG_ALIGN
(
nlh
->
nlmsg_len
);
if
(
rlen
>
skb
->
len
)
rlen
=
skb
->
len
;
if
(
xfrm_user_rcv_msg
(
skb
,
nlh
,
&
err
))
{
if
(
err
==
0
)
return
-
1
;
netlink_ack
(
skb
,
nlh
,
err
);
}
else
if
(
nlh
->
nlmsg_flags
&
NLM_F_ACK
)
netlink_ack
(
skb
,
nlh
,
0
);
skb_pull
(
skb
,
rlen
);
}
return
0
;
}
static
void
xfrm_netlink_rcv
(
struct
sock
*
sk
,
int
len
)
{
do
{
struct
sk_buff
*
skb
;
down
(
&
xfrm_cfg_sem
);
while
((
skb
=
skb_dequeue
(
&
sk
->
receive_queue
))
!=
NULL
)
{
if
(
xfrm_user_rcv_skb
(
skb
))
{
if
(
skb
->
len
)
skb_queue_head
(
&
sk
->
receive_queue
,
skb
);
else
kfree_skb
(
skb
);
break
;
}
kfree_skb
(
skb
);
}
up
(
&
xfrm_cfg_sem
);
}
while
(
xfrm_nl
&&
xfrm_nl
->
receive_queue
.
qlen
);
}
static
int
build_expire
(
struct
sk_buff
*
skb
,
struct
xfrm_state
*
x
,
int
hard
)
{
struct
xfrm_user_expire
*
ue
;
struct
nlmsghdr
*
nlh
;
unsigned
char
*
b
=
skb
->
tail
;
nlh
=
NLMSG_PUT
(
skb
,
0
,
0
,
XFRM_MSG_EXPIRE
,
sizeof
(
*
ue
));
ue
=
NLMSG_DATA
(
nlh
);
nlh
->
nlmsg_flags
=
0
;
copy_to_user_state
(
x
,
&
ue
->
state
);
ue
->
hard
=
(
hard
!=
0
)
?
1
:
0
;
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
return
skb
->
len
;
nlmsg_failure:
skb_trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
static
int
xfrm_send_notify
(
struct
xfrm_state
*
x
,
int
hard
)
{
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
sizeof
(
struct
xfrm_user_expire
)
+
16
,
GFP_ATOMIC
);
if
(
skb
==
NULL
)
return
-
ENOMEM
;
if
(
build_expire
(
skb
,
x
,
hard
)
<
0
)
BUG
();
NETLINK_CB
(
skb
).
dst_groups
=
XFRMGRP_EXPIRE
;
netlink_broadcast
(
xfrm_nl
,
skb
,
0
,
XFRMGRP_EXPIRE
,
GFP_ATOMIC
);
return
0
;
}
/* XXX Make this xfrm_state.c:xfrm_get_acqseq() */
static
u32
get_acqseq
(
void
)
{
u32
res
;
static
u32
acqseq
;
static
spinlock_t
acqseq_lock
=
SPIN_LOCK_UNLOCKED
;
spin_lock_bh
(
&
acqseq_lock
);
res
=
(
++
acqseq
?
:
++
acqseq
);
spin_unlock_bh
(
&
acqseq_lock
);
return
res
;
}
static
int
build_acquire
(
struct
sk_buff
*
skb
,
struct
xfrm_state
*
x
,
struct
xfrm_tmpl
*
xt
,
struct
xfrm_policy
*
xp
,
int
dir
)
{
struct
xfrm_user_acquire
*
ua
;
struct
nlmsghdr
*
nlh
;
unsigned
char
*
b
=
skb
->
tail
;
__u32
seq
=
get_acqseq
();
nlh
=
NLMSG_PUT
(
skb
,
0
,
0
,
XFRM_MSG_ACQUIRE
,
sizeof
(
*
ua
));
ua
=
NLMSG_DATA
(
nlh
);
nlh
->
nlmsg_flags
=
0
;
memcpy
(
&
ua
->
id
,
&
x
->
id
,
sizeof
(
ua
->
id
));
memcpy
(
&
ua
->
saddr
,
&
x
->
props
.
saddr
,
sizeof
(
ua
->
saddr
));
copy_to_user_policy
(
xp
,
&
ua
->
policy
,
dir
);
ua
->
aalgos
=
xt
->
aalgos
;
ua
->
ealgos
=
xt
->
ealgos
;
ua
->
calgos
=
xt
->
calgos
;
ua
->
seq
=
x
->
km
.
seq
=
seq
;
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
return
skb
->
len
;
nlmsg_failure:
skb_trim
(
skb
,
b
-
skb
->
data
);
return
-
1
;
}
static
int
xfrm_send_acquire
(
struct
xfrm_state
*
x
,
struct
xfrm_tmpl
*
xt
,
struct
xfrm_policy
*
xp
,
int
dir
)
{
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
sizeof
(
struct
xfrm_user_acquire
)
+
16
,
GFP_ATOMIC
);
if
(
skb
==
NULL
)
return
-
ENOMEM
;
if
(
build_acquire
(
skb
,
x
,
xt
,
xp
,
dir
)
<
0
)
BUG
();
NETLINK_CB
(
skb
).
dst_groups
=
XFRMGRP_ACQUIRE
;
netlink_broadcast
(
xfrm_nl
,
skb
,
0
,
XFRMGRP_ACQUIRE
,
GFP_ATOMIC
);
return
0
;
}
/* User gives us xfrm_user_policy_info followed by an array of 0
* or more templates.
*/
struct
xfrm_policy
*
xfrm_compile_policy
(
int
opt
,
u8
*
data
,
int
len
,
int
*
dir
)
{
struct
xfrm_userpolicy_info
*
p
=
(
struct
xfrm_userpolicy_info
*
)
data
;
struct
xfrm_user_tmpl
*
ut
=
(
struct
xfrm_user_tmpl
*
)
(
p
+
1
);
struct
xfrm_policy
*
xp
;
int
nr
;
if
(
opt
!=
IP_XFRM_POLICY
)
{
*
dir
=
-
EOPNOTSUPP
;
return
NULL
;
}
*
dir
=
-
EINVAL
;
if
(
len
<
sizeof
(
*
p
)
||
verify_newpolicy_info
(
p
))
return
NULL
;
nr
=
((
len
-
sizeof
(
*
p
))
/
sizeof
(
*
ut
));
if
(
nr
>
XFRM_MAX_DEPTH
)
return
NULL
;
xp
=
xfrm_policy_alloc
(
GFP_KERNEL
);
if
(
xp
==
NULL
)
{
*
dir
=
-
ENOBUFS
;
return
NULL
;
}
copy_from_user_policy
(
xp
,
p
);
copy_templates
(
xp
,
ut
,
nr
);
*
dir
=
p
->
dir
;
return
xp
;
}
static
struct
xfrm_mgr
netlink_mgr
=
{
.
id
=
"netlink"
,
.
notify
=
xfrm_send_notify
,
.
acquire
=
xfrm_send_acquire
,
.
compile_policy
=
xfrm_compile_policy
,
};
static
int
__init
xfrm_user_init
(
void
)
{
printk
(
KERN_INFO
"Initializing IPsec netlink socket
\n
"
);
xfrm_nl
=
netlink_kernel_create
(
NETLINK_XFRM
,
xfrm_netlink_rcv
);
if
(
xfrm_nl
==
NULL
)
panic
(
"xfrm_user_init: cannot initialize xfrm_nl
\n
"
);
xfrm_register_km
(
&
netlink_mgr
);
return
0
;
}
static
void
__exit
xfrm_user_exit
(
void
)
{
xfrm_unregister_km
(
&
netlink_mgr
);
sock_release
(
xfrm_nl
->
socket
);
}
module_init
(
xfrm_user_init
);
module_exit
(
xfrm_user_exit
);
net/ipv6/mcast.c
View file @
6ccc3e25
...
...
@@ -296,6 +296,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
}
memset
(
mc
,
0
,
sizeof
(
struct
ifmcaddr6
));
init_timer
(
&
mc
->
mca_timer
);
mc
->
mca_timer
.
function
=
igmp6_timer_handler
;
mc
->
mca_timer
.
data
=
(
unsigned
long
)
mc
;
...
...
net/irda/af_irda.c
View file @
6ccc3e25
...
...
@@ -2364,6 +2364,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
/* Set watchdog timer to expire in <val> ms. */
self
->
errno
=
0
;
init_timer
(
&
self
->
watchdog
);
self
->
watchdog
.
function
=
irda_discovery_timeout
;
self
->
watchdog
.
data
=
(
unsigned
long
)
self
;
self
->
watchdog
.
expires
=
jiffies
+
(
val
*
HZ
/
1000
);
...
...
net/key/af_key.c
View file @
6ccc3e25
...
...
@@ -528,8 +528,7 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
switch
(((
struct
sockaddr
*
)(
addr
+
1
))
->
sa_family
)
{
case
AF_INET
:
x
=
xfrm_state_lookup
(
((
struct
sockaddr_in
*
)(
addr
+
1
))
->
sin_addr
.
s_addr
,
x
=
xfrm_state_lookup
(((
struct
sockaddr_in
*
)(
addr
+
1
))
->
sin_addr
.
s_addr
,
sa
->
sadb_sa_spi
,
proto
);
break
;
case
AF_INET6
:
...
...
@@ -1043,7 +1042,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
daddr
=
(
struct
sockaddr_in
*
)(
addr
+
1
);
x
=
xfrm_find_acq
(
mode
,
reqid
,
proto
,
daddr
->
sin_addr
.
s_addr
,
saddr
->
sin_addr
.
s_addr
);
saddr
->
sin_addr
.
s_addr
,
1
);
if
(
x
==
NULL
)
return
-
ENOENT
;
...
...
@@ -1122,7 +1121,17 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
/* XXX there is race condition */
x1
=
pfkey_xfrm_state_lookup
(
hdr
,
ext_hdrs
);
if
(
x1
&&
hdr
->
sadb_msg_type
==
SADB_ADD
)
{
if
(
!
x1
)
{
x1
=
xfrm_find_acq
(
x
->
props
.
mode
,
x
->
props
.
reqid
,
x
->
id
.
proto
,
x
->
id
.
daddr
.
xfrm4_addr
,
x
->
props
.
saddr
.
xfrm4_addr
,
0
);
if
(
x1
&&
x1
->
id
.
spi
!=
x
->
id
.
spi
&&
x1
->
id
.
spi
)
{
xfrm_state_put
(
x1
);
x1
=
NULL
;
}
}
if
(
x1
&&
x1
->
id
.
spi
&&
hdr
->
sadb_msg_type
==
SADB_ADD
)
{
x
->
km
.
state
=
XFRM_STATE_DEAD
;
xfrm_state_put
(
x
);
xfrm_state_put
(
x1
);
...
...
@@ -1131,7 +1140,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
xfrm_state_insert
(
x
);
if
(
x1
&&
hdr
->
sadb_msg_type
!=
SADB_ADD
)
{
if
(
x1
)
{
xfrm_state_delete
(
x1
);
xfrm_state_put
(
x1
);
}
...
...
@@ -1225,7 +1234,7 @@ static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, int allocat
esp_len
+=
sizeof
(
struct
sadb_supported
);
len
=
esp_len
+
ah_len
+
sizeof
(
struct
sadb_msg
);
skb
=
alloc_skb
(
allocation
,
len
+
16
);
skb
=
alloc_skb
(
len
+
16
,
allocation
);
if
(
!
skb
)
goto
out_put_algs
;
...
...
@@ -2156,7 +2165,7 @@ static struct xfrm_policy *pfkey_compile_policy(int opt, u8 *data, int len, int
(
!
pol
->
sadb_x_policy_dir
||
pol
->
sadb_x_policy_dir
>
IPSEC_DIR_OUTBOUND
))
return
NULL
;
xp
=
xfrm_policy_alloc
(
GFP_
KERNEL
);
xp
=
xfrm_policy_alloc
(
GFP_
ATOMIC
);
if
(
xp
==
NULL
)
{
*
dir
=
-
ENOBUFS
;
return
NULL
;
...
...
net/llc/llc_main.c
View file @
6ccc3e25
...
...
@@ -181,18 +181,22 @@ int llc_sk_init(struct sock* sk)
llc
->
inc_cntr
=
llc
->
dec_cntr
=
2
;
llc
->
dec_step
=
llc
->
connect_step
=
1
;
init_timer
(
&
llc
->
ack_timer
);
llc
->
ack_timer
.
expire
=
LLC_ACK_TIME
;
llc
->
ack_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
ack_timer
.
timer
.
function
=
llc_conn_ack_tmr_cb
;
init_timer
(
&
llc
->
pf_cycle_timer
);
llc
->
pf_cycle_timer
.
expire
=
LLC_P_TIME
;
llc
->
pf_cycle_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
pf_cycle_timer
.
timer
.
function
=
llc_conn_pf_cycle_tmr_cb
;
init_timer
(
&
llc
->
rej_sent_timer
);
llc
->
rej_sent_timer
.
expire
=
LLC_REJ_TIME
;
llc
->
rej_sent_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
rej_sent_timer
.
timer
.
function
=
llc_conn_rej_tmr_cb
;
init_timer
(
&
llc
->
busy_state_timer
);
llc
->
busy_state_timer
.
expire
=
LLC_BUSY_TIME
;
llc
->
busy_state_timer
.
timer
.
data
=
(
unsigned
long
)
sk
;
llc
->
busy_state_timer
.
timer
.
function
=
llc_conn_busy_tmr_cb
;
...
...
@@ -552,6 +556,7 @@ static int __init llc_init(void)
skb_queue_head_init
(
&
llc_main_station
.
mac_pdu_q
);
skb_queue_head_init
(
&
llc_main_station
.
ev_q
.
list
);
spin_lock_init
(
&
llc_main_station
.
ev_q
.
lock
);
init_timer
(
&
llc_main_station
.
ack_timer
);
llc_main_station
.
ack_timer
.
data
=
(
unsigned
long
)
&
llc_main_station
;
llc_main_station
.
ack_timer
.
function
=
llc_station_ack_tmr_cb
;
...
...
net/sched/sch_sfq.c
View file @
6ccc3e25
...
...
@@ -411,9 +411,9 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
struct
sfq_sched_data
*
q
=
(
struct
sfq_sched_data
*
)
sch
->
data
;
int
i
;
init_timer
(
&
q
->
perturb_timer
);
q
->
perturb_timer
.
data
=
(
unsigned
long
)
sch
;
q
->
perturb_timer
.
function
=
sfq_perturbation
;
init_timer
(
&
q
->
perturb_timer
);
for
(
i
=
0
;
i
<
SFQ_HASH_DIVISOR
;
i
++
)
q
->
ht
[
i
]
=
SFQ_DEPTH
;
...
...
net/socket.c
View file @
6ccc3e25
...
...
@@ -66,6 +66,7 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/wanrouter.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
...
...
@@ -1839,29 +1840,19 @@ void __init sock_init(void)
#endif
}
int
socket_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
#ifdef CONFIG_PROC_FS
void
socket_seq_show
(
struct
seq_file
*
seq
)
{
int
len
,
cpu
;
int
cpu
;
int
counter
=
0
;
for
(
cpu
=
0
;
cpu
<
NR_CPUS
;
cpu
++
)
for
(
cpu
=
0
;
cpu
<
NR_CPUS
;
cpu
++
)
counter
+=
sockets_in_use
[
cpu
].
counter
;
/* It can be negative, by the way. 8) */
if
(
counter
<
0
)
counter
=
0
;
len
=
sprintf
(
buffer
,
"sockets: used %d
\n
"
,
counter
);
if
(
offset
>=
len
)
{
*
start
=
buffer
;
return
0
;
}
*
start
=
buffer
+
offset
;
len
-=
offset
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
seq_printf
(
seq
,
"sockets: used %d
\n
"
,
counter
);
}
#endif
/* CONFIG_PROC_FS */
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