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
48e24acb
Commit
48e24acb
authored
Aug 27, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge davem@nuts.davemloft.net:/disk1/BK/net-2.6
into kernel.bkbits.net:/home/davem/net-2.6
parents
0092e993
4f6aeb92
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
433 additions
and
649 deletions
+433
-649
include/linux/netfilter_ipv6/ip6t_REJECT.h
include/linux/netfilter_ipv6/ip6t_REJECT.h
+0
-16
include/linux/netlink.h
include/linux/netlink.h
+0
-7
include/linux/pkt_sched.h
include/linux/pkt_sched.h
+25
-0
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arp_tables.c
+7
-7
net/ipv6/datagram.c
net/ipv6/datagram.c
+12
-1
net/ipv6/ip6_output.c
net/ipv6/ip6_output.c
+0
-4
net/ipv6/raw.c
net/ipv6/raw.c
+10
-1
net/ipv6/tcp_ipv6.c
net/ipv6/tcp_ipv6.c
+59
-3
net/ipv6/udp.c
net/ipv6/udp.c
+10
-1
net/netlink/af_netlink.c
net/netlink/af_netlink.c
+73
-4
net/packet/af_packet.c
net/packet/af_packet.c
+19
-13
net/sched/sch_netem.c
net/sched/sch_netem.c
+218
-592
No files found.
include/linux/netfilter_ipv6/ip6t_REJECT.h
deleted
100644 → 0
View file @
0092e993
#ifndef _IP6T_REJECT_H
#define _IP6T_REJECT_H
enum
ip6t_reject_with
{
IP6T_ICMP_NET_UNREACHABLE
,
IP6T_ICMP_HOST_UNREACHABLE
,
IP6T_ICMP_PROT_UNREACHABLE
,
IP6T_ICMP_PORT_UNREACHABLE
,
IP6T_ICMP_ECHOREPLY
};
struct
ip6t_reject_info
{
enum
ip6t_reject_with
with
;
/* reject type */
};
#endif
/*_IPT_REJECT_H*/
include/linux/netlink.h
View file @
48e24acb
...
...
@@ -134,13 +134,6 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
void
netlink_detachskb
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
int
netlink_sendskb
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
protocol
);
/* finegrained unicast helpers: */
struct
sock
*
netlink_getsockbypid
(
struct
sock
*
ssk
,
u32
pid
);
struct
sock
*
netlink_getsockbyfilp
(
struct
file
*
filp
);
int
netlink_attachskb
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
nonblock
,
long
timeo
);
void
netlink_detachskb
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
int
netlink_sendskb
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
protocol
);
/*
* skb should fit one page. This choice is good for headerless malloc.
*
...
...
include/linux/pkt_sched.h
View file @
48e24acb
...
...
@@ -402,6 +402,16 @@ enum {
#define TCA_ATM_MAX TCA_ATM_STATE
/* Network emulator */
enum
{
TCA_NETEM_UNSPEC
,
TCA_NETEM_CORR
,
TCA_NETEM_DELAY_DIST
,
};
#define TCA_NETEM_MAX TCA_NETEM_DELAY_DIST
struct
tc_netem_qopt
{
__u32
latency
;
/* added delay (us) */
...
...
@@ -411,4 +421,19 @@ struct tc_netem_qopt
__u32
duplicate
;
/* random packet dup (0=none ~0=100%) */
__u32
jitter
;
/* random jitter in latency (us) */
};
struct
tc_netem_corr
{
__u32
delay_corr
;
/* delay correlation */
__u32
loss_corr
;
/* packet loss correlation */
__u32
dup_corr
;
/* duplicate correlation */
};
struct
tc_netem_dist
{
__u32
size
;
/* table size */
__u32
factor
;
/* table scaling factor */
__s16
data
[
0
];
/* distribution table values */
};
#endif
net/ipv4/netfilter/arp_tables.c
View file @
48e24acb
...
...
@@ -106,7 +106,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
{
char
*
arpptr
=
(
char
*
)(
arphdr
+
1
);
char
*
src_devaddr
,
*
tgt_devaddr
;
u32
*
src_ipaddr
,
*
tgt_ipaddr
;
u32
src_ipaddr
,
tgt_ipaddr
;
int
i
,
ret
;
#define FWINV(bool,invflg) ((bool) ^ !!(arpinfo->invflags & invflg))
...
...
@@ -145,11 +145,11 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
src_devaddr
=
arpptr
;
arpptr
+=
dev
->
addr_len
;
src_ipaddr
=
(
u32
*
)
arpptr
;
memcpy
(
&
src_ipaddr
,
arpptr
,
sizeof
(
u32
))
;
arpptr
+=
sizeof
(
u32
);
tgt_devaddr
=
arpptr
;
arpptr
+=
dev
->
addr_len
;
tgt_ipaddr
=
(
u32
*
)
arpptr
;
memcpy
(
&
tgt_ipaddr
,
arpptr
,
sizeof
(
u32
))
;
if
(
FWINV
(
arp_devaddr_compare
(
&
arpinfo
->
src_devaddr
,
src_devaddr
,
dev
->
addr_len
),
ARPT_INV_SRCDEVADDR
)
||
...
...
@@ -160,19 +160,19 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
return
0
;
}
if
(
FWINV
((
(
*
src_ipaddr
)
&
arpinfo
->
smsk
.
s_addr
)
!=
arpinfo
->
src
.
s_addr
,
if
(
FWINV
((
src_ipaddr
&
arpinfo
->
smsk
.
s_addr
)
!=
arpinfo
->
src
.
s_addr
,
ARPT_INV_SRCIP
)
||
FWINV
(((
(
*
tgt_ipaddr
)
&
arpinfo
->
tmsk
.
s_addr
)
!=
arpinfo
->
tgt
.
s_addr
),
FWINV
(((
tgt_ipaddr
&
arpinfo
->
tmsk
.
s_addr
)
!=
arpinfo
->
tgt
.
s_addr
),
ARPT_INV_TGTIP
))
{
dprintf
(
"Source or target IP address mismatch.
\n
"
);
dprintf
(
"SRC: %u.%u.%u.%u. Mask: %u.%u.%u.%u. Target: %u.%u.%u.%u.%s
\n
"
,
NIPQUAD
(
*
src_ipaddr
),
NIPQUAD
(
src_ipaddr
),
NIPQUAD
(
arpinfo
->
smsk
.
s_addr
),
NIPQUAD
(
arpinfo
->
src
.
s_addr
),
arpinfo
->
invflags
&
ARPT_INV_SRCIP
?
" (INV)"
:
""
);
dprintf
(
"TGT: %u.%u.%u.%u Mask: %u.%u.%u.%u Target: %u.%u.%u.%u.%s
\n
"
,
NIPQUAD
(
*
tgt_ipaddr
),
NIPQUAD
(
tgt_ipaddr
),
NIPQUAD
(
arpinfo
->
tmsk
.
s_addr
),
NIPQUAD
(
arpinfo
->
tgt
.
s_addr
),
arpinfo
->
invflags
&
ARPT_INV_TGTIP
?
" (INV)"
:
""
);
...
...
net/ipv6/datagram.c
View file @
48e24acb
...
...
@@ -38,7 +38,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct
sockaddr_in6
*
usin
=
(
struct
sockaddr_in6
*
)
uaddr
;
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
in6_addr
*
daddr
;
struct
in6_addr
*
daddr
,
*
final_p
=
NULL
,
final
;
struct
dst_entry
*
dst
;
struct
flowi
fl
;
struct
ip6_flowlabel
*
flowlabel
=
NULL
;
...
...
@@ -157,16 +157,27 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
if
(
flowlabel
)
{
if
(
flowlabel
->
opt
&&
flowlabel
->
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
flowlabel
->
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
}
else
if
(
np
->
opt
&&
np
->
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
np
->
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
out
;
if
(
final_p
)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
final_p
);
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
{
dst_release
(
dst
);
goto
out
;
}
/* source address lookup done in ip6_dst_lookup */
...
...
net/ipv6/ip6_output.c
View file @
48e24acb
...
...
@@ -796,10 +796,6 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
goto
out_err_release
;
}
}
if
((
err
=
xfrm_lookup
(
dst
,
fl
,
sk
,
0
))
<
0
)
{
err
=
-
ENETUNREACH
;
goto
out_err_release
;
}
return
0
;
...
...
net/ipv6/raw.c
View file @
48e24acb
...
...
@@ -606,7 +606,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
{
struct
ipv6_txoptions
opt_space
;
struct
sockaddr_in6
*
sin6
=
(
struct
sockaddr_in6
*
)
msg
->
msg_name
;
struct
in6_addr
*
daddr
;
struct
in6_addr
*
daddr
,
*
final_p
=
NULL
,
final
;
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
raw6_opt
*
raw_opt
=
raw6_sk
(
sk
);
...
...
@@ -729,7 +729,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
/* merge ip6_build_xmit from ip6_output */
if
(
opt
&&
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
if
(
!
fl
.
oif
&&
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
...
...
@@ -738,6 +740,13 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
out
;
if
(
final_p
)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
final_p
);
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
{
dst_release
(
dst
);
goto
out
;
}
if
(
hlimit
<
0
)
{
if
(
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
...
...
net/ipv6/tcp_ipv6.c
View file @
48e24acb
...
...
@@ -549,7 +549,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
tcp_opt
*
tp
=
tcp_sk
(
sk
);
struct
in6_addr
*
saddr
=
NULL
;
struct
in6_addr
*
saddr
=
NULL
,
*
final_p
=
NULL
,
final
;
struct
flowi
fl
;
struct
dst_entry
*
dst
;
int
addr_type
;
...
...
@@ -666,13 +666,21 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if
(
np
->
opt
&&
np
->
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
np
->
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
failure
;
if
(
final_p
)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
final_p
);
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
{
dst_release
(
dst
);
goto
failure
;
}
if
(
saddr
==
NULL
)
{
saddr
=
&
fl
.
fl6_src
;
...
...
@@ -793,6 +801,12 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
sk
->
sk_err_soft
=
-
err
;
goto
out
;
}
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
{
sk
->
sk_err_soft
=
-
err
;
goto
out
;
}
}
else
dst_hold
(
dst
);
...
...
@@ -863,6 +877,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
sk_buff
*
skb
;
struct
ipv6_txoptions
*
opt
=
NULL
;
struct
in6_addr
*
final_p
=
NULL
,
final
;
struct
flowi
fl
;
int
err
=
-
1
;
...
...
@@ -888,12 +903,18 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
if
(
opt
&&
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
done
;
if
(
final_p
)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
final_p
);
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
goto
done
;
}
skb
=
tcp_make_synack
(
sk
,
dst
,
req
);
...
...
@@ -1021,6 +1042,12 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
/* sk = NULL, but it is safe for now. RST socket required. */
if
(
!
ip6_dst_lookup
(
NULL
,
&
buff
->
dst
,
&
fl
))
{
if
((
xfrm_lookup
(
&
buff
->
dst
,
&
fl
,
NULL
,
0
))
<
0
)
{
dst_release
(
buff
->
dst
);
return
;
}
ip6_xmit
(
NULL
,
buff
,
&
fl
,
NULL
,
0
);
TCP_INC_STATS_BH
(
TCP_MIB_OUTSEGS
);
TCP_INC_STATS_BH
(
TCP_MIB_OUTRSTS
);
...
...
@@ -1082,6 +1109,10 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
fl
.
fl_ip_sport
=
t1
->
source
;
if
(
!
ip6_dst_lookup
(
NULL
,
&
buff
->
dst
,
&
fl
))
{
if
((
xfrm_lookup
(
&
buff
->
dst
,
&
fl
,
NULL
,
0
))
<
0
)
{
dst_release
(
buff
->
dst
);
return
;
}
ip6_xmit
(
NULL
,
buff
,
&
fl
,
NULL
,
0
);
TCP_INC_STATS_BH
(
TCP_MIB_OUTSEGS
);
return
;
...
...
@@ -1313,6 +1344,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
}
if
(
dst
==
NULL
)
{
struct
in6_addr
*
final_p
=
NULL
,
final
;
struct
flowi
fl
;
memset
(
&
fl
,
0
,
sizeof
(
fl
));
...
...
@@ -1320,7 +1352,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
&
req
->
af
.
v6_req
.
rmt_addr
);
if
(
opt
&&
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
ipv6_addr_copy
(
&
fl
.
fl6_src
,
&
req
->
af
.
v6_req
.
loc_addr
);
fl
.
oif
=
sk
->
sk_bound_dev_if
;
...
...
@@ -1329,6 +1363,12 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if
(
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
))
goto
out
;
if
(
final_p
)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
final_p
);
if
((
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
goto
out
;
}
newsk
=
tcp_create_openreq_child
(
sk
,
req
,
skb
);
...
...
@@ -1710,6 +1750,7 @@ static int tcp_v6_rebuild_header(struct sock *sk)
if
(
dst
==
NULL
)
{
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
in6_addr
*
final_p
=
NULL
,
final
;
struct
flowi
fl
;
memset
(
&
fl
,
0
,
sizeof
(
fl
));
...
...
@@ -1723,15 +1764,24 @@ static int tcp_v6_rebuild_header(struct sock *sk)
if
(
np
->
opt
&&
np
->
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
np
->
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
.
fl6_dst
);
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
{
sk
->
sk_route_caps
=
0
;
return
err
;
}
if
(
final_p
)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
final_p
);
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
{
sk
->
sk_err_soft
=
-
err
;
dst_release
(
dst
);
return
err
;
}
ip6_dst_store
(
sk
,
dst
,
NULL
);
sk
->
sk_route_caps
=
dst
->
dev
->
features
&
...
...
@@ -1775,6 +1825,12 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
return
err
;
}
if
((
err
=
xfrm_lookup
(
&
dst
,
&
fl
,
sk
,
0
))
<
0
)
{
sk
->
sk_route_caps
=
0
;
dst_release
(
dst
);
return
err
;
}
ip6_dst_store
(
sk
,
dst
,
NULL
);
sk
->
sk_route_caps
=
dst
->
dev
->
features
&
~
(
NETIF_F_IP_CSUM
|
NETIF_F_TSO
);
...
...
net/ipv6/udp.c
View file @
48e24acb
...
...
@@ -627,7 +627,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
struct
sockaddr_in6
*
sin6
=
(
struct
sockaddr_in6
*
)
msg
->
msg_name
;
struct
in6_addr
*
daddr
;
struct
in6_addr
*
daddr
,
*
final_p
=
NULL
,
final
;
struct
ipv6_txoptions
*
opt
=
NULL
;
struct
ip6_flowlabel
*
flowlabel
=
NULL
;
struct
flowi
*
fl
=
&
inet
->
cork
.
fl
;
...
...
@@ -783,7 +783,9 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
/* merge ip6_build_xmit from ip6_output */
if
(
opt
&&
opt
->
srcrt
)
{
struct
rt0_hdr
*
rt0
=
(
struct
rt0_hdr
*
)
opt
->
srcrt
;
ipv6_addr_copy
(
&
final
,
&
fl
->
fl6_dst
);
ipv6_addr_copy
(
&
fl
->
fl6_dst
,
rt0
->
addr
);
final_p
=
&
final
;
}
if
(
!
fl
->
oif
&&
ipv6_addr_is_multicast
(
&
fl
->
fl6_dst
))
...
...
@@ -792,6 +794,13 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
fl
);
if
(
err
)
goto
out
;
if
(
final_p
)
ipv6_addr_copy
(
&
fl
->
fl6_dst
,
final_p
);
if
((
err
=
xfrm_lookup
(
&
dst
,
fl
,
sk
,
0
))
<
0
)
{
dst_release
(
dst
);
goto
out
;
}
if
(
hlimit
<
0
)
{
if
(
ipv6_addr_is_multicast
(
&
fl
->
fl6_dst
))
...
...
net/netlink/af_netlink.c
View file @
48e24acb
...
...
@@ -46,6 +46,7 @@
#include <linux/security.h>
#include <net/sock.h>
#include <net/scm.h>
#include <linux/workqueue.h>
#define Nprintk(a...)
...
...
@@ -69,6 +70,14 @@ struct netlink_opt
#define nlk_sk(__sk) ((struct netlink_opt *)(__sk)->sk_protinfo)
struct
netlink_work
{
struct
sock
*
sk
;
int
len
;
struct
work_struct
work
;
};
static
struct
workqueue_struct
*
netlink_wq
;
static
struct
hlist_head
nl_table
[
MAX_LINKS
];
static
DECLARE_WAIT_QUEUE_HEAD
(
nl_table_wait
);
static
unsigned
nl_nonroot
[
MAX_LINKS
];
...
...
@@ -87,6 +96,16 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
static
struct
notifier_block
*
netlink_chain
;
/* netlink workqueue handler */
static
void
netlink_wq_handler
(
void
*
data
)
{
struct
netlink_work
*
work
=
data
;
work
->
sk
->
sk_data_ready
(
work
->
sk
,
work
->
len
);
sock_put
(
work
->
sk
);
kfree
(
work
);
}
static
void
netlink_sock_destruct
(
struct
sock
*
sk
)
{
skb_queue_purge
(
&
sk
->
sk_receive_queue
);
...
...
@@ -478,6 +497,8 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
if
(
atomic_read
(
&
sk
->
sk_rmem_alloc
)
>
sk
->
sk_rcvbuf
||
test_bit
(
0
,
&
nlk
->
state
))
{
DECLARE_WAITQUEUE
(
wait
,
current
);
task_t
*
client
;
if
(
!
timeo
)
{
if
(
!
nlk
->
pid
)
netlink_overrun
(
sk
);
...
...
@@ -486,6 +507,19 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
return
-
EAGAIN
;
}
if
(
nlk
->
pid
)
{
/* Kernel is sending information to user space
* and socket buffer is full: Wake up user
* process */
client
=
find_task_by_pid
(
nlk
->
pid
);
if
(
!
client
)
{
sock_put
(
sk
);
kfree_skb
(
skb
);
return
-
EAGAIN
;
}
wake_up_process
(
client
);
}
__set_current_state
(
TASK_INTERRUPTIBLE
);
add_wait_queue
(
&
nlk
->
wait
,
&
wait
);
...
...
@@ -525,8 +559,24 @@ int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
#endif
skb_queue_tail
(
&
sk
->
sk_receive_queue
,
skb
);
sk
->
sk_data_ready
(
sk
,
len
);
sock_put
(
sk
);
if
(
!
nlk
->
pid
)
{
struct
netlink_work
*
nlwork
=
kmalloc
(
sizeof
(
struct
netlink_work
),
GFP_KERNEL
);
if
(
!
nlwork
)
{
sock_put
(
sk
);
return
-
EAGAIN
;
}
INIT_WORK
(
&
nlwork
->
work
,
netlink_wq_handler
,
nlwork
);
nlwork
->
sk
=
sk
;
nlwork
->
len
=
len
;
queue_work
(
netlink_wq
,
&
nlwork
->
work
);
}
else
{
sk
->
sk_data_ready
(
sk
,
len
);
sock_put
(
sk
);
}
return
len
;
}
...
...
@@ -573,7 +623,21 @@ static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff
skb_orphan
(
skb
);
skb_set_owner_r
(
skb
,
sk
);
skb_queue_tail
(
&
sk
->
sk_receive_queue
,
skb
);
sk
->
sk_data_ready
(
sk
,
skb
->
len
);
if
(
!
nlk
->
pid
)
{
struct
netlink_work
*
nlwork
=
kmalloc
(
sizeof
(
struct
netlink_work
),
GFP_KERNEL
);
if
(
!
nlwork
)
return
-
1
;
INIT_WORK
(
&
nlwork
->
work
,
netlink_wq_handler
,
nlwork
);
nlwork
->
sk
=
sk
;
nlwork
->
len
=
skb
->
len
;
queue_work
(
netlink_wq
,
&
nlwork
->
work
);
}
else
sk
->
sk_data_ready
(
sk
,
skb
->
len
);
return
0
;
}
return
-
1
;
...
...
@@ -619,13 +683,14 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
netlink_overrun
(
sk
);
/* Clone failed. Notify ALL listeners. */
failure
=
1
;
sock_put
(
sk
);
}
else
if
(
netlink_broadcast_deliver
(
sk
,
skb2
))
{
netlink_overrun
(
sk
);
sock_put
(
sk
);
}
else
{
delivered
=
1
;
skb2
=
NULL
;
}
sock_put
(
sk
);
}
netlink_unlock_table
();
...
...
@@ -1202,6 +1267,9 @@ static int __init netlink_proto_init(void)
#endif
/* The netlink device handler may be needed early. */
rtnetlink_init
();
/* Create a work queue to handle callbacks to modules */
netlink_wq
=
create_workqueue
(
"netlink"
);
return
0
;
}
...
...
@@ -1209,6 +1277,7 @@ static void __exit netlink_proto_exit(void)
{
sock_unregister
(
PF_NETLINK
);
proc_net_remove
(
"netlink"
);
destroy_workqueue
(
netlink_wq
);
}
core_initcall
(
netlink_proto_init
);
...
...
net/packet/af_packet.c
View file @
48e24acb
...
...
@@ -66,6 +66,7 @@
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <asm/page.h>
#include <asm/io.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
...
...
@@ -173,7 +174,7 @@ struct packet_opt
{
struct
tpacket_stats
stats
;
#ifdef CONFIG_PACKET_MMAP
unsigned
long
*
pg_vec
;
char
*
*
pg_vec
;
unsigned
int
head
;
unsigned
int
frames_per_block
;
unsigned
int
frame_size
;
...
...
@@ -198,15 +199,15 @@ struct packet_opt
#ifdef CONFIG_PACKET_MMAP
static
inline
unsigned
long
packet_lookup_frame
(
struct
packet_opt
*
po
,
unsigned
int
position
)
static
inline
char
*
packet_lookup_frame
(
struct
packet_opt
*
po
,
unsigned
int
position
)
{
unsigned
int
pg_vec_pos
,
frame_offset
;
unsigned
long
frame
;
char
*
frame
;
pg_vec_pos
=
position
/
po
->
frames_per_block
;
frame_offset
=
position
%
po
->
frames_per_block
;
frame
=
(
unsigned
long
)
(
po
->
pg_vec
[
pg_vec_pos
]
+
(
frame_offset
*
po
->
frame_size
)
);
frame
=
po
->
pg_vec
[
pg_vec_pos
]
+
(
frame_offset
*
po
->
frame_size
);
return
frame
;
}
...
...
@@ -1549,7 +1550,12 @@ static struct vm_operations_struct packet_mmap_ops = {
.
close
=
packet_mm_close
,
};
static
void
free_pg_vec
(
unsigned
long
*
pg_vec
,
unsigned
order
,
unsigned
len
)
static
inline
struct
page
*
pg_vec_endpage
(
char
*
one_pg_vec
,
unsigned
int
order
)
{
return
virt_to_page
(
one_pg_vec
+
(
PAGE_SIZE
<<
order
)
-
1
);
}
static
void
free_pg_vec
(
char
**
pg_vec
,
unsigned
order
,
unsigned
len
)
{
int
i
;
...
...
@@ -1557,10 +1563,10 @@ static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len)
if
(
pg_vec
[
i
])
{
struct
page
*
page
,
*
pend
;
pend
=
virt_to_page
(
pg_vec
[
i
]
+
(
PAGE_SIZE
<<
order
)
-
1
);
pend
=
pg_vec_endpage
(
pg_vec
[
i
],
order
);
for
(
page
=
virt_to_page
(
pg_vec
[
i
]);
page
<=
pend
;
page
++
)
ClearPageReserved
(
page
);
free_pages
(
pg_vec
[
i
],
order
);
free_pages
(
(
unsigned
long
)
pg_vec
[
i
],
order
);
}
}
kfree
(
pg_vec
);
...
...
@@ -1569,7 +1575,7 @@ static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len)
static
int
packet_set_ring
(
struct
sock
*
sk
,
struct
tpacket_req
*
req
,
int
closing
)
{
unsigned
long
*
pg_vec
=
NULL
;
char
*
*
pg_vec
=
NULL
;
struct
packet_opt
*
po
=
pkt_sk
(
sk
);
int
was_running
,
num
,
order
=
0
;
int
err
=
0
;
...
...
@@ -1604,18 +1610,18 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
err
=
-
ENOMEM
;
pg_vec
=
kmalloc
(
req
->
tp_block_nr
*
sizeof
(
unsigned
long
*
),
GFP_KERNEL
);
pg_vec
=
kmalloc
(
req
->
tp_block_nr
*
sizeof
(
char
*
),
GFP_KERNEL
);
if
(
pg_vec
==
NULL
)
goto
out
;
memset
(
pg_vec
,
0
,
req
->
tp_block_nr
*
sizeof
(
unsigned
long
*
));
memset
(
pg_vec
,
0
,
req
->
tp_block_nr
*
sizeof
(
char
*
*
));
for
(
i
=
0
;
i
<
req
->
tp_block_nr
;
i
++
)
{
struct
page
*
page
,
*
pend
;
pg_vec
[
i
]
=
__get_free_pages
(
GFP_KERNEL
,
order
);
pg_vec
[
i
]
=
(
char
*
)
__get_free_pages
(
GFP_KERNEL
,
order
);
if
(
!
pg_vec
[
i
])
goto
out_free_pgvec
;
pend
=
virt_to_page
(
pg_vec
[
i
]
+
(
PAGE_SIZE
<<
order
)
-
1
);
pend
=
pg_vec_endpage
(
pg_vec
[
i
],
order
);
for
(
page
=
virt_to_page
(
pg_vec
[
i
]);
page
<=
pend
;
page
++
)
SetPageReserved
(
page
);
}
...
...
@@ -1623,7 +1629,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
l
=
0
;
for
(
i
=
0
;
i
<
req
->
tp_block_nr
;
i
++
)
{
unsigned
long
ptr
=
pg_vec
[
i
];
char
*
ptr
=
pg_vec
[
i
];
struct
tpacket_hdr
*
header
;
int
k
;
...
...
net/sched/sch_netem.c
View file @
48e24acb
This diff is collapsed.
Click to expand it.
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