aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-08-08 02:20:26 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-08 02:20:26 -0400
commit19fd61785a580c60cba900c5171bfadb57dd5056 (patch)
tree1e491fb014be0dc03f4b6755bb94e73afd38c455 /net
parent57569d0e12eaf31717e295960cd2a26f626c8e5b (diff)
parent8028837d71ba9904b17281b40f94b93e947fbe38 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'net')
-rw-r--r--net/atm/br2684.c2
-rw-r--r--net/core/Makefile2
-rw-r--r--net/core/secure_seq.c184
-rw-r--r--net/core/skbuff.c17
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/ipv6.c9
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/inet_hashtables.c1
-rw-r--r--net/ipv4/inetpeer.c1
-rw-r--r--net/ipv4/ip_output.c11
-rw-r--r--net/ipv4/ip_sockglue.c9
-rw-r--r--net/ipv4/netfilter.c18
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_common.c1
-rw-r--r--net/ipv4/raw.c3
-rw-r--r--net/ipv4/route.c18
-rw-r--r--net/ipv4/tcp_ipv4.c1
-rw-r--r--net/ipv6/addrconf.c2
-rw-r--r--net/ipv6/datagram.c11
-rw-r--r--net/ipv6/inet6_hashtables.c1
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_output.c13
-rw-r--r--net/ipv6/route.c35
-rw-r--r--net/ipv6/tcp_ipv6.c1
-rw-r--r--net/netfilter/nf_queue.c1
-rw-r--r--net/netlabel/Makefile2
-rw-r--r--net/netlabel/netlabel_addrlist.c2
-rw-r--r--net/netlabel/netlabel_addrlist.h2
-rw-r--r--net/netlabel/netlabel_cipso_v4.c2
-rw-r--r--net/netlabel/netlabel_cipso_v4.h2
-rw-r--r--net/netlabel/netlabel_domainhash.c2
-rw-r--r--net/netlabel/netlabel_domainhash.h2
-rw-r--r--net/netlabel/netlabel_kapi.c2
-rw-r--r--net/netlabel/netlabel_mgmt.c2
-rw-r--r--net/netlabel/netlabel_mgmt.h2
-rw-r--r--net/netlabel/netlabel_unlabeled.c2
-rw-r--r--net/netlabel/netlabel_unlabeled.h2
-rw-r--r--net/netlabel/netlabel_user.c2
-rw-r--r--net/netlabel/netlabel_user.h2
-rw-r--r--net/sched/sch_sfq.c7
-rw-r--r--net/socket.c73
-rw-r--r--net/wireless/nl80211.c2
41 files changed, 353 insertions, 103 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 2252c2085dac..52cfd0c3ea71 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -242,8 +242,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
242 if (brdev->payload == p_bridged) { 242 if (brdev->payload == p_bridged) {
243 skb_push(skb, 2); 243 skb_push(skb, 2);
244 memset(skb->data, 0, 2); 244 memset(skb->data, 0, 2);
245 } else { /* p_routed */
246 skb_pull(skb, ETH_HLEN);
247 } 245 }
248 } 246 }
249 skb_debug(skb); 247 skb_debug(skb);
diff --git a/net/core/Makefile b/net/core/Makefile
index 8a04dd22cf77..0d357b1c4e57 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ 5obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
6 gen_stats.o gen_estimator.o net_namespace.o 6 gen_stats.o gen_estimator.o net_namespace.o secure_seq.o
7 7
8obj-$(CONFIG_SYSCTL) += sysctl_net_core.o 8obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
9 9
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
new file mode 100644
index 000000000000..45329d7c9dd9
--- /dev/null
+++ b/net/core/secure_seq.c
@@ -0,0 +1,184 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/cryptohash.h>
4#include <linux/module.h>
5#include <linux/cache.h>
6#include <linux/random.h>
7#include <linux/hrtimer.h>
8#include <linux/ktime.h>
9#include <linux/string.h>
10
11#include <net/secure_seq.h>
12
13static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
14
15static int __init net_secret_init(void)
16{
17 get_random_bytes(net_secret, sizeof(net_secret));
18 return 0;
19}
20late_initcall(net_secret_init);
21
22static u32 seq_scale(u32 seq)
23{
24 /*
25 * As close as possible to RFC 793, which
26 * suggests using a 250 kHz clock.
27 * Further reading shows this assumes 2 Mb/s networks.
28 * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
29 * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
30 * we also need to limit the resolution so that the u32 seq
31 * overlaps less than one time per MSL (2 minutes).
32 * Choosing a clock of 64 ns period is OK. (period of 274 s)
33 */
34 return seq + (ktime_to_ns(ktime_get_real()) >> 6);
35}
36
37#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
38__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
39 __be16 sport, __be16 dport)
40{
41 u32 secret[MD5_MESSAGE_BYTES / 4];
42 u32 hash[MD5_DIGEST_WORDS];
43 u32 i;
44
45 memcpy(hash, saddr, 16);
46 for (i = 0; i < 4; i++)
47 secret[i] = net_secret[i] + daddr[i];
48 secret[4] = net_secret[4] +
49 (((__force u16)sport << 16) + (__force u16)dport);
50 for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
51 secret[i] = net_secret[i];
52
53 md5_transform(hash, secret);
54
55 return seq_scale(hash[0]);
56}
57EXPORT_SYMBOL(secure_tcpv6_sequence_number);
58
59u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
60 __be16 dport)
61{
62 u32 secret[MD5_MESSAGE_BYTES / 4];
63 u32 hash[MD5_DIGEST_WORDS];
64 u32 i;
65
66 memcpy(hash, saddr, 16);
67 for (i = 0; i < 4; i++)
68 secret[i] = net_secret[i] + (__force u32) daddr[i];
69 secret[4] = net_secret[4] + (__force u32)dport;
70 for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
71 secret[i] = net_secret[i];
72
73 md5_transform(hash, secret);
74
75 return hash[0];
76}
77#endif
78
79#ifdef CONFIG_INET
80__u32 secure_ip_id(__be32 daddr)
81{
82 u32 hash[MD5_DIGEST_WORDS];
83
84 hash[0] = (__force __u32) daddr;
85 hash[1] = net_secret[13];
86 hash[2] = net_secret[14];
87 hash[3] = net_secret[15];
88
89 md5_transform(hash, net_secret);
90
91 return hash[0];
92}
93
94__u32 secure_ipv6_id(const __be32 daddr[4])
95{
96 __u32 hash[4];
97
98 memcpy(hash, daddr, 16);
99 md5_transform(hash, net_secret);
100
101 return hash[0];
102}
103
104__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
105 __be16 sport, __be16 dport)
106{
107 u32 hash[MD5_DIGEST_WORDS];
108
109 hash[0] = (__force u32)saddr;
110 hash[1] = (__force u32)daddr;
111 hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
112 hash[3] = net_secret[15];
113
114 md5_transform(hash, net_secret);
115
116 return seq_scale(hash[0]);
117}
118
119u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
120{
121 u32 hash[MD5_DIGEST_WORDS];
122
123 hash[0] = (__force u32)saddr;
124 hash[1] = (__force u32)daddr;
125 hash[2] = (__force u32)dport ^ net_secret[14];
126 hash[3] = net_secret[15];
127
128 md5_transform(hash, net_secret);
129
130 return hash[0];
131}
132EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
133#endif
134
135#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
136u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
137 __be16 sport, __be16 dport)
138{
139 u32 hash[MD5_DIGEST_WORDS];
140 u64 seq;
141
142 hash[0] = (__force u32)saddr;
143 hash[1] = (__force u32)daddr;
144 hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
145 hash[3] = net_secret[15];
146
147 md5_transform(hash, net_secret);
148
149 seq = hash[0] | (((u64)hash[1]) << 32);
150 seq += ktime_to_ns(ktime_get_real());
151 seq &= (1ull << 48) - 1;
152
153 return seq;
154}
155EXPORT_SYMBOL(secure_dccp_sequence_number);
156
157#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
158u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
159 __be16 sport, __be16 dport)
160{
161 u32 secret[MD5_MESSAGE_BYTES / 4];
162 u32 hash[MD5_DIGEST_WORDS];
163 u64 seq;
164 u32 i;
165
166 memcpy(hash, saddr, 16);
167 for (i = 0; i < 4; i++)
168 secret[i] = net_secret[i] + daddr[i];
169 secret[4] = net_secret[4] +
170 (((__force u16)sport << 16) + (__force u16)dport);
171 for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
172 secret[i] = net_secret[i];
173
174 md5_transform(hash, secret);
175
176 seq = hash[0] | (((u64)hash[1]) << 32);
177 seq += ktime_to_ns(ktime_get_real());
178 seq &= (1ull << 48) - 1;
179
180 return seq;
181}
182EXPORT_SYMBOL(secure_dccpv6_sequence_number);
183#endif
184#endif
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2beda824636e..27002dffe7ed 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1369,8 +1369,21 @@ pull_pages:
1369} 1369}
1370EXPORT_SYMBOL(__pskb_pull_tail); 1370EXPORT_SYMBOL(__pskb_pull_tail);
1371 1371
1372/* Copy some data bits from skb to kernel buffer. */ 1372/**
1373 1373 * skb_copy_bits - copy bits from skb to kernel buffer
1374 * @skb: source skb
1375 * @offset: offset in source
1376 * @to: destination buffer
1377 * @len: number of bytes to copy
1378 *
1379 * Copy the specified number of bytes from the source skb to the
1380 * destination buffer.
1381 *
1382 * CAUTION ! :
1383 * If its prototype is ever changed,
1384 * check arch/{*}/net/{*}.S files,
1385 * since it is called from BPF assembly code.
1386 */
1374int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) 1387int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
1375{ 1388{
1376 int start = skb_headlen(skb); 1389 int start = skb_headlen(skb);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 8c36adfd1919..332639b56f4d 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -26,6 +26,7 @@
26#include <net/timewait_sock.h> 26#include <net/timewait_sock.h>
27#include <net/tcp_states.h> 27#include <net/tcp_states.h>
28#include <net/xfrm.h> 28#include <net/xfrm.h>
29#include <net/secure_seq.h>
29 30
30#include "ackvec.h" 31#include "ackvec.h"
31#include "ccid.h" 32#include "ccid.h"
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 8dc4348774a5..b74f76117dcf 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -29,6 +29,7 @@
29#include <net/transp_v6.h> 29#include <net/transp_v6.h>
30#include <net/ip6_checksum.h> 30#include <net/ip6_checksum.h>
31#include <net/xfrm.h> 31#include <net/xfrm.h>
32#include <net/secure_seq.h>
32 33
33#include "dccp.h" 34#include "dccp.h"
34#include "ipv6.h" 35#include "ipv6.h"
@@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb)
69 dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); 70 dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr);
70} 71}
71 72
72static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, 73static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
73 __be16 sport, __be16 dport )
74{
75 return secure_tcpv6_sequence_number(saddr, daddr, sport, dport);
76}
77
78static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb)
79{ 74{
80 return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, 75 return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
81 ipv6_hdr(skb)->saddr.s6_addr32, 76 ipv6_hdr(skb)->saddr.s6_addr32,
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 83532d22129f..70695221a10d 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
1718 1718
1719 pmc->sfcount[sfmode]--; 1719 pmc->sfcount[sfmode]--;
1720 for (j=0; j<i; j++) 1720 for (j=0; j<i; j++)
1721 (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); 1721 (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]);
1722 } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { 1722 } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {
1723#ifdef CONFIG_IP_MULTICAST 1723#ifdef CONFIG_IP_MULTICAST
1724 struct ip_sf_list *psf; 1724 struct ip_sf_list *psf;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 3c0369a3a663..984ec656b03b 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -21,6 +21,7 @@
21 21
22#include <net/inet_connection_sock.h> 22#include <net/inet_connection_sock.h>
23#include <net/inet_hashtables.h> 23#include <net/inet_hashtables.h>
24#include <net/secure_seq.h>
24#include <net/ip.h> 25#include <net/ip.h>
25 26
26/* 27/*
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index e38213817d0a..86f13c67ea85 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -19,6 +19,7 @@
19#include <linux/net.h> 19#include <linux/net.h>
20#include <net/ip.h> 20#include <net/ip.h>
21#include <net/inetpeer.h> 21#include <net/inetpeer.h>
22#include <net/secure_seq.h>
22 23
23/* 24/*
24 * Theory of operations. 25 * Theory of operations.
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ccaaa851ab42..8c6563361ab5 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -122,6 +122,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
122 newskb->pkt_type = PACKET_LOOPBACK; 122 newskb->pkt_type = PACKET_LOOPBACK;
123 newskb->ip_summed = CHECKSUM_UNNECESSARY; 123 newskb->ip_summed = CHECKSUM_UNNECESSARY;
124 WARN_ON(!skb_dst(newskb)); 124 WARN_ON(!skb_dst(newskb));
125 skb_dst_force(newskb);
125 netif_rx_ni(newskb); 126 netif_rx_ni(newskb);
126 return 0; 127 return 0;
127} 128}
@@ -204,9 +205,15 @@ static inline int ip_finish_output2(struct sk_buff *skb)
204 skb = skb2; 205 skb = skb2;
205 } 206 }
206 207
208 rcu_read_lock();
207 neigh = dst_get_neighbour(dst); 209 neigh = dst_get_neighbour(dst);
208 if (neigh) 210 if (neigh) {
209 return neigh_output(neigh, skb); 211 int res = neigh_output(neigh, skb);
212
213 rcu_read_unlock();
214 return res;
215 }
216 rcu_read_unlock();
210 217
211 if (net_ratelimit()) 218 if (net_ratelimit())
212 printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); 219 printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index ab0c9efd1efa..8905e92f896a 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt);
1067 */ 1067 */
1068 1068
1069static int do_ip_getsockopt(struct sock *sk, int level, int optname, 1069static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1070 char __user *optval, int __user *optlen) 1070 char __user *optval, int __user *optlen, unsigned flags)
1071{ 1071{
1072 struct inet_sock *inet = inet_sk(sk); 1072 struct inet_sock *inet = inet_sk(sk);
1073 int val; 1073 int val;
@@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1240 1240
1241 msg.msg_control = optval; 1241 msg.msg_control = optval;
1242 msg.msg_controllen = len; 1242 msg.msg_controllen = len;
1243 msg.msg_flags = 0; 1243 msg.msg_flags = flags;
1244 1244
1245 if (inet->cmsg_flags & IP_CMSG_PKTINFO) { 1245 if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
1246 struct in_pktinfo info; 1246 struct in_pktinfo info;
@@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level,
1294{ 1294{
1295 int err; 1295 int err;
1296 1296
1297 err = do_ip_getsockopt(sk, level, optname, optval, optlen); 1297 err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
1298#ifdef CONFIG_NETFILTER 1298#ifdef CONFIG_NETFILTER
1299 /* we need to exclude all possible ENOPROTOOPTs except default case */ 1299 /* we need to exclude all possible ENOPROTOOPTs except default case */
1300 if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && 1300 if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
@@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
1327 return compat_mc_getsockopt(sk, level, optname, optval, optlen, 1327 return compat_mc_getsockopt(sk, level, optname, optval, optlen,
1328 ip_getsockopt); 1328 ip_getsockopt);
1329 1329
1330 err = do_ip_getsockopt(sk, level, optname, optval, optlen); 1330 err = do_ip_getsockopt(sk, level, optname, optval, optlen,
1331 MSG_CMSG_COMPAT);
1331 1332
1332#ifdef CONFIG_NETFILTER 1333#ifdef CONFIG_NETFILTER
1333 /* we need to exclude all possible ENOPROTOOPTs except default case */ 1334 /* we need to exclude all possible ENOPROTOOPTs except default case */
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 2e97e3ec1eb7..929b27bdeb79 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
18 struct rtable *rt; 18 struct rtable *rt;
19 struct flowi4 fl4 = {}; 19 struct flowi4 fl4 = {};
20 __be32 saddr = iph->saddr; 20 __be32 saddr = iph->saddr;
21 __u8 flags = 0; 21 __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
22 unsigned int hh_len; 22 unsigned int hh_len;
23 23
24 if (!skb->sk && addr_type != RTN_LOCAL) { 24 if (addr_type == RTN_UNSPEC)
25 if (addr_type == RTN_UNSPEC) 25 addr_type = inet_addr_type(net, saddr);
26 addr_type = inet_addr_type(net, saddr); 26 if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
27 if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) 27 flags |= FLOWI_FLAG_ANYSRC;
28 flags |= FLOWI_FLAG_ANYSRC; 28 else
29 else 29 saddr = 0;
30 saddr = 0;
31 }
32 30
33 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause 31 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
34 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. 32 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
@@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
38 fl4.flowi4_tos = RT_TOS(iph->tos); 36 fl4.flowi4_tos = RT_TOS(iph->tos);
39 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; 37 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
40 fl4.flowi4_mark = skb->mark; 38 fl4.flowi4_mark = skb->mark;
41 fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; 39 fl4.flowi4_flags = flags;
42 rt = ip_route_output_key(net, &fl4); 40 rt = ip_route_output_key(net, &fl4);
43 if (IS_ERR(rt)) 41 if (IS_ERR(rt))
44 return -1; 42 return -1;
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c
index 3e61faf23a9a..f52d41ea0690 100644
--- a/net/ipv4/netfilter/nf_nat_proto_common.c
+++ b/net/ipv4/netfilter/nf_nat_proto_common.c
@@ -12,6 +12,7 @@
12#include <linux/ip.h> 12#include <linux/ip.h>
13 13
14#include <linux/netfilter.h> 14#include <linux/netfilter.h>
15#include <net/secure_seq.h>
15#include <net/netfilter/nf_nat.h> 16#include <net/netfilter/nf_nat.h>
16#include <net/netfilter/nf_nat_core.h> 17#include <net/netfilter/nf_nat_core.h>
17#include <net/netfilter/nf_nat_rule.h> 18#include <net/netfilter/nf_nat_rule.h>
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 1457acb39cec..61714bd52925 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
563 flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, 563 flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
564 RT_SCOPE_UNIVERSE, 564 RT_SCOPE_UNIVERSE,
565 inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, 565 inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
566 FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); 566 inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP,
567 daddr, saddr, 0, 0);
567 568
568 if (!inet->hdrincl) { 569 if (!inet->hdrincl) {
569 err = raw_probe_proto_opt(&fl4, msg); 570 err = raw_probe_proto_opt(&fl4, msg);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1730689f560e..cb7efe0567f0 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -109,6 +109,7 @@
109#include <linux/sysctl.h> 109#include <linux/sysctl.h>
110#endif 110#endif
111#include <net/atmclip.h> 111#include <net/atmclip.h>
112#include <net/secure_seq.h>
112 113
113#define RT_FL_TOS(oldflp4) \ 114#define RT_FL_TOS(oldflp4) \
114 ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) 115 ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)))
@@ -730,6 +731,7 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2)
730 ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | 731 ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
731 (rt1->rt_mark ^ rt2->rt_mark) | 732 (rt1->rt_mark ^ rt2->rt_mark) |
732 (rt1->rt_key_tos ^ rt2->rt_key_tos) | 733 (rt1->rt_key_tos ^ rt2->rt_key_tos) |
734 (rt1->rt_route_iif ^ rt2->rt_route_iif) |
733 (rt1->rt_oif ^ rt2->rt_oif) | 735 (rt1->rt_oif ^ rt2->rt_oif) |
734 (rt1->rt_iif ^ rt2->rt_iif)) == 0; 736 (rt1->rt_iif ^ rt2->rt_iif)) == 0;
735} 737}
@@ -1628,16 +1630,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
1628{ 1630{
1629 struct rtable *rt = (struct rtable *) dst; 1631 struct rtable *rt = (struct rtable *) dst;
1630 __be32 orig_gw = rt->rt_gateway; 1632 __be32 orig_gw = rt->rt_gateway;
1631 struct neighbour *n; 1633 struct neighbour *n, *old_n;
1632 1634
1633 dst_confirm(&rt->dst); 1635 dst_confirm(&rt->dst);
1634 1636
1635 neigh_release(dst_get_neighbour(&rt->dst));
1636 dst_set_neighbour(&rt->dst, NULL);
1637
1638 rt->rt_gateway = peer->redirect_learned.a4; 1637 rt->rt_gateway = peer->redirect_learned.a4;
1639 rt_bind_neighbour(rt); 1638
1640 n = dst_get_neighbour(&rt->dst); 1639 n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
1640 if (IS_ERR(n))
1641 return PTR_ERR(n);
1642 old_n = xchg(&rt->dst._neighbour, n);
1643 if (old_n)
1644 neigh_release(old_n);
1641 if (!n || !(n->nud_state & NUD_VALID)) { 1645 if (!n || !(n->nud_state & NUD_VALID)) {
1642 if (n) 1646 if (n)
1643 neigh_event_send(n, NULL); 1647 neigh_event_send(n, NULL);
@@ -2318,8 +2322,8 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2318 if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | 2322 if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) |
2319 ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | 2323 ((__force u32)rth->rt_key_src ^ (__force u32)saddr) |
2320 (rth->rt_iif ^ iif) | 2324 (rth->rt_iif ^ iif) |
2321 rth->rt_oif |
2322 (rth->rt_key_tos ^ tos)) == 0 && 2325 (rth->rt_key_tos ^ tos)) == 0 &&
2326 rt_is_input_route(rth) &&
2323 rth->rt_mark == skb->mark && 2327 rth->rt_mark == skb->mark &&
2324 net_eq(dev_net(rth->dst.dev), net) && 2328 net_eq(dev_net(rth->dst.dev), net) &&
2325 !rt_is_expired(rth)) { 2329 !rt_is_expired(rth)) {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 955b8e65b69e..1c12b8ec849d 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -72,6 +72,7 @@
72#include <net/timewait_sock.h> 72#include <net/timewait_sock.h>
73#include <net/xfrm.h> 73#include <net/xfrm.h>
74#include <net/netdma.h> 74#include <net/netdma.h>
75#include <net/secure_seq.h>
75 76
76#include <linux/inet.h> 77#include <linux/inet.h>
77#include <linux/ipv6.h> 78#include <linux/ipv6.h>
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7d82123b1d26..8f1e5be26d91 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
656 * layer address of our nexhop router 656 * layer address of our nexhop router
657 */ 657 */
658 658
659 if (dst_get_neighbour(&rt->dst) == NULL) 659 if (dst_get_neighbour_raw(&rt->dst) == NULL)
660 ifa->flags &= ~IFA_F_OPTIMISTIC; 660 ifa->flags &= ~IFA_F_OPTIMISTIC;
661 661
662 ifa->idev = idev; 662 ifa->idev = idev;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 16560336eb72..9ef1831746ef 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -33,6 +33,11 @@
33#include <linux/errqueue.h> 33#include <linux/errqueue.h>
34#include <asm/uaccess.h> 34#include <asm/uaccess.h>
35 35
36static inline int ipv6_mapped_addr_any(const struct in6_addr *a)
37{
38 return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0));
39}
40
36int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 41int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
37{ 42{
38 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 43 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
@@ -102,10 +107,12 @@ ipv4_connected:
102 107
103 ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); 108 ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr);
104 109
105 if (ipv6_addr_any(&np->saddr)) 110 if (ipv6_addr_any(&np->saddr) ||
111 ipv6_mapped_addr_any(&np->saddr))
106 ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); 112 ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
107 113
108 if (ipv6_addr_any(&np->rcv_saddr)) { 114 if (ipv6_addr_any(&np->rcv_saddr) ||
115 ipv6_mapped_addr_any(&np->rcv_saddr)) {
109 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, 116 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
110 &np->rcv_saddr); 117 &np->rcv_saddr);
111 if (sk->sk_prot->rehash) 118 if (sk->sk_prot->rehash)
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index b53197233709..73f1a00a96af 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -20,6 +20,7 @@
20#include <net/inet_connection_sock.h> 20#include <net/inet_connection_sock.h>
21#include <net/inet_hashtables.h> 21#include <net/inet_hashtables.h>
22#include <net/inet6_hashtables.h> 22#include <net/inet6_hashtables.h>
23#include <net/secure_seq.h>
23#include <net/ip.h> 24#include <net/ip.h>
24 25
25int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) 26int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 54a4678955bf..320d91d20ad7 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg)
1455 RT6_TRACE("aging clone %p\n", rt); 1455 RT6_TRACE("aging clone %p\n", rt);
1456 return -1; 1456 return -1;
1457 } else if ((rt->rt6i_flags & RTF_GATEWAY) && 1457 } else if ((rt->rt6i_flags & RTF_GATEWAY) &&
1458 (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) { 1458 (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) {
1459 RT6_TRACE("purging route %p via non-router but gateway\n", 1459 RT6_TRACE("purging route %p via non-router but gateway\n",
1460 rt); 1460 rt);
1461 return -1; 1461 return -1;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 32e5339db0c8..4c882cf4e8a1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -135,10 +135,15 @@ static int ip6_finish_output2(struct sk_buff *skb)
135 skb->len); 135 skb->len);
136 } 136 }
137 137
138 rcu_read_lock();
138 neigh = dst_get_neighbour(dst); 139 neigh = dst_get_neighbour(dst);
139 if (neigh) 140 if (neigh) {
140 return neigh_output(neigh, skb); 141 int res = neigh_output(neigh, skb);
141 142
143 rcu_read_unlock();
144 return res;
145 }
146 rcu_read_unlock();
142 IP6_INC_STATS_BH(dev_net(dst->dev), 147 IP6_INC_STATS_BH(dev_net(dst->dev),
143 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 148 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
144 kfree_skb(skb); 149 kfree_skb(skb);
@@ -975,12 +980,14 @@ static int ip6_dst_lookup_tail(struct sock *sk,
975 * dst entry and replace it instead with the 980 * dst entry and replace it instead with the
976 * dst entry of the nexthop router 981 * dst entry of the nexthop router
977 */ 982 */
983 rcu_read_lock();
978 n = dst_get_neighbour(*dst); 984 n = dst_get_neighbour(*dst);
979 if (n && !(n->nud_state & NUD_VALID)) { 985 if (n && !(n->nud_state & NUD_VALID)) {
980 struct inet6_ifaddr *ifp; 986 struct inet6_ifaddr *ifp;
981 struct flowi6 fl_gw6; 987 struct flowi6 fl_gw6;
982 int redirect; 988 int redirect;
983 989
990 rcu_read_unlock();
984 ifp = ipv6_get_ifaddr(net, &fl6->saddr, 991 ifp = ipv6_get_ifaddr(net, &fl6->saddr,
985 (*dst)->dev, 1); 992 (*dst)->dev, 1);
986 993
@@ -1000,6 +1007,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
1000 if ((err = (*dst)->error)) 1007 if ((err = (*dst)->error))
1001 goto out_err_release; 1008 goto out_err_release;
1002 } 1009 }
1010 } else {
1011 rcu_read_unlock();
1003 } 1012 }
1004#endif 1013#endif
1005 1014
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e8987da06667..9e69eb0ec6dd 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -364,7 +364,7 @@ out:
364#ifdef CONFIG_IPV6_ROUTER_PREF 364#ifdef CONFIG_IPV6_ROUTER_PREF
365static void rt6_probe(struct rt6_info *rt) 365static void rt6_probe(struct rt6_info *rt)
366{ 366{
367 struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; 367 struct neighbour *neigh;
368 /* 368 /*
369 * Okay, this does not seem to be appropriate 369 * Okay, this does not seem to be appropriate
370 * for now, however, we need to check if it 370 * for now, however, we need to check if it
@@ -373,8 +373,10 @@ static void rt6_probe(struct rt6_info *rt)
373 * Router Reachability Probe MUST be rate-limited 373 * Router Reachability Probe MUST be rate-limited
374 * to no more than one per minute. 374 * to no more than one per minute.
375 */ 375 */
376 rcu_read_lock();
377 neigh = rt ? dst_get_neighbour(&rt->dst) : NULL;
376 if (!neigh || (neigh->nud_state & NUD_VALID)) 378 if (!neigh || (neigh->nud_state & NUD_VALID))
377 return; 379 goto out;
378 read_lock_bh(&neigh->lock); 380 read_lock_bh(&neigh->lock);
379 if (!(neigh->nud_state & NUD_VALID) && 381 if (!(neigh->nud_state & NUD_VALID) &&
380 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { 382 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
@@ -387,8 +389,11 @@ static void rt6_probe(struct rt6_info *rt)
387 target = (struct in6_addr *)&neigh->primary_key; 389 target = (struct in6_addr *)&neigh->primary_key;
388 addrconf_addr_solict_mult(target, &mcaddr); 390 addrconf_addr_solict_mult(target, &mcaddr);
389 ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); 391 ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL);
390 } else 392 } else {
391 read_unlock_bh(&neigh->lock); 393 read_unlock_bh(&neigh->lock);
394 }
395out:
396 rcu_read_unlock();
392} 397}
393#else 398#else
394static inline void rt6_probe(struct rt6_info *rt) 399static inline void rt6_probe(struct rt6_info *rt)
@@ -412,8 +417,11 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif)
412 417
413static inline int rt6_check_neigh(struct rt6_info *rt) 418static inline int rt6_check_neigh(struct rt6_info *rt)
414{ 419{
415 struct neighbour *neigh = dst_get_neighbour(&rt->dst); 420 struct neighbour *neigh;
416 int m; 421 int m;
422
423 rcu_read_lock();
424 neigh = dst_get_neighbour(&rt->dst);
417 if (rt->rt6i_flags & RTF_NONEXTHOP || 425 if (rt->rt6i_flags & RTF_NONEXTHOP ||
418 !(rt->rt6i_flags & RTF_GATEWAY)) 426 !(rt->rt6i_flags & RTF_GATEWAY))
419 m = 1; 427 m = 1;
@@ -430,6 +438,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
430 read_unlock_bh(&neigh->lock); 438 read_unlock_bh(&neigh->lock);
431 } else 439 } else
432 m = 0; 440 m = 0;
441 rcu_read_unlock();
433 return m; 442 return m;
434} 443}
435 444
@@ -769,7 +778,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
769 rt->rt6i_dst.plen = 128; 778 rt->rt6i_dst.plen = 128;
770 rt->rt6i_flags |= RTF_CACHE; 779 rt->rt6i_flags |= RTF_CACHE;
771 rt->dst.flags |= DST_HOST; 780 rt->dst.flags |= DST_HOST;
772 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst))); 781 dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst)));
773 } 782 }
774 return rt; 783 return rt;
775} 784}
@@ -803,7 +812,7 @@ restart:
803 dst_hold(&rt->dst); 812 dst_hold(&rt->dst);
804 read_unlock_bh(&table->tb6_lock); 813 read_unlock_bh(&table->tb6_lock);
805 814
806 if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) 815 if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
807 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); 816 nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
808 else if (!(rt->dst.flags & DST_HOST)) 817 else if (!(rt->dst.flags & DST_HOST))
809 nrt = rt6_alloc_clone(rt, &fl6->daddr); 818 nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -1587,7 +1596,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
1587 dst_confirm(&rt->dst); 1596 dst_confirm(&rt->dst);
1588 1597
1589 /* Duplicate redirect: silently ignore. */ 1598 /* Duplicate redirect: silently ignore. */
1590 if (neigh == dst_get_neighbour(&rt->dst)) 1599 if (neigh == dst_get_neighbour_raw(&rt->dst))
1591 goto out; 1600 goto out;
1592 1601
1593 nrt = ip6_rt_copy(rt, dest); 1602 nrt = ip6_rt_copy(rt, dest);
@@ -1682,7 +1691,7 @@ again:
1682 1. It is connected route. Action: COW 1691 1. It is connected route. Action: COW
1683 2. It is gatewayed route or NONEXTHOP route. Action: clone it. 1692 2. It is gatewayed route or NONEXTHOP route. Action: clone it.
1684 */ 1693 */
1685 if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) 1694 if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
1686 nrt = rt6_alloc_cow(rt, daddr, saddr); 1695 nrt = rt6_alloc_cow(rt, daddr, saddr);
1687 else 1696 else
1688 nrt = rt6_alloc_clone(rt, daddr); 1697 nrt = rt6_alloc_clone(rt, daddr);
@@ -2326,6 +2335,7 @@ static int rt6_fill_node(struct net *net,
2326 struct nlmsghdr *nlh; 2335 struct nlmsghdr *nlh;
2327 long expires; 2336 long expires;
2328 u32 table; 2337 u32 table;
2338 struct neighbour *n;
2329 2339
2330 if (prefix) { /* user wants prefix routes only */ 2340 if (prefix) { /* user wants prefix routes only */
2331 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { 2341 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
@@ -2414,8 +2424,11 @@ static int rt6_fill_node(struct net *net,
2414 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 2424 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
2415 goto nla_put_failure; 2425 goto nla_put_failure;
2416 2426
2417 if (dst_get_neighbour(&rt->dst)) 2427 rcu_read_lock();
2418 NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key); 2428 n = dst_get_neighbour(&rt->dst);
2429 if (n)
2430 NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key);
2431 rcu_read_unlock();
2419 2432
2420 if (rt->dst.dev) 2433 if (rt->dst.dev)
2421 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); 2434 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
@@ -2608,12 +2621,14 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2608#else 2621#else
2609 seq_puts(m, "00000000000000000000000000000000 00 "); 2622 seq_puts(m, "00000000000000000000000000000000 00 ");
2610#endif 2623#endif
2624 rcu_read_lock();
2611 n = dst_get_neighbour(&rt->dst); 2625 n = dst_get_neighbour(&rt->dst);
2612 if (n) { 2626 if (n) {
2613 seq_printf(m, "%pi6", n->primary_key); 2627 seq_printf(m, "%pi6", n->primary_key);
2614 } else { 2628 } else {
2615 seq_puts(m, "00000000000000000000000000000000"); 2629 seq_puts(m, "00000000000000000000000000000000");
2616 } 2630 }
2631 rcu_read_unlock();
2617 seq_printf(m, " %08x %08x %08x %08x %8s\n", 2632 seq_printf(m, " %08x %08x %08x %08x %8s\n",
2618 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), 2633 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
2619 rt->dst.__use, rt->rt6i_flags, 2634 rt->dst.__use, rt->rt6i_flags,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 78aa53492b3e..d1fb63f4aeb7 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -61,6 +61,7 @@
61#include <net/timewait_sock.h> 61#include <net/timewait_sock.h>
62#include <net/netdma.h> 62#include <net/netdma.h>
63#include <net/inet_common.h> 63#include <net/inet_common.h>
64#include <net/secure_seq.h>
64 65
65#include <asm/uaccess.h> 66#include <asm/uaccess.h>
66 67
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index c1894ae196de..99ffd2885088 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -312,6 +312,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
312 } 312 }
313 break; 313 break;
314 case NF_STOLEN: 314 case NF_STOLEN:
315 break;
315 default: 316 default:
316 kfree_skb(skb); 317 kfree_skb(skb);
317 } 318 }
diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile
index ea750e9df65f..d2732fc952e2 100644
--- a/net/netlabel/Makefile
+++ b/net/netlabel/Makefile
@@ -1,8 +1,6 @@
1# 1#
2# Makefile for the NetLabel subsystem. 2# Makefile for the NetLabel subsystem.
3# 3#
4# Feb 9, 2006, Paul Moore <paul.moore@hp.com>
5#
6 4
7# base objects 5# base objects
8obj-y := netlabel_user.o netlabel_kapi.o 6obj-y := netlabel_user.o netlabel_kapi.o
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c
index c0519139679e..96b749dacc34 100644
--- a/net/netlabel/netlabel_addrlist.c
+++ b/net/netlabel/netlabel_addrlist.c
@@ -6,7 +6,7 @@
6 * system manages static and dynamic label mappings for network protocols such 6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO. 7 * as CIPSO and RIPSO.
8 * 8 *
9 * Author: Paul Moore <paul.moore@hp.com> 9 * Author: Paul Moore <paul@paul-moore.com>
10 * 10 *
11 */ 11 */
12 12
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h
index 2b9644e19de0..fdbc1d2c7352 100644
--- a/net/netlabel/netlabel_addrlist.h
+++ b/net/netlabel/netlabel_addrlist.h
@@ -6,7 +6,7 @@
6 * system manages static and dynamic label mappings for network protocols such 6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO. 7 * as CIPSO and RIPSO.
8 * 8 *
9 * Author: Paul Moore <paul.moore@hp.com> 9 * Author: Paul Moore <paul@paul-moore.com>
10 * 10 *
11 */ 11 */
12 12
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index dd53a36d89af..6bf878335d94 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -5,7 +5,7 @@
5 * NetLabel system manages static and dynamic label mappings for network 5 * NetLabel system manages static and dynamic label mappings for network
6 * protocols such as CIPSO and RIPSO. 6 * protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h
index af7f3355103e..d24d774bfd62 100644
--- a/net/netlabel/netlabel_cipso_v4.h
+++ b/net/netlabel/netlabel_cipso_v4.h
@@ -5,7 +5,7 @@
5 * NetLabel system manages static and dynamic label mappings for network 5 * NetLabel system manages static and dynamic label mappings for network
6 * protocols such as CIPSO and RIPSO. 6 * protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index c0594cdfe617..3f905e5370c2 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -6,7 +6,7 @@
6 * system manages static and dynamic label mappings for network protocols such 6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO. 7 * as CIPSO and RIPSO.
8 * 8 *
9 * Author: Paul Moore <paul.moore@hp.com> 9 * Author: Paul Moore <paul@paul-moore.com>
10 * 10 *
11 */ 11 */
12 12
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h
index 0261dda3f2d2..bfcc0f7024c5 100644
--- a/net/netlabel/netlabel_domainhash.h
+++ b/net/netlabel/netlabel_domainhash.h
@@ -6,7 +6,7 @@
6 * system manages static and dynamic label mappings for network protocols such 6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO. 7 * as CIPSO and RIPSO.
8 * 8 *
9 * Author: Paul Moore <paul.moore@hp.com> 9 * Author: Paul Moore <paul@paul-moore.com>
10 * 10 *
11 */ 11 */
12 12
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index b528dd928d3c..58107d060846 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -5,7 +5,7 @@
5 * system manages static and dynamic label mappings for network protocols such 5 * system manages static and dynamic label mappings for network protocols such
6 * as CIPSO and RIPSO. 6 * as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index dff8a0809245..bfa555869775 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -5,7 +5,7 @@
5 * NetLabel system manages static and dynamic label mappings for network 5 * NetLabel system manages static and dynamic label mappings for network
6 * protocols such as CIPSO and RIPSO. 6 * protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index 8db37f4c10f7..5a9f31ce5799 100644
--- a/net/netlabel/netlabel_mgmt.h
+++ b/net/netlabel/netlabel_mgmt.h
@@ -5,7 +5,7 @@
5 * NetLabel system manages static and dynamic label mappings for network 5 * NetLabel system manages static and dynamic label mappings for network
6 * protocols such as CIPSO and RIPSO. 6 * protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 5a587cf6c86f..e251c2c88521 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -5,7 +5,7 @@
5 * NetLabel system. The NetLabel system manages static and dynamic label 5 * NetLabel system. The NetLabel system manages static and dynamic label
6 * mappings for network protocols such as CIPSO and RIPSO. 6 * mappings for network protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h
index 0bc8dc3f9e3c..700af49022a0 100644
--- a/net/netlabel/netlabel_unlabeled.h
+++ b/net/netlabel/netlabel_unlabeled.h
@@ -5,7 +5,7 @@
5 * NetLabel system. The NetLabel system manages static and dynamic label 5 * NetLabel system. The NetLabel system manages static and dynamic label
6 * mappings for network protocols such as CIPSO and RIPSO. 6 * mappings for network protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index a3fd75ac3fa5..9fae63f10298 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -5,7 +5,7 @@
5 * NetLabel system manages static and dynamic label mappings for network 5 * NetLabel system manages static and dynamic label mappings for network
6 * protocols such as CIPSO and RIPSO. 6 * protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index f4fc4c9ad567..81969785e279 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -5,7 +5,7 @@
5 * NetLabel system manages static and dynamic label mappings for network 5 * NetLabel system manages static and dynamic label mappings for network
6 * protocols such as CIPSO and RIPSO. 6 * protocols such as CIPSO and RIPSO.
7 * 7 *
8 * Author: Paul Moore <paul.moore@hp.com> 8 * Author: Paul Moore <paul@paul-moore.com>
9 * 9 *
10 */ 10 */
11 11
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 4536ee64383e..4f5510e2bd6f 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
410 /* Return Congestion Notification only if we dropped a packet 410 /* Return Congestion Notification only if we dropped a packet
411 * from this flow. 411 * from this flow.
412 */ 412 */
413 return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; 413 if (qlen != slot->qlen)
414 return NET_XMIT_CN;
415
416 /* As we dropped a packet, better let upper stack know this */
417 qdisc_tree_decrease_qlen(sch, 1);
418 return NET_XMIT_SUCCESS;
414} 419}
415 420
416static struct sk_buff * 421static struct sk_buff *
diff --git a/net/socket.c b/net/socket.c
index 7ec8f9b669b3..2517e11a5300 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how)
1871#define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) 1871#define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen)
1872#define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) 1872#define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags)
1873 1873
1874struct used_address {
1875 struct sockaddr_storage name;
1876 unsigned int name_len;
1877};
1878
1874static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, 1879static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
1875 struct msghdr *msg_sys, unsigned flags, int nosec) 1880 struct msghdr *msg_sys, unsigned flags,
1881 struct used_address *used_address)
1876{ 1882{
1877 struct compat_msghdr __user *msg_compat = 1883 struct compat_msghdr __user *msg_compat =
1878 (struct compat_msghdr __user *)msg; 1884 (struct compat_msghdr __user *)msg;
@@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
1953 1959
1954 if (sock->file->f_flags & O_NONBLOCK) 1960 if (sock->file->f_flags & O_NONBLOCK)
1955 msg_sys->msg_flags |= MSG_DONTWAIT; 1961 msg_sys->msg_flags |= MSG_DONTWAIT;
1956 err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, 1962 /*
1957 total_len); 1963 * If this is sendmmsg() and current destination address is same as
1964 * previously succeeded address, omit asking LSM's decision.
1965 * used_address->name_len is initialized to UINT_MAX so that the first
1966 * destination address never matches.
1967 */
1968 if (used_address && used_address->name_len == msg_sys->msg_namelen &&
1969 !memcmp(&used_address->name, msg->msg_name,
1970 used_address->name_len)) {
1971 err = sock_sendmsg_nosec(sock, msg_sys, total_len);
1972 goto out_freectl;
1973 }
1974 err = sock_sendmsg(sock, msg_sys, total_len);
1975 /*
1976 * If this is sendmmsg() and sending to current destination address was
1977 * successful, remember it.
1978 */
1979 if (used_address && err >= 0) {
1980 used_address->name_len = msg_sys->msg_namelen;
1981 memcpy(&used_address->name, msg->msg_name,
1982 used_address->name_len);
1983 }
1958 1984
1959out_freectl: 1985out_freectl:
1960 if (ctl_buf != ctl) 1986 if (ctl_buf != ctl)
@@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
1979 if (!sock) 2005 if (!sock)
1980 goto out; 2006 goto out;
1981 2007
1982 err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); 2008 err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
1983 2009
1984 fput_light(sock->file, fput_needed); 2010 fput_light(sock->file, fput_needed);
1985out: 2011out:
@@ -1998,6 +2024,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
1998 struct mmsghdr __user *entry; 2024 struct mmsghdr __user *entry;
1999 struct compat_mmsghdr __user *compat_entry; 2025 struct compat_mmsghdr __user *compat_entry;
2000 struct msghdr msg_sys; 2026 struct msghdr msg_sys;
2027 struct used_address used_address;
2028
2029 if (vlen > UIO_MAXIOV)
2030 vlen = UIO_MAXIOV;
2001 2031
2002 datagrams = 0; 2032 datagrams = 0;
2003 2033
@@ -2005,27 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2005 if (!sock) 2035 if (!sock)
2006 return err; 2036 return err;
2007 2037
2008 err = sock_error(sock->sk); 2038 used_address.name_len = UINT_MAX;
2009 if (err)
2010 goto out_put;
2011
2012 entry = mmsg; 2039 entry = mmsg;
2013 compat_entry = (struct compat_mmsghdr __user *)mmsg; 2040 compat_entry = (struct compat_mmsghdr __user *)mmsg;
2041 err = 0;
2014 2042
2015 while (datagrams < vlen) { 2043 while (datagrams < vlen) {
2016 /*
2017 * No need to ask LSM for more than the first datagram.
2018 */
2019 if (MSG_CMSG_COMPAT & flags) { 2044 if (MSG_CMSG_COMPAT & flags) {
2020 err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, 2045 err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
2021 &msg_sys, flags, datagrams); 2046 &msg_sys, flags, &used_address);
2022 if (err < 0) 2047 if (err < 0)
2023 break; 2048 break;
2024 err = __put_user(err, &compat_entry->msg_len); 2049 err = __put_user(err, &compat_entry->msg_len);
2025 ++compat_entry; 2050 ++compat_entry;
2026 } else { 2051 } else {
2027 err = __sys_sendmsg(sock, (struct msghdr __user *)entry, 2052 err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
2028 &msg_sys, flags, datagrams); 2053 &msg_sys, flags, &used_address);
2029 if (err < 0) 2054 if (err < 0)
2030 break; 2055 break;
2031 err = put_user(err, &entry->msg_len); 2056 err = put_user(err, &entry->msg_len);
@@ -2037,29 +2062,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2037 ++datagrams; 2062 ++datagrams;
2038 } 2063 }
2039 2064
2040out_put:
2041 fput_light(sock->file, fput_needed); 2065 fput_light(sock->file, fput_needed);
2042 2066
2043 if (err == 0) 2067 /* We only return an error if no datagrams were able to be sent */
2044 return datagrams; 2068 if (datagrams != 0)
2045
2046 if (datagrams != 0) {
2047 /*
2048 * We may send less entries than requested (vlen) if the
2049 * sock is non blocking...
2050 */
2051 if (err != -EAGAIN) {
2052 /*
2053 * ... or if sendmsg returns an error after we
2054 * send some datagrams, where we record the
2055 * error to return on the next call or if the
2056 * app asks about it using getsockopt(SO_ERROR).
2057 */
2058 sock->sk->sk_err = -err;
2059 }
2060
2061 return datagrams; 2069 return datagrams;
2062 }
2063 2070
2064 return err; 2071 return err;
2065} 2072}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 28d2aa109bee..e83e7fee3bc0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3464,7 +3464,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3464 tmp) { 3464 tmp) {
3465 enum ieee80211_band band = nla_type(attr); 3465 enum ieee80211_band band = nla_type(attr);
3466 3466
3467 if (band < 0 || band > IEEE80211_NUM_BANDS) { 3467 if (band < 0 || band >= IEEE80211_NUM_BANDS) {
3468 err = -EINVAL; 3468 err = -EINVAL;
3469 goto out_free; 3469 goto out_free;
3470 } 3470 }