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
nexedi
linux
Commits
27df0cf8
Commit
27df0cf8
authored
Sep 28, 2004
by
Richard Russon
Browse files
Options
Browse Files
Download
Plain Diff
Merge flatcap.org:/home/flatcap/backup/bk/linux-2.6
into flatcap.org:/home/flatcap/backup/bk/ntfs-2.6
parents
ee05a6ce
aea2fb73
Changes
28
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
947 additions
and
760 deletions
+947
-760
include/linux/skbuff.h
include/linux/skbuff.h
+1
-1
include/linux/tcp.h
include/linux/tcp.h
+8
-2
include/linux/time.h
include/linux/time.h
+12
-0
include/net/addrconf.h
include/net/addrconf.h
+3
-1
include/net/dn_neigh.h
include/net/dn_neigh.h
+0
-1
include/net/neighbour.h
include/net/neighbour.h
+26
-5
include/net/tcp.h
include/net/tcp.h
+15
-13
kernel/sys.c
kernel/sys.c
+1
-1
net/atm/clip.c
net/atm/clip.c
+121
-140
net/core/neighbour.c
net/core/neighbour.c
+422
-51
net/decnet/dn_neigh.c
net/decnet/dn_neigh.c
+53
-147
net/decnet/dn_route.c
net/decnet/dn_route.c
+1
-1
net/ipv4/arp.c
net/ipv4/arp.c
+23
-172
net/ipv4/fib_hash.c
net/ipv4/fib_hash.c
+11
-13
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+18
-16
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+65
-59
net/ipv4/netfilter/ip_conntrack_proto_udp.c
net/ipv4/netfilter/ip_conntrack_proto_udp.c
+5
-4
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_conntrack_standalone.c
+0
-1
net/ipv4/netfilter/ipt_helper.c
net/ipv4/netfilter/ipt_helper.c
+1
-0
net/ipv4/netfilter/ipt_sctp.c
net/ipv4/netfilter/ipt_sctp.c
+18
-16
net/ipv4/tcp_diag.c
net/ipv4/tcp_diag.c
+21
-13
net/ipv4/tcp_input.c
net/ipv4/tcp_input.c
+31
-31
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_minisocks.c
+2
-1
net/ipv4/tcp_output.c
net/ipv4/tcp_output.c
+2
-2
net/ipv6/addrconf.c
net/ipv6/addrconf.c
+55
-47
net/ipv6/anycast.c
net/ipv6/anycast.c
+13
-10
net/ipv6/mcast.c
net/ipv6/mcast.c
+12
-5
net/ipv6/ndisc.c
net/ipv6/ndisc.c
+7
-7
No files found.
include/linux/skbuff.h
View file @
27df0cf8
...
...
@@ -250,8 +250,8 @@ struct sk_buff {
#ifdef CONFIG_NETFILTER
unsigned
long
nfmark
;
__u32
nfcache
;
struct
nf_conntrack
*
nfct
;
__u32
nfctinfo
;
struct
nf_conntrack
*
nfct
;
#ifdef CONFIG_NETFILTER_DEBUG
unsigned
int
nf_debug
;
#endif
...
...
include/linux/tcp.h
View file @
27df0cf8
...
...
@@ -205,6 +205,13 @@ typedef struct tcp_pcount {
__u32
val
;
}
tcp_pcount_t
;
enum
tcp_congestion_algo
{
TCP_RENO
=
0
,
TCP_VEGAS
,
TCP_WESTWOOD
,
TCP_BIC
,
};
struct
tcp_opt
{
int
tcp_header_len
;
/* Bytes of tcp header to send */
...
...
@@ -265,7 +272,7 @@ struct tcp_opt {
__u8
frto_counter
;
/* Number of new acks after RTO */
__u32
frto_highmark
;
/* snd_nxt when RTO occurred */
__u8
unused_pad
;
__u8
adv_cong
;
/* Using Vegas, Westwood, or BIC */
__u8
defer_accept
;
/* User waits for some data after accept() */
/* one byte hole, try to pack */
...
...
@@ -412,7 +419,6 @@ struct tcp_opt {
__u32
beg_snd_nxt
;
/* right edge during last RTT */
__u32
beg_snd_una
;
/* left edge during last RTT */
__u32
beg_snd_cwnd
;
/* saves the size of the cwnd */
__u8
do_vegas
;
/* do vegas for this connection */
__u8
doing_vegas_now
;
/* if true, do vegas for this RTT */
__u16
cntRTT
;
/* # of RTTs measured within last RTT */
__u32
minRTT
;
/* min of RTTs measured within last RTT (in usec) */
...
...
include/linux/time.h
View file @
27df0cf8
...
...
@@ -194,6 +194,18 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j)
return
(
j
*
1000
)
/
HZ
;
#endif
}
static
inline
unsigned
int
jiffies_to_usecs
(
const
unsigned
long
j
)
{
#if HZ <= 1000 && !(1000 % HZ)
return
(
1000000
/
HZ
)
*
j
;
#elif HZ > 1000 && !(HZ % 1000)
return
(
j
*
1000
+
(
HZ
-
1000
))
/
(
HZ
/
1000
);
#else
return
(
j
*
1000000
)
/
HZ
;
#endif
}
static
inline
unsigned
long
msecs_to_jiffies
(
const
unsigned
int
m
)
{
#if HZ <= 1000 && !(1000 % HZ)
...
...
include/net/addrconf.h
View file @
27df0cf8
...
...
@@ -74,7 +74,7 @@ extern int ipv6_rcv_saddr_equal(const struct sock *sk,
const
struct
sock
*
sk2
);
extern
void
addrconf_join_solict
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
void
addrconf_leave_solict
(
struct
net_device
*
dev
,
extern
void
addrconf_leave_solict
(
struct
inet6_dev
*
i
dev
,
struct
in6_addr
*
addr
);
/*
...
...
@@ -89,6 +89,7 @@ extern int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr,
struct
in6_addr
*
src_addr
);
extern
int
ipv6_dev_mc_inc
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
__ipv6_dev_mc_dec
(
struct
inet6_dev
*
idev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_mc_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
void
ipv6_mc_up
(
struct
inet6_dev
*
idev
);
extern
void
ipv6_mc_down
(
struct
inet6_dev
*
idev
);
...
...
@@ -111,6 +112,7 @@ extern void ipv6_sock_ac_close(struct sock *sk);
extern
int
inet6_ac_check
(
struct
sock
*
sk
,
struct
in6_addr
*
addr
,
int
ifindex
);
extern
int
ipv6_dev_ac_inc
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
__ipv6_dev_ac_dec
(
struct
inet6_dev
*
idev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_dev_ac_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
extern
int
ipv6_chk_acast_addr
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
);
...
...
include/net/dn_neigh.h
View file @
27df0cf8
...
...
@@ -18,7 +18,6 @@ struct dn_neigh {
extern
void
dn_neigh_init
(
void
);
extern
void
dn_neigh_cleanup
(
void
);
extern
struct
neighbour
*
dn_neigh_lookup
(
struct
neigh_table
*
tbl
,
const
void
*
ptr
);
extern
int
dn_neigh_router_hello
(
struct
sk_buff
*
skb
);
extern
int
dn_neigh_endnode_hello
(
struct
sk_buff
*
skb
);
extern
void
dn_neigh_pointopoint_hello
(
struct
sk_buff
*
skb
);
...
...
include/net/neighbour.h
View file @
27df0cf8
...
...
@@ -47,6 +47,7 @@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/sysctl.h>
...
...
@@ -139,9 +140,6 @@ struct pneigh_entry
u8
key
[
0
];
};
#define NEIGH_HASHMASK 0x1F
#define PNEIGH_HASHMASK 0xF
/*
* neighbour table manipulation
*/
...
...
@@ -175,8 +173,11 @@ struct neigh_table
struct
neigh_parms
*
parms_list
;
kmem_cache_t
*
kmem_cachep
;
struct
neigh_statistics
stats
;
struct
neighbour
*
hash_buckets
[
NEIGH_HASHMASK
+
1
];
struct
pneigh_entry
*
phash_buckets
[
PNEIGH_HASHMASK
+
1
];
struct
neighbour
**
hash_buckets
;
unsigned
int
hash_mask
;
__u32
hash_rnd
;
unsigned
int
hash_chain_gc
;
struct
pneigh_entry
**
phash_buckets
;
};
/* flags for neigh_update() */
...
...
@@ -191,6 +192,8 @@ extern int neigh_table_clear(struct neigh_table *tbl);
extern
struct
neighbour
*
neigh_lookup
(
struct
neigh_table
*
tbl
,
const
void
*
pkey
,
struct
net_device
*
dev
);
extern
struct
neighbour
*
neigh_lookup_nodev
(
struct
neigh_table
*
tbl
,
const
void
*
pkey
);
extern
struct
neighbour
*
neigh_create
(
struct
neigh_table
*
tbl
,
const
void
*
pkey
,
struct
net_device
*
dev
);
...
...
@@ -224,6 +227,24 @@ extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
extern
int
neigh_delete
(
struct
sk_buff
*
skb
,
struct
nlmsghdr
*
nlh
,
void
*
arg
);
extern
void
neigh_app_ns
(
struct
neighbour
*
n
);
extern
void
neigh_for_each
(
struct
neigh_table
*
tbl
,
void
(
*
cb
)(
struct
neighbour
*
,
void
*
),
void
*
cookie
);
extern
void
__neigh_for_each_release
(
struct
neigh_table
*
tbl
,
int
(
*
cb
)(
struct
neighbour
*
));
extern
void
pneigh_for_each
(
struct
neigh_table
*
tbl
,
void
(
*
cb
)(
struct
pneigh_entry
*
));
struct
neigh_seq_state
{
struct
neigh_table
*
tbl
;
void
*
(
*
neigh_sub_iter
)(
struct
neigh_seq_state
*
state
,
struct
neighbour
*
n
,
loff_t
*
pos
);
unsigned
int
bucket
;
unsigned
int
flags
;
#define NEIGH_SEQ_NEIGH_ONLY 0x00000001
#define NEIGH_SEQ_IS_PNEIGH 0x00000002
#define NEIGH_SEQ_SKIP_NOARP 0x00000004
};
extern
void
*
neigh_seq_start
(
struct
seq_file
*
,
loff_t
*
,
struct
neigh_table
*
,
unsigned
int
);
extern
void
*
neigh_seq_next
(
struct
seq_file
*
,
void
*
,
loff_t
*
);
extern
void
neigh_seq_stop
(
struct
seq_file
*
,
void
*
);
extern
int
neigh_sysctl_register
(
struct
net_device
*
dev
,
struct
neigh_parms
*
p
,
int
p_id
,
int
pdev_id
,
...
...
include/net/tcp.h
View file @
27df0cf8
...
...
@@ -1271,6 +1271,13 @@ static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp)
tcp_get_pcount
(
&
tp
->
retrans_out
));
}
/*
* Which congestion algorithim is in use on the connection.
*/
#define tcp_is_vegas(__tp) ((__tp)->adv_cong == TCP_VEGAS)
#define tcp_is_westwood(__tp) ((__tp)->adv_cong == TCP_WESTWOOD)
#define tcp_is_bic(__tp) ((__tp)->adv_cong == TCP_BIC)
/* Recalculate snd_ssthresh, we want to set it to:
*
* Reno:
...
...
@@ -1283,7 +1290,7 @@ static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp)
*/
static
inline
__u32
tcp_recalc_ssthresh
(
struct
tcp_opt
*
tp
)
{
if
(
sysctl_tcp_bic
)
{
if
(
tcp_is_bic
(
tp
)
)
{
if
(
sysctl_tcp_bic_fast_convergence
&&
tp
->
snd_cwnd
<
tp
->
bictcp
.
last_max_cwnd
)
tp
->
bictcp
.
last_max_cwnd
...
...
@@ -1303,11 +1310,6 @@ static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
/* Stop taking Vegas samples for now. */
#define tcp_vegas_disable(__tp) ((__tp)->vegas.doing_vegas_now = 0)
/* Is this TCP connection using Vegas (regardless of whether it is taking
* Vegas measurements at the current time)?
*/
#define tcp_is_vegas(__tp) ((__tp)->vegas.do_vegas)
static
inline
void
tcp_vegas_enable
(
struct
tcp_opt
*
tp
)
{
/* There are several situations when we must "re-start" Vegas:
...
...
@@ -1340,7 +1342,7 @@ static inline void tcp_vegas_enable(struct tcp_opt *tp)
/* Should we be taking Vegas samples right now? */
#define tcp_vegas_enabled(__tp) ((__tp)->vegas.doing_vegas_now)
extern
void
tcp_
vegas
_init
(
struct
tcp_opt
*
tp
);
extern
void
tcp_
ca
_init
(
struct
tcp_opt
*
tp
);
static
inline
void
tcp_set_ca_state
(
struct
tcp_opt
*
tp
,
u8
ca_state
)
{
...
...
@@ -2024,7 +2026,7 @@ extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
static
inline
void
tcp_westwood_update_rtt
(
struct
tcp_opt
*
tp
,
__u32
rtt_seq
)
{
if
(
sysctl_tcp_westwood
)
if
(
tcp_is_westwood
(
tp
)
)
tp
->
westwood
.
rtt
=
rtt_seq
;
}
...
...
@@ -2033,13 +2035,13 @@ void __tcp_westwood_slow_bw(struct sock *, struct sk_buff *);
static
inline
void
tcp_westwood_fast_bw
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
if
(
sysctl_tcp_westwood
)
if
(
tcp_is_westwood
(
tcp_sk
(
sk
))
)
__tcp_westwood_fast_bw
(
sk
,
skb
);
}
static
inline
void
tcp_westwood_slow_bw
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
if
(
sysctl_tcp_westwood
)
if
(
tcp_is_westwood
(
tcp_sk
(
sk
))
)
__tcp_westwood_slow_bw
(
sk
,
skb
);
}
...
...
@@ -2052,14 +2054,14 @@ static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_opt *tp)
static
inline
__u32
tcp_westwood_bw_rttmin
(
const
struct
tcp_opt
*
tp
)
{
return
sysctl_tcp_westwood
?
__tcp_westwood_bw_rttmin
(
tp
)
:
0
;
return
tcp_is_westwood
(
tp
)
?
__tcp_westwood_bw_rttmin
(
tp
)
:
0
;
}
static
inline
int
tcp_westwood_ssthresh
(
struct
tcp_opt
*
tp
)
{
__u32
ssthresh
=
0
;
if
(
sysctl_tcp_westwood
)
{
if
(
tcp_is_westwood
(
tp
)
)
{
ssthresh
=
__tcp_westwood_bw_rttmin
(
tp
);
if
(
ssthresh
)
tp
->
snd_ssthresh
=
ssthresh
;
...
...
@@ -2072,7 +2074,7 @@ static inline int tcp_westwood_cwnd(struct tcp_opt *tp)
{
__u32
cwnd
=
0
;
if
(
sysctl_tcp_westwood
)
{
if
(
tcp_is_westwood
(
tp
)
)
{
cwnd
=
__tcp_westwood_bw_rttmin
(
tp
);
if
(
cwnd
)
tp
->
snd_cwnd
=
cwnd
;
...
...
kernel/sys.c
View file @
27df0cf8
...
...
@@ -1734,7 +1734,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned
char
ncomm
[
sizeof
(
me
->
comm
)];
ncomm
[
sizeof
(
me
->
comm
)
-
1
]
=
0
;
if
(
strncpy_from_user
(
ncomm
,
(
char
*
)
arg2
,
if
(
strncpy_from_user
(
ncomm
,
(
char
__user
*
)
arg2
,
sizeof
(
me
->
comm
)
-
1
)
<
0
)
return
-
EFAULT
;
set_task_comm
(
me
,
ncomm
);
...
...
net/atm/clip.c
View file @
27df0cf8
...
...
@@ -27,6 +27,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/rcupdate.h>
#include <linux/jhash.h>
#include <net/route.h>
/* for struct rtable and routing */
#include <net/icmp.h>
/* icmp_send */
#include <asm/param.h>
/* for HZ */
...
...
@@ -123,64 +124,49 @@ static void unlink_clip_vcc(struct clip_vcc *clip_vcc)
spin_unlock_bh
(
&
entry
->
neigh
->
dev
->
xmit_lock
);
}
static
void
idle_timer_check
(
unsigned
long
dummy
)
/* The neighbour entry n->lock is held. */
static
int
neigh_check_cb
(
struct
neighbour
*
n
)
{
int
i
;
/*DPRINTK("idle_timer_check\n");*/
write_lock
(
&
clip_tbl
.
lock
);
for
(
i
=
0
;
i
<=
NEIGH_HASHMASK
;
i
++
)
{
struct
neighbour
**
np
;
for
(
np
=
&
clip_tbl
.
hash_buckets
[
i
];
*
np
;)
{
struct
neighbour
*
n
=
*
np
;
struct
atmarp_entry
*
entry
=
NEIGH2ENTRY
(
n
);
struct
clip_vcc
*
clip_vcc
;
struct
clip_vcc
*
cv
;
for
(
cv
=
entry
->
vccs
;
cv
;
cv
=
cv
->
next
)
{
unsigned
long
exp
=
cv
->
last_use
+
cv
->
idle_timeout
;
write_lock
(
&
n
->
lock
);
for
(
clip_vcc
=
entry
->
vccs
;
clip_vcc
;
clip_vcc
=
clip_vcc
->
next
)
if
(
clip_vcc
->
idle_timeout
&&
time_after
(
jiffies
,
clip_vcc
->
last_use
+
clip_vcc
->
idle_timeout
))
{
DPRINTK
(
"releasing vcc %p->%p of "
"entry %p
\n
"
,
clip_vcc
,
clip_vcc
->
vcc
,
entry
);
vcc_release_async
(
clip_vcc
->
vcc
,
-
ETIMEDOUT
);
if
(
cv
->
idle_timeout
&&
time_after
(
jiffies
,
exp
))
{
DPRINTK
(
"releasing vcc %p->%p of entry %p
\n
"
,
cv
,
cv
->
vcc
,
entry
);
vcc_release_async
(
cv
->
vcc
,
-
ETIMEDOUT
);
}
if
(
entry
->
vccs
||
time_before
(
jiffies
,
entry
->
expires
))
{
np
=
&
n
->
next
;
write_unlock
(
&
n
->
lock
);
continue
;
}
if
(
entry
->
vccs
||
time_before
(
jiffies
,
entry
->
expires
))
return
0
;
if
(
atomic_read
(
&
n
->
refcnt
)
>
1
)
{
struct
sk_buff
*
skb
;
DPRINTK
(
"destruction postponed with ref %d
\n
"
,
atomic_read
(
&
n
->
refcnt
));
while
((
skb
=
skb_dequeue
(
&
n
->
arp_queue
))
!=
NULL
)
while
((
skb
=
skb_dequeue
(
&
n
->
arp_queue
))
!=
NULL
)
dev_kfree_skb
(
skb
);
np
=
&
n
->
next
;
write_unlock
(
&
n
->
lock
);
continue
;
return
0
;
}
*
np
=
n
->
next
;
DPRINTK
(
"expired neigh %p
\n
"
,
n
);
n
->
dead
=
1
;
write_unlock
(
&
n
->
lock
);
neigh_release
(
n
);
}
}
return
1
;
}
static
void
idle_timer_check
(
unsigned
long
dummy
)
{
write_lock
(
&
clip_tbl
.
lock
);
__neigh_for_each_release
(
&
clip_tbl
,
neigh_check_cb
);
mod_timer
(
&
idle_timer
,
jiffies
+
CLIP_CHECK_INTERVAL
*
HZ
);
write_unlock
(
&
clip_tbl
.
lock
);
}
static
int
clip_arp_rcv
(
struct
sk_buff
*
skb
)
{
struct
atm_vcc
*
vcc
;
...
...
@@ -343,15 +329,7 @@ static int clip_constructor(struct neighbour *neigh)
static
u32
clip_hash
(
const
void
*
pkey
,
const
struct
net_device
*
dev
)
{
u32
hash_val
;
hash_val
=
*
(
u32
*
)
pkey
;
hash_val
^=
(
hash_val
>>
16
);
hash_val
^=
hash_val
>>
8
;
hash_val
^=
hash_val
>>
3
;
hash_val
=
(
hash_val
^
dev
->
ifindex
)
&
NEIGH_HASHMASK
;
return
hash_val
;
return
jhash_2words
(
*
(
u32
*
)
pkey
,
dev
->
ifindex
,
clip_tbl
.
hash_rnd
);
}
static
struct
neigh_table
clip_tbl
=
{
...
...
@@ -833,120 +811,126 @@ static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
}
}
/* This means the neighbour entry has no attached VCC objects. */
#define SEQ_NO_VCC_TOKEN ((void *) 2)
static
void
atmarp_info
(
struct
seq_file
*
seq
,
struct
net_device
*
dev
,
struct
atmarp_entry
*
entry
,
struct
clip_vcc
*
clip_vcc
)
{
unsigned
long
exp
;
char
buf
[
17
];
int
svc
,
off
;
int
svc
,
llc
,
off
;
svc
=
((
clip_vcc
==
SEQ_NO_VCC_TOKEN
)
||
(
clip_vcc
->
vcc
->
sk
->
sk_family
==
AF_ATMSVC
));
svc
=
!
clip_vcc
||
clip_vcc
->
vcc
->
sk
->
sk_family
==
AF_ATMSVC
;
seq_printf
(
seq
,
"%-6s%-4s%-4s%5ld "
,
dev
->
name
,
svc
?
"SVC"
:
"PVC"
,
!
clip_vcc
||
clip_vcc
->
encap
?
"LLC"
:
"NULL"
,
(
jiffies
-
(
clip_vcc
?
clip_vcc
->
last_use
:
entry
->
neigh
->
used
))
/
HZ
);
llc
=
((
clip_vcc
==
SEQ_NO_VCC_TOKEN
)
||
clip_vcc
->
encap
);
off
=
scnprintf
(
buf
,
sizeof
(
buf
)
-
1
,
"%d.%d.%d.%d"
,
NIPQUAD
(
entry
->
ip
));
if
(
clip_vcc
==
SEQ_NO_VCC_TOKEN
)
exp
=
entry
->
neigh
->
used
;
else
exp
=
clip_vcc
->
last_use
;
exp
=
(
jiffies
-
exp
)
/
HZ
;
seq_printf
(
seq
,
"%-6s%-4s%-4s%5ld "
,
dev
->
name
,
svc
?
"SVC"
:
"PVC"
,
llc
?
"LLC"
:
"NULL"
,
exp
);
off
=
scnprintf
(
buf
,
sizeof
(
buf
)
-
1
,
"%d.%d.%d.%d"
,
NIPQUAD
(
entry
->
ip
));
while
(
off
<
16
)
buf
[
off
++
]
=
' '
;
buf
[
off
]
=
'\0'
;
seq_printf
(
seq
,
"%s"
,
buf
);
if
(
!
clip_vcc
)
{
if
(
clip_vcc
==
SEQ_NO_VCC_TOKEN
)
{
if
(
time_before
(
jiffies
,
entry
->
expires
))
seq_printf
(
seq
,
"(resolving)
\n
"
);
else
seq_printf
(
seq
,
"(expired, ref %d)
\n
"
,
atomic_read
(
&
entry
->
neigh
->
refcnt
));
}
else
if
(
!
svc
)
{
seq_printf
(
seq
,
"%d.%d.%d
\n
"
,
clip_vcc
->
vcc
->
dev
->
number
,
clip_vcc
->
vcc
->
vpi
,
clip_vcc
->
vcc
->
vci
);
seq_printf
(
seq
,
"%d.%d.%d
\n
"
,
clip_vcc
->
vcc
->
dev
->
number
,
clip_vcc
->
vcc
->
vpi
,
clip_vcc
->
vcc
->
vci
);
}
else
{
svc_addr
(
seq
,
&
clip_vcc
->
vcc
->
remote
);
seq_putc
(
seq
,
'\n'
);
}
}
struct
arp_state
{
int
bucket
;
struct
neighbour
*
n
;
struct
clip_seq_state
{
/* This member must be first. */
struct
neigh_seq_state
ns
;
/* Local to clip specific iteration. */
struct
clip_vcc
*
vcc
;
};
static
void
*
arp_vcc_walk
(
struct
arp_state
*
stat
e
,
struct
atmarp_entry
*
e
,
loff_t
*
l
)
static
struct
clip_vcc
*
clip_seq_next_vcc
(
struct
atmarp_entry
*
e
,
struct
clip_vcc
*
curr
)
{
struct
clip_vcc
*
vcc
=
state
->
vcc
;
if
(
!
vcc
)
vcc
=
e
->
vccs
;
if
(
vcc
==
(
void
*
)
1
)
{
vcc
=
e
->
vccs
;
--*
l
;
}
for
(;
vcc
;
vcc
=
vcc
->
next
)
{
if
(
--*
l
<
0
)
break
;
if
(
!
curr
)
{
curr
=
e
->
vccs
;
if
(
!
curr
)
return
SEQ_NO_VCC_TOKEN
;
return
curr
;
}
state
->
vcc
=
vcc
;
return
(
*
l
<
0
)
?
state
:
NULL
;
if
(
curr
==
SEQ_NO_VCC_TOKEN
)
return
NULL
;
curr
=
curr
->
next
;
return
curr
;
}
static
void
*
arp_get_idx
(
struct
arp_state
*
state
,
loff_t
l
)
static
void
*
clip_seq_vcc_walk
(
struct
clip_seq_state
*
state
,
struct
atmarp_entry
*
e
,
loff_t
*
pos
)
{
void
*
v
=
NULL
;
struct
clip_vcc
*
vcc
=
state
->
vcc
;
for
(;
state
->
bucket
<=
NEIGH_HASHMASK
;
state
->
bucket
++
)
{
for
(;
state
->
n
;
state
->
n
=
state
->
n
->
next
)
{
v
=
arp_vcc_walk
(
state
,
NEIGH2ENTRY
(
state
->
n
),
&
l
);
if
(
v
)
goto
done
;
vcc
=
clip_seq_next_vcc
(
e
,
vcc
);
if
(
vcc
&&
pos
!=
NULL
)
{
while
(
*
pos
)
{
vcc
=
clip_seq_next_vcc
(
e
,
vcc
);
if
(
!
vcc
)
break
;
--
(
*
pos
);
}
state
->
n
=
clip_tbl
.
hash_buckets
[
state
->
bucket
+
1
];
}
done:
return
v
;
}
state
->
vcc
=
vcc
;
static
void
*
arp_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
struct
arp_state
*
state
=
seq
->
private
;
void
*
ret
=
(
void
*
)
1
;
read_lock_bh
(
&
clip_tbl
.
lock
);
state
->
bucket
=
0
;
state
->
n
=
clip_tbl
.
hash_buckets
[
0
];
state
->
vcc
=
(
void
*
)
1
;
if
(
*
pos
)
ret
=
arp_get_idx
(
state
,
*
pos
);
return
ret
;
return
vcc
;
}
static
void
arp_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
static
void
*
clip_seq_sub_iter
(
struct
neigh_seq_state
*
_state
,
struct
neighbour
*
n
,
loff_t
*
pos
)
{
struct
arp_state
*
state
=
seq
->
priv
ate
;
struct
clip_seq_state
*
state
=
(
struct
clip_seq_state
*
)
_st
ate
;
if
(
state
->
bucket
!=
-
1
)
read_unlock_bh
(
&
clip_tbl
.
lock
);
return
clip_seq_vcc_walk
(
state
,
NEIGH2ENTRY
(
n
),
pos
);
}
static
void
*
arp_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
static
void
*
clip_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
struct
arp_state
*
state
=
seq
->
private
;
v
=
arp_get_idx
(
state
,
1
);
*
pos
+=
!!
PTR_ERR
(
v
);
return
v
;
return
neigh_seq_start
(
seq
,
pos
,
&
clip_tbl
,
NEIGH_SEQ_NEIGH_ONLY
);
}
static
int
ar
p_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
static
int
cli
p_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
static
char
atm_arp_banner
[]
=
"IPitf TypeEncp Idle IP address ATM address
\n
"
;
if
(
v
==
(
void
*
)
1
)
if
(
v
==
SEQ_START_TOKEN
)
{
seq_puts
(
seq
,
atm_arp_banner
);
else
{
struct
arp
_state
*
state
=
seq
->
private
;
struct
neighbour
*
n
=
state
->
n
;
}
else
{
struct
clip_seq
_state
*
state
=
seq
->
private
;
struct
neighbour
*
n
=
v
;
struct
clip_vcc
*
vcc
=
state
->
vcc
;
atmarp_info
(
seq
,
n
->
dev
,
NEIGH2ENTRY
(
n
),
vcc
);
...
...
@@ -955,15 +939,15 @@ static int arp_seq_show(struct seq_file *seq, void *v)
}
static
struct
seq_operations
arp_seq_ops
=
{
.
start
=
ar
p_seq_start
,
.
next
=
arp
_seq_next
,
.
stop
=
arp
_seq_stop
,
.
show
=
ar
p_seq_show
,
.
start
=
cli
p_seq_start
,
.
next
=
neigh
_seq_next
,
.
stop
=
neigh
_seq_stop
,
.
show
=
cli
p_seq_show
,
};
static
int
arp_seq_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
arp
_state
*
state
;
struct
clip_seq
_state
*
state
;
struct
seq_file
*
seq
;
int
rc
=
-
EAGAIN
;
...
...
@@ -972,6 +956,8 @@ static int arp_seq_open(struct inode *inode, struct file *file)
rc
=
-
ENOMEM
;
goto
out_kfree
;
}
memset
(
state
,
0
,
sizeof
(
*
state
));
state
->
ns
.
neigh_sub_iter
=
clip_seq_sub_iter
;
rc
=
seq_open
(
file
,
&
arp_seq_ops
);
if
(
rc
)
...
...
@@ -987,16 +973,11 @@ static int arp_seq_open(struct inode *inode, struct file *file)
goto
out
;
}
static
int
arp_seq_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_release_private
(
inode
,
file
);
}
static
struct
file_operations
arp_seq_fops
=
{
.
open
=
arp_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
arp_seq_releas
e
,
.
release
=
seq_release_privat
e
,
.
owner
=
THIS_MODULE
};
#endif
...
...
net/core/neighbour.c
View file @
27df0cf8
This diff is collapsed.
Click to expand it.
net/decnet/dn_neigh.c
View file @
27df0cf8
...
...
@@ -36,6 +36,7 @@
#include <linux/spinlock.h>
#include <linux/seq_file.h>
#include <linux/rcupdate.h>
#include <linux/jhash.h>
#include <asm/atomic.h>
#include <net/neighbour.h>
#include <net/dst.h>
...
...
@@ -122,13 +123,7 @@ struct neigh_table dn_neigh_table = {
static
u32
dn_neigh_hash
(
const
void
*
pkey
,
const
struct
net_device
*
dev
)
{
u32
hash_val
;
hash_val
=
*
(
dn_address
*
)
pkey
;
hash_val
^=
(
hash_val
>>
10
);
hash_val
^=
(
hash_val
>>
3
);
return
hash_val
&
NEIGH_HASHMASK
;
return
jhash_2words
(
*
(
dn_address
*
)
pkey
,
0
,
dn_neigh_table
.
hash_rnd
);
}
static
int
dn_neigh_construct
(
struct
neighbour
*
neigh
)
...
...
@@ -359,27 +354,6 @@ static int dn_phase3_output(struct sk_buff *skb)
* basically does a neigh_lookup(), but without comparing the device
* field. This is required for the On-Ethernet cache
*/
struct
neighbour
*
dn_neigh_lookup
(
struct
neigh_table
*
tbl
,
const
void
*
ptr
)
{
struct
neighbour
*
neigh
;
u32
hash_val
;
hash_val
=
tbl
->
hash
(
ptr
,
NULL
);
read_lock_bh
(
&
tbl
->
lock
);
for
(
neigh
=
tbl
->
hash_buckets
[
hash_val
];
neigh
!=
NULL
;
neigh
=
neigh
->
next
)
{
if
(
memcmp
(
neigh
->
primary_key
,
ptr
,
tbl
->
key_len
)
==
0
)
{
atomic_inc
(
&
neigh
->
refcnt
);
read_unlock_bh
(
&
tbl
->
lock
);
return
neigh
;
}
}
read_unlock_bh
(
&
tbl
->
lock
);
return
NULL
;
}
/*
* Any traffic on a pointopoint link causes the timer to be reset
* for the entry in the neighbour table.
...
...
@@ -514,141 +488,66 @@ static char *dn_find_slot(char *base, int max, int priority)
return
(
*
min
<
priority
)
?
(
min
-
6
)
:
NULL
;
}
int
dn_neigh_elist
(
struct
net_device
*
dev
,
unsigned
char
*
ptr
,
int
n
)
struct
elist_cb_state
{
struct
net_device
*
dev
;
unsigned
char
*
ptr
;
unsigned
char
*
rs
;
int
t
,
n
;
};
static
void
neigh_elist_cb
(
struct
neighbour
*
neigh
,
void
*
_info
)
{
int
t
=
0
;
int
i
;
struct
neighbour
*
neigh
;
struct
elist_cb_state
*
s
=
_info
;
struct
dn_dev
*
dn_db
;
struct
dn_neigh
*
dn
;
struct
neigh_table
*
tbl
=
&
dn_neigh_table
;
unsigned
char
*
rs
=
ptr
;
struct
dn_dev
*
dn_db
=
(
struct
dn_dev
*
)
dev
->
dn_ptr
;
read_lock_bh
(
&
tbl
->
lock
);
if
(
neigh
->
dev
!=
s
->
dev
)
return
;
for
(
i
=
0
;
i
<
NEIGH_HASHMASK
;
i
++
)
{
for
(
neigh
=
tbl
->
hash_buckets
[
i
];
neigh
!=
NULL
;
neigh
=
neigh
->
next
)
{
if
(
neigh
->
dev
!=
dev
)
continue
;
dn
=
(
struct
dn_neigh
*
)
neigh
;
dn
=
(
struct
dn_neigh
*
)
neigh
;
if
(
!
(
dn
->
flags
&
(
DN_NDFLAG_R1
|
DN_NDFLAG_R2
)))
continue
;
if
(
dn_db
->
parms
.
forwarding
==
1
&&
(
dn
->
flags
&
DN_NDFLAG_R2
))
continue
;
if
(
t
==
n
)
rs
=
dn_find_slot
(
ptr
,
n
,
dn
->
priority
);
else
t
++
;
if
(
rs
==
NULL
)
continue
;
dn_dn2eth
(
rs
,
dn
->
addr
);
rs
+=
6
;
*
rs
=
neigh
->
nud_state
&
NUD_CONNECTED
?
0x80
:
0x0
;
*
rs
|=
dn
->
priority
;
rs
++
;
}
}
read_unlock_bh
(
&
tbl
->
lock
);
return
t
;
}
#ifdef CONFIG_PROC_FS
struct
dn_neigh_iter_state
{
int
bucket
;
};
static
struct
neighbour
*
neigh_get_first
(
struct
seq_file
*
seq
)
{
struct
dn_neigh_iter_state
*
state
=
seq
->
private
;
struct
neighbour
*
n
=
NULL
;
for
(
state
->
bucket
=
0
;
state
->
bucket
<=
NEIGH_HASHMASK
;
++
state
->
bucket
)
{
n
=
dn_neigh_table
.
hash_buckets
[
state
->
bucket
];
if
(
n
)
break
;
}
return
;
return
n
;
}
dn_db
=
(
struct
dn_dev
*
)
s
->
dev
->
dn_ptr
;
if
(
dn_db
->
parms
.
forwarding
==
1
&&
(
dn
->
flags
&
DN_NDFLAG_R2
))
return
;
static
struct
neighbour
*
neigh_get_next
(
struct
seq_file
*
seq
,
struct
neighbour
*
n
)
{
struct
dn_neigh_iter_state
*
state
=
seq
->
private
;
if
(
s
->
t
==
s
->
n
)
s
->
rs
=
dn_find_slot
(
s
->
ptr
,
s
->
n
,
dn
->
priority
);
else
s
->
t
++
;
if
(
s
->
rs
==
NULL
)
return
;
n
=
n
->
next
;
try_again:
if
(
n
)
goto
out
;
if
(
++
state
->
bucket
>
NEIGH_HASHMASK
)
goto
out
;
n
=
dn_neigh_table
.
hash_buckets
[
state
->
bucket
];
goto
try_again
;
out:
return
n
;
dn_dn2eth
(
s
->
rs
,
dn
->
addr
);
s
->
rs
+=
6
;
*
(
s
->
rs
)
=
neigh
->
nud_state
&
NUD_CONNECTED
?
0x80
:
0x0
;
*
(
s
->
rs
)
|=
dn
->
priority
;
s
->
rs
++
;
}
static
struct
neighbour
*
neigh_get_idx
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
int
dn_neigh_elist
(
struct
net_device
*
dev
,
unsigned
char
*
ptr
,
int
n
)
{
struct
neighbour
*
n
=
neigh_get_first
(
seq
)
;
struct
elist_cb_state
state
;
if
(
n
)
while
(
*
pos
&&
(
n
=
neigh_get_next
(
seq
,
n
)))
--*
pos
;
return
*
pos
?
NULL
:
n
;
}
state
.
dev
=
dev
;
state
.
t
=
0
;
state
.
n
=
n
;
state
.
ptr
=
ptr
;
state
.
rs
=
ptr
;
static
void
*
dn_neigh_get_idx
(
struct
seq_file
*
seq
,
loff_t
pos
)
{
void
*
rc
;
read_lock_bh
(
&
dn_neigh_table
.
lock
);
rc
=
neigh_get_idx
(
seq
,
&
pos
);
if
(
!
rc
)
{
read_unlock_bh
(
&
dn_neigh_table
.
lock
);
}
return
rc
;
}
neigh_for_each
(
&
dn_neigh_table
,
neigh_elist_cb
,
&
state
);
static
void
*
dn_neigh_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
return
*
pos
?
dn_neigh_get_idx
(
seq
,
*
pos
-
1
)
:
SEQ_START_TOKEN
;
return
state
.
t
;
}
static
void
*
dn_neigh_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
void
*
rc
;
if
(
v
==
SEQ_START_TOKEN
)
{
rc
=
dn_neigh_get_idx
(
seq
,
0
);
goto
out
;
}
rc
=
neigh_get_next
(
seq
,
v
);
if
(
rc
)
goto
out
;
read_unlock_bh
(
&
dn_neigh_table
.
lock
);
out:
++*
pos
;
return
rc
;
}
static
void
dn_neigh_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
if
(
v
&&
v
!=
SEQ_START_TOKEN
)
read_unlock_bh
(
&
dn_neigh_table
.
lock
);
}
#ifdef CONFIG_PROC_FS
static
inline
void
dn_neigh_format_entry
(
struct
seq_file
*
seq
,
struct
neighbour
*
n
)
{
struct
dn_neigh
*
dn
=
(
struct
dn_neigh
*
)
n
;
struct
dn_neigh
*
dn
=
(
struct
dn_neigh
*
)
n
;
char
buf
[
DN_ASCBUF_LEN
];
read_lock
(
&
n
->
lock
);
...
...
@@ -675,10 +574,16 @@ static int dn_neigh_seq_show(struct seq_file *seq, void *v)
return
0
;
}
static
void
*
dn_neigh_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
return
neigh_seq_start
(
seq
,
pos
,
&
dn_neigh_table
,
NEIGH_SEQ_NEIGH_ONLY
);
}
static
struct
seq_operations
dn_neigh_seq_ops
=
{
.
start
=
dn_neigh_seq_start
,
.
next
=
dn_
neigh_seq_next
,
.
stop
=
dn_
neigh_seq_stop
,
.
next
=
neigh_seq_next
,
.
stop
=
neigh_seq_stop
,
.
show
=
dn_neigh_seq_show
,
};
...
...
@@ -686,11 +591,12 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file)
{
struct
seq_file
*
seq
;
int
rc
=
-
ENOMEM
;
struct
dn_neigh_iter
_state
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
struct
neigh_seq
_state
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
if
(
!
s
)
goto
out
;
memset
(
s
,
0
,
sizeof
(
*
s
));
rc
=
seq_open
(
file
,
&
dn_neigh_seq_ops
);
if
(
rc
)
goto
out_kfree
;
...
...
net/decnet/dn_route.c
View file @
27df0cf8
...
...
@@ -996,7 +996,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
* here
*/
if
(
!
try_hard
)
{
neigh
=
dn_neigh_lookup
(
&
dn_neigh_table
,
&
fl
.
fld_dst
);
neigh
=
neigh_lookup_nodev
(
&
dn_neigh_table
,
&
fl
.
fld_dst
);
if
(
neigh
)
{
if
((
oldflp
->
oif
&&
(
neigh
->
dev
->
ifindex
!=
oldflp
->
oif
))
||
...
...
net/ipv4/arp.c
View file @
27df0cf8
...
...
@@ -71,6 +71,7 @@
* arp_xmit so intermediate drivers like
* bonding can change the skb before
* sending (e.g. insert 8021q tag).
* Harald Welte : convert to make use of jenkins hash
*/
#include <linux/module.h>
...
...
@@ -97,6 +98,7 @@
#include <linux/init.h>
#include <linux/net.h>
#include <linux/rcupdate.h>
#include <linux/jhash.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
...
...
@@ -223,15 +225,7 @@ int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir)
static
u32
arp_hash
(
const
void
*
pkey
,
const
struct
net_device
*
dev
)
{
u32
hash_val
;
hash_val
=
*
(
u32
*
)
pkey
;
hash_val
^=
(
hash_val
>>
16
);
hash_val
^=
hash_val
>>
8
;
hash_val
^=
hash_val
>>
3
;
hash_val
=
(
hash_val
^
dev
->
ifindex
)
&
NEIGH_HASHMASK
;
return
hash_val
;
return
jhash_2words
(
*
(
u32
*
)
pkey
,
dev
->
ifindex
,
arp_tbl
.
hash_rnd
);
}
static
int
arp_constructor
(
struct
neighbour
*
neigh
)
...
...
@@ -1269,161 +1263,9 @@ static char *ax2asc2(ax25_address *a, char *buf)
}
#endif
/* CONFIG_AX25 */
struct
arp_iter_state
{
int
is_pneigh
,
bucket
;
};
static
struct
neighbour
*
neigh_get_first
(
struct
seq_file
*
seq
)
{
struct
arp_iter_state
*
state
=
seq
->
private
;
struct
neighbour
*
n
=
NULL
;
state
->
is_pneigh
=
0
;
for
(
state
->
bucket
=
0
;
state
->
bucket
<=
NEIGH_HASHMASK
;
++
state
->
bucket
)
{
n
=
arp_tbl
.
hash_buckets
[
state
->
bucket
];
while
(
n
&&
!
(
n
->
nud_state
&
~
NUD_NOARP
))
n
=
n
->
next
;
if
(
n
)
break
;
}
return
n
;
}
static
struct
neighbour
*
neigh_get_next
(
struct
seq_file
*
seq
,
struct
neighbour
*
n
)
{
struct
arp_iter_state
*
state
=
seq
->
private
;
do
{
n
=
n
->
next
;
/* Don't confuse "arp -a" w/ magic entries */
try_again:
;
}
while
(
n
&&
!
(
n
->
nud_state
&
~
NUD_NOARP
));
if
(
n
)
goto
out
;
if
(
++
state
->
bucket
>
NEIGH_HASHMASK
)
goto
out
;
n
=
arp_tbl
.
hash_buckets
[
state
->
bucket
];
goto
try_again
;
out:
return
n
;
}
static
struct
neighbour
*
neigh_get_idx
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
struct
neighbour
*
n
=
neigh_get_first
(
seq
);
if
(
n
)
while
(
*
pos
&&
(
n
=
neigh_get_next
(
seq
,
n
)))
--*
pos
;
return
*
pos
?
NULL
:
n
;
}
static
struct
pneigh_entry
*
pneigh_get_first
(
struct
seq_file
*
seq
)
{
struct
arp_iter_state
*
state
=
seq
->
private
;
struct
pneigh_entry
*
pn
;
state
->
is_pneigh
=
1
;
for
(
state
->
bucket
=
0
;
state
->
bucket
<=
PNEIGH_HASHMASK
;
++
state
->
bucket
)
{
pn
=
arp_tbl
.
phash_buckets
[
state
->
bucket
];
if
(
pn
)
break
;
}
return
pn
;
}
static
struct
pneigh_entry
*
pneigh_get_next
(
struct
seq_file
*
seq
,
struct
pneigh_entry
*
pn
)
{
struct
arp_iter_state
*
state
=
seq
->
private
;
pn
=
pn
->
next
;
while
(
!
pn
)
{
if
(
++
state
->
bucket
>
PNEIGH_HASHMASK
)
break
;
pn
=
arp_tbl
.
phash_buckets
[
state
->
bucket
];
}
return
pn
;
}
static
struct
pneigh_entry
*
pneigh_get_idx
(
struct
seq_file
*
seq
,
loff_t
pos
)
{
struct
pneigh_entry
*
pn
=
pneigh_get_first
(
seq
);
if
(
pn
)
while
(
pos
&&
(
pn
=
pneigh_get_next
(
seq
,
pn
)))
--
pos
;
return
pos
?
NULL
:
pn
;
}
static
void
*
arp_get_idx
(
struct
seq_file
*
seq
,
loff_t
pos
)
{
void
*
rc
;
read_lock_bh
(
&
arp_tbl
.
lock
);
rc
=
neigh_get_idx
(
seq
,
&
pos
);
if
(
!
rc
)
{
read_unlock_bh
(
&
arp_tbl
.
lock
);
rc
=
pneigh_get_idx
(
seq
,
pos
);
}
return
rc
;
}
static
void
*
arp_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
struct
arp_iter_state
*
state
=
seq
->
private
;
state
->
is_pneigh
=
0
;
state
->
bucket
=
0
;
return
*
pos
?
arp_get_idx
(
seq
,
*
pos
-
1
)
:
SEQ_START_TOKEN
;
}
static
void
*
arp_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
void
*
rc
;
struct
arp_iter_state
*
state
;
if
(
v
==
SEQ_START_TOKEN
)
{
rc
=
arp_get_idx
(
seq
,
0
);
goto
out
;
}
state
=
seq
->
private
;
if
(
!
state
->
is_pneigh
)
{
rc
=
neigh_get_next
(
seq
,
v
);
if
(
rc
)
goto
out
;
read_unlock_bh
(
&
arp_tbl
.
lock
);
rc
=
pneigh_get_first
(
seq
);
}
else
rc
=
pneigh_get_next
(
seq
,
v
);
out:
++*
pos
;
return
rc
;
}
static
void
arp_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
struct
arp_iter_state
*
state
=
seq
->
private
;
if
(
!
state
->
is_pneigh
&&
v
!=
SEQ_START_TOKEN
)
read_unlock_bh
(
&
arp_tbl
.
lock
);
}
#define HBUFFERLEN 30
static
__inline__
void
arp_format_neigh_entry
(
struct
seq_file
*
seq
,
static
void
arp_format_neigh_entry
(
struct
seq_file
*
seq
,
struct
neighbour
*
n
)
{
char
hbuffer
[
HBUFFERLEN
];
...
...
@@ -1455,7 +1297,7 @@ static __inline__ void arp_format_neigh_entry(struct seq_file *seq,
read_unlock
(
&
n
->
lock
);
}
static
__inline__
void
arp_format_pneigh_entry
(
struct
seq_file
*
seq
,
static
void
arp_format_pneigh_entry
(
struct
seq_file
*
seq
,
struct
pneigh_entry
*
n
)
{
struct
net_device
*
dev
=
n
->
dev
;
...
...
@@ -1470,13 +1312,13 @@ static __inline__ void arp_format_pneigh_entry(struct seq_file *seq,
static
int
arp_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
if
(
v
==
SEQ_START_TOKEN
)
if
(
v
==
SEQ_START_TOKEN
)
{
seq_puts
(
seq
,
"IP address HW type Flags "
"HW address Mask Device
\n
"
);
else
{
struct
arp_iter_state
*
state
=
seq
->
private
;
}
else
{
struct
neigh_seq_state
*
state
=
seq
->
private
;
if
(
state
->
is_pneigh
)
if
(
state
->
flags
&
NEIGH_SEQ_IS_PNEIGH
)
arp_format_pneigh_entry
(
seq
,
v
);
else
arp_format_neigh_entry
(
seq
,
v
);
...
...
@@ -1485,12 +1327,20 @@ static int arp_seq_show(struct seq_file *seq, void *v)
return
0
;
}
static
void
*
arp_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
/* Don't want to confuse "arp -a" w/ magic entries,
* so we tell the generic iterator to skip NUD_NOARP.
*/
return
neigh_seq_start
(
seq
,
pos
,
&
arp_tbl
,
NEIGH_SEQ_SKIP_NOARP
);
}
/* ------------------------------------------------------------------------ */
static
struct
seq_operations
arp_seq_ops
=
{
.
start
=
arp_seq_start
,
.
next
=
arp
_seq_next
,
.
stop
=
arp
_seq_stop
,
.
next
=
neigh
_seq_next
,
.
stop
=
neigh
_seq_stop
,
.
show
=
arp_seq_show
,
};
...
...
@@ -1498,11 +1348,12 @@ static int arp_seq_open(struct inode *inode, struct file *file)
{
struct
seq_file
*
seq
;
int
rc
=
-
ENOMEM
;
struct
arp_iter
_state
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
struct
neigh_seq
_state
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
if
(
!
s
)
goto
out
;
memset
(
s
,
0
,
sizeof
(
*
s
));
rc
=
seq_open
(
file
,
&
arp_seq_ops
);
if
(
rc
)
goto
out_kfree
;
...
...
net/ipv4/fib_hash.c
View file @
27df0cf8
...
...
@@ -438,17 +438,15 @@ static struct fib_alias *fib_find_alias(struct fib_node *fn, u8 tos, u32 prio)
{
if
(
fn
)
{
struct
list_head
*
head
=
&
fn
->
fn_alias
;
struct
fib_alias
*
fa
,
*
prev_fa
;
struct
fib_alias
*
fa
;
prev_fa
=
NULL
;
list_for_each_entry
(
fa
,
head
,
fa_list
)
{
if
(
fa
->
fa_tos
!=
tos
)
if
(
fa
->
fa_tos
>
tos
)
continue
;
prev_fa
=
fa
;
if
(
prio
<=
fa
->
fa_info
->
fib_priority
)
break
;
if
(
fa
->
fa_info
->
fib_priority
>=
prio
||
fa
->
fa_tos
<
tos
)
return
fa
;
}
return
prev_fa
;
}
return
NULL
;
}
...
...
@@ -505,7 +503,7 @@ fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
* and we need to allocate a new one of those as well.
*/
if
(
fa
&&
if
(
fa
&&
fa
->
fa_tos
==
tos
&&
fa
->
fa_info
->
fib_priority
==
fi
->
fib_priority
)
{
struct
fib_alias
*
fa_orig
;
...
...
@@ -537,7 +535,8 @@ fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
* information.
*/
fa_orig
=
fa
;
list_for_each_entry
(
fa
,
fa_orig
->
fa_list
.
prev
,
fa_list
)
{
fa
=
list_entry
(
fa
->
fa_list
.
prev
,
struct
fib_alias
,
fa_list
);
list_for_each_entry_continue
(
fa
,
&
f
->
fn_alias
,
fa_list
)
{
if
(
fa
->
fa_tos
!=
tos
)
break
;
if
(
fa
->
fa_info
->
fib_priority
!=
fi
->
fib_priority
)
...
...
@@ -585,7 +584,7 @@ fn_hash_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
write_lock_bh
(
&
fib_hash_lock
);
if
(
new_f
)
fib_insert_node
(
fz
,
new_f
);
list_add
(
&
new_fa
->
fa_list
,
list_add
_tail
(
&
new_fa
->
fa_list
,
(
fa
?
&
fa
->
fa_list
:
&
f
->
fn_alias
));
write_unlock_bh
(
&
fib_hash_lock
);
...
...
@@ -611,7 +610,6 @@ fn_hash_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
struct
fn_hash
*
table
=
(
struct
fn_hash
*
)
tb
->
tb_data
;
struct
fib_node
*
f
;
struct
fib_alias
*
fa
,
*
fa_to_delete
;
struct
list_head
*
fa_head
;
int
z
=
r
->
rtm_dst_len
;
struct
fn_zone
*
fz
;
u32
key
;
...
...
@@ -637,8 +635,8 @@ fn_hash_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
return
-
ESRCH
;
fa_to_delete
=
NULL
;
fa
_head
=
fa
->
fa_list
.
prev
;
list_for_each_entry
(
fa
,
fa_head
,
fa_list
)
{
fa
=
list_entry
(
fa
->
fa_list
.
prev
,
struct
fib_alias
,
fa_list
)
;
list_for_each_entry
_continue
(
fa
,
&
f
->
fn_alias
,
fa_list
)
{
struct
fib_info
*
fi
=
fa
->
fa_info
;
if
(
fa
->
fa_tos
!=
tos
)
...
...
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
View file @
27df0cf8
...
...
@@ -139,7 +139,7 @@ icmp_error_message(struct sk_buff *skb,
struct
{
struct
icmphdr
icmp
;
struct
iphdr
ip
;
}
inside
;
}
_in
,
*
inside
;
struct
ip_conntrack_protocol
*
innerproto
;
struct
ip_conntrack_tuple_hash
*
h
;
int
dataoff
;
...
...
@@ -147,21 +147,22 @@ icmp_error_message(struct sk_buff *skb,
IP_NF_ASSERT
(
skb
->
nfct
==
NULL
);
/* Not enough header? */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
inside
,
sizeof
(
inside
))
!=
0
)
inside
=
skb_header_pointer
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
sizeof
(
_in
),
&
_in
);
if
(
inside
==
NULL
)
return
NF_ACCEPT
;
/* Ignore ICMP's containing fragments (shouldn't happen) */
if
(
inside
.
ip
.
frag_off
&
htons
(
IP_OFFSET
))
{
if
(
inside
->
ip
.
frag_off
&
htons
(
IP_OFFSET
))
{
DEBUGP
(
"icmp_error_track: fragment of proto %u
\n
"
,
inside
.
ip
.
protocol
);
inside
->
ip
.
protocol
);
return
NF_ACCEPT
;
}
innerproto
=
ip_ct_find_proto
(
inside
.
ip
.
protocol
);
dataoff
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
inside
.
icmp
)
+
inside
.
ip
.
ihl
*
4
;
innerproto
=
ip_ct_find_proto
(
inside
->
ip
.
protocol
);
dataoff
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
inside
->
icmp
)
+
inside
->
ip
.
ihl
*
4
;
/* Are they talking about one of our connections? */
if
(
!
ip_ct_get_tuple
(
&
inside
.
ip
,
skb
,
dataoff
,
&
origtuple
,
innerproto
))
{
DEBUGP
(
"icmp_error: ! get_tuple p=%u"
,
inside
.
ip
.
protocol
);
if
(
!
ip_ct_get_tuple
(
&
inside
->
ip
,
skb
,
dataoff
,
&
origtuple
,
innerproto
))
{
DEBUGP
(
"icmp_error: ! get_tuple p=%u"
,
inside
->
ip
.
protocol
);
return
NF_ACCEPT
;
}
...
...
@@ -205,10 +206,11 @@ static int
icmp_error
(
struct
sk_buff
*
skb
,
enum
ip_conntrack_info
*
ctinfo
,
unsigned
int
hooknum
)
{
struct
icmphdr
icmph
;
struct
icmphdr
_ih
,
*
icmph
;
/* Not enough header? */
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
icmph
,
sizeof
(
icmph
))
!=
0
)
{
icmph
=
skb_header_pointer
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
sizeof
(
_ih
),
&
_ih
);
if
(
icmph
==
NULL
)
{
if
(
LOG_INVALID
(
IPPROTO_ICMP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_icmp: short packet "
);
...
...
@@ -245,7 +247,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
* RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently
* discarded.
*/
if
(
icmph
.
type
>
NR_ICMP_TYPES
)
{
if
(
icmph
->
type
>
NR_ICMP_TYPES
)
{
if
(
LOG_INVALID
(
IPPROTO_ICMP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_icmp: invalid ICMP type "
);
...
...
@@ -253,11 +255,11 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
}
/* Need to track icmp error message? */
if
(
icmph
.
type
!=
ICMP_DEST_UNREACH
&&
icmph
.
type
!=
ICMP_SOURCE_QUENCH
&&
icmph
.
type
!=
ICMP_TIME_EXCEEDED
&&
icmph
.
type
!=
ICMP_PARAMETERPROB
&&
icmph
.
type
!=
ICMP_REDIRECT
)
if
(
icmph
->
type
!=
ICMP_DEST_UNREACH
&&
icmph
->
type
!=
ICMP_SOURCE_QUENCH
&&
icmph
->
type
!=
ICMP_TIME_EXCEEDED
&&
icmph
->
type
!=
ICMP_PARAMETERPROB
&&
icmph
->
type
!=
ICMP_REDIRECT
)
return
NF_ACCEPT
;
return
icmp_error_message
(
skb
,
ctinfo
,
hooknum
);
...
...
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
View file @
27df0cf8
...
...
@@ -152,18 +152,18 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
unsigned
int
dataoff
,
struct
ip_conntrack_tuple
*
tuple
)
{
sctp_sctphdr_t
hdr
;
sctp_sctphdr_t
_hdr
,
*
hp
;
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
/* Actually only need first 8 bytes. */
if
(
skb_copy_bits
(
skb
,
dataoff
,
&
hdr
,
8
)
!=
0
)
hp
=
skb_header_pointer
(
skb
,
dataoff
,
8
,
&
_hdr
);
if
(
hp
==
NULL
)
return
0
;
tuple
->
src
.
u
.
sctp
.
port
=
hdr
.
source
;
tuple
->
dst
.
u
.
sctp
.
port
=
hdr
.
dest
;
tuple
->
src
.
u
.
sctp
.
port
=
hp
->
source
;
tuple
->
dst
.
u
.
sctp
.
port
=
hp
->
dest
;
return
1
;
}
...
...
@@ -206,10 +206,11 @@ static int sctp_print_conntrack(struct seq_file *s,
return
seq_printf
(
s
,
"%s "
,
sctp_conntrack_names
[
state
]);
}
#define for_each_sctp_chunk(skb, sch, offset, count) \
for (offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t), count = 0; \
offset < skb->len && !skb_copy_bits(skb, offset, &sch, sizeof(sch)); \
offset += (htons(sch.length) + 3) & ~3, count++)
#define for_each_sctp_chunk(skb, sch, _sch, offset, count) \
for (offset = skb->nh.iph->ihl * 4 + sizeof(sctp_sctphdr_t), count = 0; \
offset < skb->len && \
(sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
offset += (htons(sch->length) + 3) & ~3, count++)
/* Some validity checks to make sure the chunks are fine */
static
int
do_basic_checks
(
struct
ip_conntrack
*
conntrack
,
...
...
@@ -217,7 +218,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
char
*
map
)
{
u_int32_t
offset
,
count
;
sctp_chunkhdr_t
sch
;
sctp_chunkhdr_t
_sch
,
*
sch
;
int
flag
;
DEBUGP
(
__FUNCTION__
);
...
...
@@ -225,19 +226,19 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
flag
=
0
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
DEBUGP
(
"Chunk Num: %d Type: %d
\n
"
,
count
,
sch
.
type
);
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
DEBUGP
(
"Chunk Num: %d Type: %d
\n
"
,
count
,
sch
->
type
);
if
(
sch
.
type
==
SCTP_CID_INIT
||
sch
.
type
==
SCTP_CID_INIT_ACK
||
sch
.
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
if
(
sch
->
type
==
SCTP_CID_INIT
||
sch
->
type
==
SCTP_CID_INIT_ACK
||
sch
->
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
flag
=
1
;
}
/* Cookie Ack/Echo chunks not the first OR
Init / Init Ack / Shutdown compl chunks not the only chunks */
if
((
sch
.
type
==
SCTP_CID_COOKIE_ACK
||
sch
.
type
==
SCTP_CID_COOKIE_ECHO
if
((
sch
->
type
==
SCTP_CID_COOKIE_ACK
||
sch
->
type
==
SCTP_CID_COOKIE_ECHO
||
flag
)
&&
count
!=
0
)
{
DEBUGP
(
"Basic checks failed
\n
"
);
...
...
@@ -245,7 +246,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
}
if
(
map
)
{
set_bit
(
sch
.
type
,
(
void
*
)
map
);
set_bit
(
sch
->
type
,
(
void
*
)
map
);
}
}
...
...
@@ -313,15 +314,17 @@ static int sctp_packet(struct ip_conntrack *conntrack,
enum
ip_conntrack_info
ctinfo
)
{
enum
sctp_conntrack
newconntrack
,
oldsctpstate
;
sctp_sctphdr_t
sctph
;
sctp_chunkhdr_t
sch
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
sctp_sctphdr_t
_sctph
,
*
sh
;
sctp_chunkhdr_t
_sch
,
*
sch
;
u_int32_t
offset
,
count
;
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
sctph
,
sizeof
(
sctph
))
!=
0
)
sh
=
skb_header_pointer
(
skb
,
iph
->
ihl
*
4
,
sizeof
(
_sctph
),
&
_sctph
);
if
(
sh
==
NULL
)
return
-
1
;
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
...
...
@@ -333,71 +336,72 @@ static int sctp_packet(struct ip_conntrack *conntrack,
&&
!
test_bit
(
SCTP_CID_COOKIE_ECHO
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_ABORT
,
(
void
*
)
map
)
&&
!
test_bit
(
SCTP_CID_SHUTDOWN_ACK
,
(
void
*
)
map
)
&&
(
s
ctph
.
vtag
!=
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
&&
(
s
h
->
vtag
!=
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
DEBUGP
(
"Verification tag check failed
\n
"
);
return
-
1
;
}
oldsctpstate
=
newconntrack
=
SCTP_CONNTRACK_MAX
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
WRITE_LOCK
(
&
sctp_lock
);
/* Special cases of Verification tag check (Sec 8.5.1) */
if
(
sch
.
type
==
SCTP_CID_INIT
)
{
if
(
sch
->
type
==
SCTP_CID_INIT
)
{
/* Sec 8.5.1 (A) */
if
(
s
ctph
.
vtag
!=
0
)
{
if
(
s
h
->
vtag
!=
0
)
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
else
if
(
sch
.
type
==
SCTP_CID_ABORT
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_ABORT
)
{
/* Sec 8.5.1 (B) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
1
-
CTINFO2DIR
(
ctinfo
)]))
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
else
if
(
sch
.
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_SHUTDOWN_COMPLETE
)
{
/* Sec 8.5.1 (C) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)])
&&
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
1
-
CTINFO2DIR
(
ctinfo
)]
&&
(
sch
.
flags
&
1
)))
{
&&
(
sch
->
flags
&
1
)))
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
else
if
(
sch
.
type
==
SCTP_CID_COOKIE_ECHO
)
{
}
else
if
(
sch
->
type
==
SCTP_CID_COOKIE_ECHO
)
{
/* Sec 8.5.1 (D) */
if
(
!
(
s
ctph
.
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
if
(
!
(
s
h
->
vtag
==
conntrack
->
proto
.
sctp
.
vtag
[
CTINFO2DIR
(
ctinfo
)]))
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
}
oldsctpstate
=
conntrack
->
proto
.
sctp
.
state
;
newconntrack
=
new_state
(
CTINFO2DIR
(
ctinfo
),
oldsctpstate
,
sch
.
type
);
newconntrack
=
new_state
(
CTINFO2DIR
(
ctinfo
),
oldsctpstate
,
sch
->
type
);
/* Invalid */
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
DEBUGP
(
"ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u
\n
"
,
CTINFO2DIR
(
ctinfo
),
sch
.
type
,
oldsctpstate
);
CTINFO2DIR
(
ctinfo
),
sch
->
type
,
oldsctpstate
);
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
/* If it is an INIT or an INIT ACK note down the vtag */
if
(
sch
.
type
==
SCTP_CID_INIT
||
sch
.
type
==
SCTP_CID_INIT_ACK
)
{
sctp_inithdr_t
inithdr
;
if
(
sch
->
type
==
SCTP_CID_INIT
||
sch
->
type
==
SCTP_CID_INIT_ACK
)
{
sctp_inithdr_t
_inithdr
,
*
ih
;
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
&
inithdr
,
sizeof
(
inithdr
))
!=
0
)
{
ih
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
sizeof
(
_inithdr
),
&
_inithdr
);
if
(
ih
==
NULL
)
{
WRITE_UNLOCK
(
&
sctp_lock
);
return
-
1
;
}
DEBUGP
(
"Setting vtag %x for dir %d
\n
"
,
i
nithdr
.
init_tag
,
CTINFO2DIR
(
ctinfo
));
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_ORIGINAL
]
=
i
nithdr
.
init_tag
;
i
h
->
init_tag
,
CTINFO2DIR
(
ctinfo
));
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_ORIGINAL
]
=
i
h
->
init_tag
;
}
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
...
...
@@ -421,15 +425,17 @@ static int sctp_new(struct ip_conntrack *conntrack,
const
struct
sk_buff
*
skb
)
{
enum
sctp_conntrack
newconntrack
;
sctp_sctphdr_t
sctph
;
sctp_chunkhdr_t
sch
;
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
sctp_sctphdr_t
_sctph
,
*
sh
;
sctp_chunkhdr_t
_sch
,
*
sch
;
u_int32_t
offset
,
count
;
char
map
[
256
/
sizeof
(
char
)]
=
{
0
};
DEBUGP
(
__FUNCTION__
);
DEBUGP
(
"
\n
"
);
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
sctph
,
sizeof
(
sctph
))
!=
0
)
sh
=
skb_header_pointer
(
skb
,
iph
->
ihl
*
4
,
sizeof
(
_sctph
),
&
_sctph
);
if
(
sh
==
NULL
)
return
0
;
if
(
do_basic_checks
(
conntrack
,
skb
,
map
)
!=
0
)
...
...
@@ -443,10 +449,10 @@ static int sctp_new(struct ip_conntrack *conntrack,
}
newconntrack
=
SCTP_CONNTRACK_MAX
;
for_each_sctp_chunk
(
skb
,
sch
,
offset
,
count
)
{
for_each_sctp_chunk
(
skb
,
sch
,
_sch
,
offset
,
count
)
{
/* Don't need lock here: this conntrack not in circulation yet */
newconntrack
=
new_state
(
IP_CT_DIR_ORIGINAL
,
SCTP_CONNTRACK_NONE
,
sch
.
type
);
SCTP_CONNTRACK_NONE
,
sch
->
type
);
/* Invalid: delete conntrack */
if
(
newconntrack
==
SCTP_CONNTRACK_MAX
)
{
...
...
@@ -455,20 +461,20 @@ static int sctp_new(struct ip_conntrack *conntrack,
}
/* Copy the vtag into the state info */
if
(
sch
.
type
==
SCTP_CID_INIT
)
{
if
(
s
ctph
.
vtag
==
0
)
{
sctp_inithdr_t
inithdr
;
if
(
sch
->
type
==
SCTP_CID_INIT
)
{
if
(
s
h
->
vtag
==
0
)
{
sctp_inithdr_t
_inithdr
,
*
ih
;
if
(
skb_copy_bits
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
&
inithdr
,
sizeof
(
inithdr
))
!=
0
)
{
ih
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
sctp_chunkhdr_t
),
sizeof
(
_inithdr
),
&
_inithdr
);
if
(
ih
==
NULL
)
return
0
;
}
DEBUGP
(
"Setting vtag %x for new conn
\n
"
,
i
nithdr
.
init_tag
);
i
h
->
init_tag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
i
nithdr
.
init_tag
;
i
h
->
init_tag
;
}
else
{
/* Sec 8.5.1 (A) */
return
0
;
...
...
@@ -478,8 +484,8 @@ static int sctp_new(struct ip_conntrack *conntrack,
shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
else
{
DEBUGP
(
"Setting vtag %x for new conn OOTB
\n
"
,
s
ctph
.
vtag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
s
ctph
.
vtag
;
s
h
->
vtag
);
conntrack
->
proto
.
sctp
.
vtag
[
IP_CT_DIR_REPLY
]
=
s
h
->
vtag
;
}
conntrack
->
proto
.
sctp
.
state
=
newconntrack
;
...
...
net/ipv4/netfilter/ip_conntrack_proto_udp.c
View file @
27df0cf8
...
...
@@ -91,10 +91,11 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
{
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
unsigned
int
udplen
=
skb
->
len
-
iph
->
ihl
*
4
;
struct
udphdr
hdr
;
struct
udphdr
_hdr
,
*
hdr
;
/* Header is too small? */
if
(
skb_copy_bits
(
skb
,
iph
->
ihl
*
4
,
&
hdr
,
sizeof
(
hdr
))
!=
0
)
{
hdr
=
skb_header_pointer
(
skb
,
iph
->
ihl
*
4
,
sizeof
(
_hdr
),
&
_hdr
);
if
(
hdr
==
NULL
)
{
if
(
LOG_INVALID
(
IPPROTO_UDP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_udp: short packet "
);
...
...
@@ -102,7 +103,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
}
/* Truncated/malformed packets */
if
(
ntohs
(
hdr
.
len
)
>
udplen
||
ntohs
(
hdr
.
len
)
<
sizeof
(
hdr
))
{
if
(
ntohs
(
hdr
->
len
)
>
udplen
||
ntohs
(
hdr
->
len
)
<
sizeof
(
*
hdr
))
{
if
(
LOG_INVALID
(
IPPROTO_UDP
))
nf_log_packet
(
PF_INET
,
0
,
skb
,
NULL
,
NULL
,
"ip_ct_udp: truncated/malformed packet "
);
...
...
@@ -110,7 +111,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
}
/* Packet with no checksum */
if
(
!
hdr
.
check
)
if
(
!
hdr
->
check
)
return
NF_ACCEPT
;
/* Checksum invalid? Ignore.
...
...
net/ipv4/netfilter/ip_conntrack_standalone.c
View file @
27df0cf8
...
...
@@ -871,7 +871,6 @@ EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
EXPORT_SYMBOL
(
invert_tuplepr
);
EXPORT_SYMBOL
(
ip_conntrack_alter_reply
);
EXPORT_SYMBOL
(
ip_conntrack_destroyed
);
EXPORT_SYMBOL
(
ip_conntrack_get
);
EXPORT_SYMBOL
(
need_ip_conntrack
);
EXPORT_SYMBOL
(
ip_conntrack_helper_register
);
EXPORT_SYMBOL
(
ip_conntrack_helper_unregister
);
...
...
net/ipv4/netfilter/ipt_helper.c
View file @
27df0cf8
...
...
@@ -107,6 +107,7 @@ static struct ipt_match helper_match = {
static
int
__init
init
(
void
)
{
need_ip_conntrack
();
return
ipt_register_match
(
&
helper_match
);
}
...
...
net/ipv4/netfilter/ipt_sctp.c
View file @
27df0cf8
...
...
@@ -42,7 +42,7 @@ match_packet(const struct sk_buff *skb,
{
int
offset
;
u_int32_t
chunkmapcopy
[
256
/
sizeof
(
u_int32_t
)];
sctp_chunkhdr_t
sch
;
sctp_chunkhdr_t
_sch
,
*
sch
;
#ifdef DEBUG_SCTP
int
i
=
0
;
...
...
@@ -54,38 +54,39 @@ match_packet(const struct sk_buff *skb,
offset
=
skb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
sctp_sctphdr_t
);
do
{
if
(
skb_copy_bits
(
skb
,
offset
,
&
sch
,
sizeof
(
sch
))
<
0
)
{
sch
=
skb_header_pointer
(
skb
,
offset
,
sizeof
(
_sch
),
&
_sch
);
if
(
sch
==
NULL
)
{
duprintf
(
"Dropping invalid SCTP packet.
\n
"
);
*
hotdrop
=
1
;
return
0
;
}
duprintf
(
"Chunk num: %d
\t
offset: %d
\t
type: %d
\t
length: %d
\t
flags: %x
\n
"
,
++
i
,
offset
,
sch
.
type
,
htons
(
sch
.
length
),
sch
.
flags
);
++
i
,
offset
,
sch
->
type
,
htons
(
sch
->
length
),
sch
->
flags
);
offset
+=
(
htons
(
sch
.
length
)
+
3
)
&
~
3
;
offset
+=
(
htons
(
sch
->
length
)
+
3
)
&
~
3
;
duprintf
(
"skb->len: %d
\t
offset: %d
\n
"
,
skb
->
len
,
offset
);
if
(
SCTP_CHUNKMAP_IS_SET
(
chunkmap
,
sch
.
type
))
{
if
(
SCTP_CHUNKMAP_IS_SET
(
chunkmap
,
sch
->
type
))
{
switch
(
chunk_match_type
)
{
case
SCTP_CHUNK_MATCH_ANY
:
if
(
match_flags
(
flag_info
,
flag_count
,
sch
.
type
,
sch
.
flags
))
{
sch
->
type
,
sch
->
flags
))
{
return
1
;
}
break
;
case
SCTP_CHUNK_MATCH_ALL
:
if
(
match_flags
(
flag_info
,
flag_count
,
sch
.
type
,
sch
.
flags
))
{
SCTP_CHUNKMAP_CLEAR
(
chunkmapcopy
,
sch
.
type
);
sch
->
type
,
sch
->
flags
))
{
SCTP_CHUNKMAP_CLEAR
(
chunkmapcopy
,
sch
->
type
);
}
break
;
case
SCTP_CHUNK_MATCH_ONLY
:
if
(
!
match_flags
(
flag_info
,
flag_count
,
sch
.
type
,
sch
.
flags
))
{
sch
->
type
,
sch
->
flags
))
{
return
0
;
}
break
;
...
...
@@ -120,7 +121,7 @@ match(const struct sk_buff *skb,
int
*
hotdrop
)
{
const
struct
ipt_sctp_info
*
info
;
sctp_sctphdr_t
sh
;
sctp_sctphdr_t
_sh
,
*
sh
;
info
=
(
const
struct
ipt_sctp_info
*
)
matchinfo
;
...
...
@@ -129,18 +130,19 @@ match(const struct sk_buff *skb,
return
0
;
}
if
(
skb_copy_bits
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
&
sh
,
sizeof
(
sh
))
<
0
)
{
sh
=
skb_header_pointer
(
skb
,
skb
->
nh
.
iph
->
ihl
*
4
,
sizeof
(
_sh
),
&
_sh
);
if
(
sh
==
NULL
)
{
duprintf
(
"Dropping evil TCP offset=0 tinygram.
\n
"
);
*
hotdrop
=
1
;
return
0
;
}
duprintf
(
"spt: %d
\t
dpt: %d
\n
"
,
ntohs
(
sh
.
source
),
ntohs
(
sh
.
dest
));
duprintf
(
"spt: %d
\t
dpt: %d
\n
"
,
ntohs
(
sh
->
source
),
ntohs
(
sh
->
dest
));
return
SCCHECK
(((
ntohs
(
sh
.
source
)
>=
info
->
spts
[
0
])
&&
(
ntohs
(
sh
.
source
)
<=
info
->
spts
[
1
])),
return
SCCHECK
(((
ntohs
(
sh
->
source
)
>=
info
->
spts
[
0
])
&&
(
ntohs
(
sh
->
source
)
<=
info
->
spts
[
1
])),
IPT_SCTP_SRC_PORTS
,
info
->
flags
,
info
->
invflags
)
&&
SCCHECK
(((
ntohs
(
sh
.
dest
)
>=
info
->
dpts
[
0
])
&&
(
ntohs
(
sh
.
dest
)
<=
info
->
dpts
[
1
])),
&&
SCCHECK
(((
ntohs
(
sh
->
dest
)
>=
info
->
dpts
[
0
])
&&
(
ntohs
(
sh
->
dest
)
<=
info
->
dpts
[
1
])),
IPT_SCTP_DEST_PORTS
,
info
->
flags
,
info
->
invflags
)
&&
SCCHECK
(
match_packet
(
skb
,
info
->
chunkmap
,
info
->
chunk_match_type
,
info
->
flag_info
,
info
->
flag_count
,
...
...
net/ipv4/tcp_diag.c
View file @
27df0cf8
...
...
@@ -68,8 +68,8 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
if
(
tp
->
ecn_flags
&
TCP_ECN_OK
)
info
->
tcpi_options
|=
TCPI_OPT_ECN
;
info
->
tcpi_rto
=
(
1000000
*
tp
->
rto
)
/
HZ
;
info
->
tcpi_ato
=
(
1000000
*
tp
->
ack
.
ato
)
/
HZ
;
info
->
tcpi_rto
=
jiffies_to_usecs
(
tp
->
rto
)
;
info
->
tcpi_ato
=
jiffies_to_usecs
(
tp
->
ack
.
ato
)
;
info
->
tcpi_snd_mss
=
tp
->
mss_cache_std
;
info
->
tcpi_rcv_mss
=
tp
->
ack
.
rcv_mss
;
...
...
@@ -79,20 +79,20 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
info
->
tcpi_retrans
=
tcp_get_pcount
(
&
tp
->
retrans_out
);
info
->
tcpi_fackets
=
tcp_get_pcount
(
&
tp
->
fackets_out
);
info
->
tcpi_last_data_sent
=
((
now
-
tp
->
lsndtime
)
*
1000
)
/
HZ
;
info
->
tcpi_last_data_recv
=
((
now
-
tp
->
ack
.
lrcvtime
)
*
1000
)
/
HZ
;
info
->
tcpi_last_ack_recv
=
((
now
-
tp
->
rcv_tstamp
)
*
1000
)
/
HZ
;
info
->
tcpi_last_data_sent
=
jiffies_to_msecs
(
now
-
tp
->
lsndtime
)
;
info
->
tcpi_last_data_recv
=
jiffies_to_msecs
(
now
-
tp
->
ack
.
lrcvtime
)
;
info
->
tcpi_last_ack_recv
=
jiffies_to_msecs
(
now
-
tp
->
rcv_tstamp
)
;
info
->
tcpi_pmtu
=
tp
->
pmtu_cookie
;
info
->
tcpi_rcv_ssthresh
=
tp
->
rcv_ssthresh
;
info
->
tcpi_rtt
=
((
1000000
*
tp
->
srtt
)
/
HZ
)
>>
3
;
info
->
tcpi_rttvar
=
((
1000000
*
tp
->
mdev
)
/
HZ
)
>>
2
;
info
->
tcpi_rtt
=
jiffies_to_usecs
(
tp
->
srtt
)
>>
3
;
info
->
tcpi_rttvar
=
jiffies_to_usecs
(
tp
->
mdev
)
>>
2
;
info
->
tcpi_snd_ssthresh
=
tp
->
snd_ssthresh
;
info
->
tcpi_snd_cwnd
=
tp
->
snd_cwnd
;
info
->
tcpi_advmss
=
tp
->
advmss
;
info
->
tcpi_reordering
=
tp
->
reordering
;
info
->
tcpi_rcv_rtt
=
((
1000000
*
tp
->
rcv_rtt_est
.
rtt
)
/
HZ
)
>>
3
;
info
->
tcpi_rcv_rtt
=
jiffies_to_usecs
(
tp
->
rcv_rtt_est
.
rtt
)
>>
3
;
info
->
tcpi_rcv_space
=
tp
->
rcvq_space
.
space
;
}
...
...
@@ -116,7 +116,8 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
if
(
ext
&
(
1
<<
(
TCPDIAG_INFO
-
1
)))
info
=
TCPDIAG_PUT
(
skb
,
TCPDIAG_INFO
,
sizeof
(
*
info
));
if
(
tcp_is_vegas
(
tp
)
&&
(
ext
&
(
1
<<
(
TCPDIAG_VEGASINFO
-
1
))))
if
((
tcp_is_westwood
(
tp
)
||
tcp_is_vegas
(
tp
))
&&
(
ext
&
(
1
<<
(
TCPDIAG_VEGASINFO
-
1
))))
vinfo
=
TCPDIAG_PUT
(
skb
,
TCPDIAG_VEGASINFO
,
sizeof
(
*
vinfo
));
}
r
->
tcpdiag_family
=
sk
->
sk_family
;
...
...
@@ -209,10 +210,17 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
tcp_get_info
(
sk
,
info
);
if
(
vinfo
)
{
if
(
tcp_is_vegas
(
tp
))
{
vinfo
->
tcpv_enabled
=
tp
->
vegas
.
doing_vegas_now
;
vinfo
->
tcpv_rttcnt
=
tp
->
vegas
.
cntRTT
;
vinfo
->
tcpv_rtt
=
tp
->
vegas
.
baseRTT
;
vinfo
->
tcpv_minrtt
=
tp
->
vegas
.
minRTT
;
vinfo
->
tcpv_rtt
=
jiffies_to_usecs
(
tp
->
vegas
.
baseRTT
);
vinfo
->
tcpv_minrtt
=
jiffies_to_usecs
(
tp
->
vegas
.
minRTT
);
}
else
{
vinfo
->
tcpv_enabled
=
0
;
vinfo
->
tcpv_rttcnt
=
0
;
vinfo
->
tcpv_rtt
=
jiffies_to_usecs
(
tp
->
westwood
.
rtt
);
vinfo
->
tcpv_minrtt
=
jiffies_to_usecs
(
tp
->
westwood
.
rtt_min
);
}
}
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
...
...
net/ipv4/tcp_input.c
View file @
27df0cf8
...
...
@@ -555,17 +555,20 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_opt *tp, struct sk_b
tcp_grow_window
(
sk
,
tp
,
skb
);
}
/*
Set up a new TCP connection, depending on whether it should be
*
using Vegas or not
.
/*
When starting a new connection, pin down the current choice of
*
congestion algorithm
.
*/
void
tcp_
vegas
_init
(
struct
tcp_opt
*
tp
)
void
tcp_
ca
_init
(
struct
tcp_opt
*
tp
)
{
if
(
sysctl_tcp_vegas_cong_avoid
)
{
tp
->
vegas
.
do_vegas
=
1
;
if
(
sysctl_tcp_westwood
)
tp
->
adv_cong
=
TCP_WESTWOOD
;
else
if
(
sysctl_tcp_bic
)
tp
->
adv_cong
=
TCP_BIC
;
else
if
(
sysctl_tcp_vegas_cong_avoid
)
{
tp
->
adv_cong
=
TCP_VEGAS
;
tp
->
vegas
.
baseRTT
=
0x7fffffff
;
tcp_vegas_enable
(
tp
);
}
else
tcp_vegas_disable
(
tp
);
}
}
/* Do RTT sampling needed for Vegas.
...
...
@@ -2039,7 +2042,7 @@ tcp_ack_update_rtt(struct tcp_opt *tp, int flag, s32 seq_rtt)
static
inline
__u32
bictcp_cwnd
(
struct
tcp_opt
*
tp
)
{
/* orignal Reno behaviour */
if
(
!
sysctl_tcp_bic
)
if
(
!
tcp_is_bic
(
tp
)
)
return
tp
->
snd_cwnd
;
if
(
tp
->
bictcp
.
last_cwnd
==
tp
->
snd_cwnd
&&
...
...
@@ -2617,18 +2620,16 @@ static void westwood_filter(struct sock *sk, __u32 delta)
* WESTWOOD_RTT_MIN minimum bound since we could be on a LAN!
*/
static
inline
__u32
westwood_update_rttmin
(
struct
sock
*
sk
)
static
inline
__u32
westwood_update_rttmin
(
const
struct
sock
*
sk
)
{
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
const
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
__u32
rttmin
=
tp
->
westwood
.
rtt_min
;
if
(
tp
->
westwood
.
rtt
==
0
)
return
(
rttmin
);
if
(
tp
->
westwood
.
rtt
<
tp
->
westwood
.
rtt_min
||
!
rttmin
)
if
(
tp
->
westwood
.
rtt
!=
0
&&
(
tp
->
westwood
.
rtt
<
tp
->
westwood
.
rtt_min
||
!
rttmin
))
rttmin
=
tp
->
westwood
.
rtt
;
return
(
rttmin
)
;
return
rttmin
;
}
/*
...
...
@@ -2636,11 +2637,11 @@ static inline __u32 westwood_update_rttmin(struct sock *sk)
* Evaluate increases for dk.
*/
static
inline
__u32
westwood_acked
(
struct
sock
*
sk
)
static
inline
__u32
westwood_acked
(
const
struct
sock
*
sk
)
{
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
const
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
return
((
tp
->
snd_una
)
-
(
tp
->
westwood
.
snd_una
))
;
return
tp
->
snd_una
-
tp
->
westwood
.
snd_una
;
}
/*
...
...
@@ -2652,9 +2653,9 @@ static inline __u32 westwood_acked(struct sock *sk)
* window, 1 if the sample has to be considered in the next window.
*/
static
int
westwood_new_window
(
struct
sock
*
sk
)
static
int
westwood_new_window
(
const
struct
sock
*
sk
)
{
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
const
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
__u32
left_bound
;
__u32
rtt
;
int
ret
=
0
;
...
...
@@ -2688,14 +2689,13 @@ static void __westwood_update_window(struct sock *sk, __u32 now)
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
__u32
delta
=
now
-
tp
->
westwood
.
rtt_win_sx
;
if
(
!
delta
)
return
;
if
(
delta
)
{
if
(
tp
->
westwood
.
rtt
)
westwood_filter
(
sk
,
delta
);
tp
->
westwood
.
bk
=
0
;
tp
->
westwood
.
rtt_win_sx
=
tcp_time_stamp
;
}
}
...
...
@@ -2739,7 +2739,7 @@ static void westwood_dupack_update(struct sock *sk)
static
inline
int
westwood_may_change_cumul
(
struct
tcp_opt
*
tp
)
{
return
(
(
tp
->
westwood
.
cumul_ack
)
>
tp
->
mss_cache_std
);
return
(
tp
->
westwood
.
cumul_ack
>
tp
->
mss_cache_std
);
}
static
inline
void
westwood_partial_update
(
struct
tcp_opt
*
tp
)
...
...
@@ -2760,7 +2760,7 @@ static inline void westwood_complete_update(struct tcp_opt *tp)
* delayed or partial acks.
*/
static
__u32
westwood_acked_count
(
struct
sock
*
sk
)
static
inline
__u32
westwood_acked_count
(
struct
sock
*
sk
)
{
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
...
...
@@ -2774,7 +2774,7 @@ static __u32 westwood_acked_count(struct sock *sk)
if
(
westwood_may_change_cumul
(
tp
))
{
/* Partial or delayed ack */
if
(
(
tp
->
westwood
.
accounted
)
>=
(
tp
->
westwood
.
cumul_ack
)
)
if
(
tp
->
westwood
.
accounted
>=
tp
->
westwood
.
cumul_ack
)
westwood_partial_update
(
tp
);
else
westwood_complete_update
(
tp
);
...
...
net/ipv4/tcp_minisocks.c
View file @
27df0cf8
...
...
@@ -841,7 +841,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
if
(
newtp
->
ecn_flags
&
TCP_ECN_OK
)
newsk
->
sk_no_largesend
=
1
;
tcp_vegas_init
(
newtp
);
tcp_ca_init
(
newtp
);
TCP_INC_STATS_BH
(
TCP_MIB_PASSIVEOPENS
);
}
return
newsk
;
...
...
net/ipv4/tcp_output.c
View file @
27df0cf8
...
...
@@ -1359,7 +1359,7 @@ static inline void tcp_connect_init(struct sock *sk)
tp
->
window_clamp
=
dst_metric
(
dst
,
RTAX_WINDOW
);
tp
->
advmss
=
dst_metric
(
dst
,
RTAX_ADVMSS
);
tcp_initialize_rcv_mss
(
sk
);
tcp_
vegas
_init
(
tp
);
tcp_
ca
_init
(
tp
);
tcp_select_initial_window
(
tcp_full_space
(
sk
),
tp
->
advmss
-
(
tp
->
ts_recent_stamp
?
tp
->
tcp_header_len
-
sizeof
(
struct
tcphdr
)
:
0
),
...
...
@@ -1411,7 +1411,7 @@ int tcp_connect(struct sock *sk)
TCP_SKB_CB
(
buff
)
->
end_seq
=
tp
->
write_seq
;
tp
->
snd_nxt
=
tp
->
write_seq
;
tp
->
pushed_seq
=
tp
->
write_seq
;
tcp_
vegas
_init
(
tp
);
tcp_
ca
_init
(
tp
);
/* Send it off. */
TCP_SKB_CB
(
buff
)
->
when
=
tcp_time_stamp
;
...
...
net/ipv6/addrconf.c
View file @
27df0cf8
...
...
@@ -128,6 +128,9 @@ static struct timer_list addr_chk_timer =
TIMER_INITIALIZER
(
addrconf_verify
,
0
,
0
);
static
spinlock_t
addrconf_verify_lock
=
SPIN_LOCK_UNLOCKED
;
static
void
addrconf_join_anycast
(
struct
inet6_ifaddr
*
ifp
);
static
void
addrconf_leave_anycast
(
struct
inet6_ifaddr
*
ifp
);
static
int
addrconf_ifdown
(
struct
net_device
*
dev
,
int
how
);
static
void
addrconf_dad_start
(
struct
inet6_ifaddr
*
ifp
,
int
flags
);
...
...
@@ -419,32 +422,27 @@ static void dev_forward_change(struct inet6_dev *idev)
ipv6_dev_mc_dec
(
dev
,
&
addr
);
}
for
(
ifa
=
idev
->
addr_list
;
ifa
;
ifa
=
ifa
->
if_next
)
{
ipv6_addr_prefix
(
&
addr
,
&
ifa
->
addr
,
ifa
->
prefix_len
);
if
(
ipv6_addr_any
(
&
addr
))
continue
;
if
(
idev
->
cnf
.
forwarding
)
ipv6_dev_ac_inc
(
idev
->
dev
,
&
addr
);
addrconf_join_anycast
(
ifa
);
else
ipv6_dev_ac_dec
(
idev
->
dev
,
&
addr
);
addrconf_leave_anycast
(
ifa
);
}
}
static
void
addrconf_forward_change
(
struct
inet6_dev
*
idev
)
static
void
addrconf_forward_change
(
void
)
{
struct
net_device
*
dev
;
if
(
idev
)
{
dev_forward_change
(
idev
);
return
;
}
struct
inet6_dev
*
idev
;
read_lock
(
&
dev_base_lock
);
for
(
dev
=
dev_base
;
dev
;
dev
=
dev
->
next
)
{
read_lock
(
&
addrconf_lock
);
idev
=
__in6_dev_get
(
dev
);
if
(
idev
)
{
int
changed
=
(
!
idev
->
cnf
.
forwarding
)
^
(
!
ipv6_devconf
.
forwarding
);
idev
->
cnf
.
forwarding
=
ipv6_devconf
.
forwarding
;
if
(
changed
)
dev_forward_change
(
idev
);
}
read_unlock
(
&
addrconf_lock
);
...
...
@@ -1062,17 +1060,34 @@ void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
ipv6_dev_mc_inc
(
dev
,
&
maddr
);
}
void
addrconf_leave_solict
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
)
void
addrconf_leave_solict
(
struct
inet6_dev
*
i
dev
,
struct
in6_addr
*
addr
)
{
struct
in6_addr
maddr
;
if
(
dev
->
flags
&
(
IFF_LOOPBACK
|
IFF_NOARP
))
if
(
idev
->
dev
->
flags
&
(
IFF_LOOPBACK
|
IFF_NOARP
))
return
;
addrconf_addr_solict_mult
(
addr
,
&
maddr
);
ipv6_dev_mc_dec
(
dev
,
&
maddr
);
__ipv6_dev_mc_dec
(
idev
,
&
maddr
);
}
void
addrconf_join_anycast
(
struct
inet6_ifaddr
*
ifp
)
{
struct
in6_addr
addr
;
ipv6_addr_prefix
(
&
addr
,
&
ifp
->
addr
,
ifp
->
prefix_len
);
if
(
ipv6_addr_any
(
&
addr
))
return
;
ipv6_dev_ac_inc
(
ifp
->
idev
->
dev
,
&
addr
);
}
void
addrconf_leave_anycast
(
struct
inet6_ifaddr
*
ifp
)
{
struct
in6_addr
addr
;
ipv6_addr_prefix
(
&
addr
,
&
ifp
->
addr
,
ifp
->
prefix_len
);
if
(
ipv6_addr_any
(
&
addr
))
return
;
__ipv6_dev_ac_dec
(
ifp
->
idev
,
&
addr
);
}
static
int
ipv6_generate_eui64
(
u8
*
eui
,
struct
net_device
*
dev
)
{
...
...
@@ -2225,14 +2240,6 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
addrconf_mod_timer
(
ifp
,
AC_RS
,
ifp
->
idev
->
cnf
.
rtr_solicit_interval
);
spin_unlock_bh
(
&
ifp
->
lock
);
}
if
(
ifp
->
idev
->
cnf
.
forwarding
)
{
struct
in6_addr
addr
;
ipv6_addr_prefix
(
&
addr
,
&
ifp
->
addr
,
ifp
->
prefix_len
);
if
(
!
ipv6_addr_any
(
&
addr
))
ipv6_dev_ac_inc
(
ifp
->
idev
->
dev
,
&
addr
);
}
}
#ifdef CONFIG_PROC_FS
...
...
@@ -2994,16 +3001,13 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
dst_hold
(
&
ifp
->
rt
->
u
.
dst
);
if
(
ip6_ins_rt
(
ifp
->
rt
,
NULL
,
NULL
))
dst_release
(
&
ifp
->
rt
->
u
.
dst
);
if
(
ifp
->
idev
->
cnf
.
forwarding
)
addrconf_join_anycast
(
ifp
);
break
;
case
RTM_DELADDR
:
addrconf_leave_solict
(
ifp
->
idev
->
dev
,
&
ifp
->
addr
);
if
(
ifp
->
idev
->
cnf
.
forwarding
)
{
struct
in6_addr
addr
;
ipv6_addr_prefix
(
&
addr
,
&
ifp
->
addr
,
ifp
->
prefix_len
);
if
(
!
ipv6_addr_any
(
&
addr
))
ipv6_dev_ac_dec
(
ifp
->
idev
->
dev
,
&
addr
);
}
if
(
ifp
->
idev
->
cnf
.
forwarding
)
addrconf_leave_anycast
(
ifp
);
addrconf_leave_solict
(
ifp
->
idev
,
&
ifp
->
addr
);
dst_hold
(
&
ifp
->
rt
->
u
.
dst
);
if
(
ip6_del_rt
(
ifp
->
rt
,
NULL
,
NULL
))
dst_free
(
&
ifp
->
rt
->
u
.
dst
);
...
...
@@ -3025,18 +3029,18 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
ret
=
proc_dointvec
(
ctl
,
write
,
filp
,
buffer
,
lenp
,
ppos
);
if
(
write
&&
*
valp
!=
val
&&
valp
!=
&
ipv6_devconf_dflt
.
forwarding
)
{
struct
inet6_dev
*
idev
=
NULL
;
if
(
write
&&
valp
!=
&
ipv6_devconf_dflt
.
forwarding
)
{
if
(
valp
!=
&
ipv6_devconf
.
forwarding
)
{
idev
=
(
struct
inet6_dev
*
)
ctl
->
extra1
;
if
((
!*
valp
)
^
(
!
val
))
{
struct
inet6_dev
*
idev
=
(
struct
inet6_dev
*
)
ctl
->
extra1
;
if
(
idev
==
NULL
)
return
ret
;
}
else
dev_forward_change
(
idev
);
}
}
else
{
ipv6_devconf_dflt
.
forwarding
=
ipv6_devconf
.
forwarding
;
addrconf_forward_change
(
idev
);
addrconf_forward_change
();
}
if
(
*
valp
)
rt6_purge_dflt_routers
(
0
);
}
...
...
@@ -3077,15 +3081,19 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
}
if
(
valp
!=
&
ipv6_devconf_dflt
.
forwarding
)
{
struct
inet6_dev
*
idev
;
if
(
valp
!=
&
ipv6_devconf
.
forwarding
)
{
idev
=
(
struct
inet6_dev
*
)
table
->
extra1
;
struct
inet6_dev
*
idev
=
(
struct
inet6_dev
*
)
table
->
extra1
;
int
changed
;
if
(
unlikely
(
idev
==
NULL
))
return
-
ENODEV
;
}
else
idev
=
NULL
;
changed
=
(
!*
valp
)
^
(
!
new
);
*
valp
=
new
;
if
(
changed
)
dev_forward_change
(
idev
);
}
else
{
*
valp
=
new
;
addrconf_forward_change
(
idev
);
addrconf_forward_change
();
}
if
(
*
valp
)
rt6_purge_dflt_routers
(
0
);
...
...
net/ipv6/anycast.c
View file @
27df0cf8
...
...
@@ -377,15 +377,10 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
/*
* device anycast group decrement
*/
int
ipv6_dev_ac_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
)
int
__ipv6_dev_ac_dec
(
struct
inet6_dev
*
i
dev
,
struct
in6_addr
*
addr
)
{
struct
inet6_dev
*
idev
;
struct
ifacaddr6
*
aca
,
*
prev_aca
;
idev
=
in6_dev_get
(
dev
);
if
(
idev
==
NULL
)
return
-
ENODEV
;
write_lock_bh
(
&
idev
->
lock
);
prev_aca
=
NULL
;
for
(
aca
=
idev
->
ac_list
;
aca
;
aca
=
aca
->
aca_next
)
{
...
...
@@ -395,12 +390,10 @@ int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
}
if
(
!
aca
)
{
write_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
return
-
ENOENT
;
}
if
(
--
aca
->
aca_users
>
0
)
{
write_unlock_bh
(
&
idev
->
lock
);
in6_dev_put
(
idev
);
return
0
;
}
if
(
prev_aca
)
...
...
@@ -408,7 +401,7 @@ int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
else
idev
->
ac_list
=
aca
->
aca_next
;
write_unlock_bh
(
&
idev
->
lock
);
addrconf_leave_solict
(
dev
,
&
aca
->
aca_addr
);
addrconf_leave_solict
(
i
dev
,
&
aca
->
aca_addr
);
dst_hold
(
&
aca
->
aca_rt
->
u
.
dst
);
if
(
ip6_del_rt
(
aca
->
aca_rt
,
NULL
,
NULL
))
...
...
@@ -417,10 +410,20 @@ int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
dst_release
(
&
aca
->
aca_rt
->
u
.
dst
);
aca_put
(
aca
);
in6_dev_put
(
idev
);
return
0
;
}
int
ipv6_dev_ac_dec
(
struct
net_device
*
dev
,
struct
in6_addr
*
addr
)
{
int
ret
;
struct
inet6_dev
*
idev
=
in6_dev_get
(
dev
);
if
(
idev
==
NULL
)
return
-
ENODEV
;
ret
=
__ipv6_dev_ac_dec
(
idev
,
addr
);
in6_dev_put
(
idev
);
return
ret
;
}
/*
* check if the interface has this anycast address
*/
...
...
net/ipv6/mcast.c
View file @
27df0cf8
...
...
@@ -128,6 +128,8 @@ static rwlock_t ipv6_sk_mc_lock = RW_LOCK_UNLOCKED;
static
struct
socket
*
igmp6_socket
;
int
__ipv6_dev_mc_dec
(
struct
inet6_dev
*
idev
,
struct
in6_addr
*
addr
);
static
void
igmp6_join_group
(
struct
ifmcaddr6
*
ma
);
static
void
igmp6_leave_group
(
struct
ifmcaddr6
*
ma
);
static
void
igmp6_timer_handler
(
unsigned
long
data
);
...
...
@@ -256,9 +258,9 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
if
(
idev
)
{
(
void
)
ip6_mc_leave_src
(
sk
,
mc_lst
,
idev
);
__ipv6_dev_mc_dec
(
idev
,
&
mc_lst
->
addr
);
in6_dev_put
(
idev
);
}
ipv6_dev_mc_dec
(
dev
,
&
mc_lst
->
addr
);
dev_put
(
dev
);
}
sock_kfree_s
(
sk
,
mc_lst
,
sizeof
(
*
mc_lst
));
...
...
@@ -322,9 +324,9 @@ void ipv6_sock_mc_close(struct sock *sk)
if
(
idev
)
{
(
void
)
ip6_mc_leave_src
(
sk
,
mc_lst
,
idev
);
__ipv6_dev_mc_dec
(
idev
,
&
mc_lst
->
addr
);
in6_dev_put
(
idev
);
}
ipv6_dev_mc_dec
(
dev
,
&
mc_lst
->
addr
);
dev_put
(
dev
);
}
...
...
@@ -870,7 +872,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
/*
* device multicast group del
*/
static
int
__ipv6_dev_mc_dec
(
struct
net_device
*
dev
,
struct
inet6_dev
*
idev
,
struct
in6_addr
*
addr
)
int
__ipv6_dev_mc_dec
(
struct
inet6_dev
*
idev
,
struct
in6_addr
*
addr
)
{
struct
ifmcaddr6
*
ma
,
**
map
;
...
...
@@ -903,7 +905,7 @@ int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr)
if
(
!
idev
)
return
-
ENODEV
;
err
=
__ipv6_dev_mc_dec
(
dev
,
idev
,
addr
);
err
=
__ipv6_dev_mc_dec
(
idev
,
addr
);
in6_dev_put
(
idev
);
...
...
@@ -2108,7 +2110,12 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
* addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will
* fail.
*/
__ipv6_dev_mc_dec
(
idev
->
dev
,
idev
,
&
maddr
);
__ipv6_dev_mc_dec
(
idev
,
&
maddr
);
if
(
idev
->
cnf
.
forwarding
)
{
ipv6_addr_all_routers
(
&
maddr
);
__ipv6_dev_mc_dec
(
idev
,
&
maddr
);
}
write_lock_bh
(
&
idev
->
lock
);
while
((
i
=
idev
->
mc_list
)
!=
NULL
)
{
...
...
net/ipv6/ndisc.c
View file @
27df0cf8
...
...
@@ -66,6 +66,7 @@
#include <linux/if_arp.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/jhash.h>
#include <net/sock.h>
#include <net/snmp.h>
...
...
@@ -270,15 +271,14 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
static
u32
ndisc_hash
(
const
void
*
pkey
,
const
struct
net_device
*
dev
)
{
u32
hash_val
;
const
u32
*
p32
=
pkey
;
u32
addr_hash
,
i
;
hash_val
=
*
(
u32
*
)(
pkey
+
sizeof
(
struct
in6_addr
)
-
4
);
hash_val
^=
(
hash_val
>>
16
);
hash_val
^=
hash_val
>>
8
;
hash_val
^=
hash_val
>>
3
;
hash_val
=
(
hash_val
^
dev
->
ifindex
)
&
NEIGH_HASHMASK
;
addr_hash
=
0
;
for
(
i
=
0
;
i
<
(
sizeof
(
struct
in6_addr
)
/
sizeof
(
u32
));
i
++
)
addr_hash
^=
*
p32
++
;
return
hash_val
;
return
jhash_2words
(
addr_hash
,
dev
->
ifindex
,
nd_tbl
.
hash_rnd
)
;
}
static
int
ndisc_constructor
(
struct
neighbour
*
neigh
)
...
...
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