diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-28 04:19:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-28 04:19:40 -0400 |
commit | 1b63ba8a86c85524a8d7e5953b314ce71ebcb9c9 (patch) | |
tree | fe3dc41cbb47ae12b7c3faf6a88b097349e50d5a /net | |
parent | e35c3269edba151e1c703d87068a28ce2cd65bb0 (diff) | |
parent | d420895efb259a78dda50f95289571faa6e10e41 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl4965-base.c
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 6 | ||||
-rw-r--r-- | net/core/net_namespace.c | 3 | ||||
-rw-r--r-- | net/core/skbuff.c | 17 | ||||
-rw-r--r-- | net/ipv4/inet_fragment.c | 16 | ||||
-rw-r--r-- | net/ipv4/inet_lro.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 9 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 9 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 11 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 3 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 2 | ||||
-rw-r--r-- | net/ipv6/route.c | 6 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 6 | ||||
-rw-r--r-- | net/mac80211/key.c | 9 | ||||
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 2 | ||||
-rw-r--r-- | net/netlink/attr.c | 7 | ||||
-rw-r--r-- | net/sched/Kconfig | 11 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 2 | ||||
-rw-r--r-- | net/sctp/socket.c | 4 | ||||
-rw-r--r-- | net/unix/af_unix.c | 52 |
22 files changed, 112 insertions, 76 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index f6944ecd5b2e..472676dd550e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2107,6 +2107,10 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2107 | 2107 | ||
2108 | rcu_read_lock(); | 2108 | rcu_read_lock(); |
2109 | 2109 | ||
2110 | /* Don't receive packets in an exiting network namespace */ | ||
2111 | if (!net_alive(dev_net(skb->dev))) | ||
2112 | goto out; | ||
2113 | |||
2110 | #ifdef CONFIG_NET_CLS_ACT | 2114 | #ifdef CONFIG_NET_CLS_ACT |
2111 | if (skb->tc_verd & TC_NCLS) { | 2115 | if (skb->tc_verd & TC_NCLS) { |
2112 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); | 2116 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); |
@@ -3034,7 +3038,7 @@ EXPORT_SYMBOL(dev_unicast_delete); | |||
3034 | /** | 3038 | /** |
3035 | * dev_unicast_add - add a secondary unicast address | 3039 | * dev_unicast_add - add a secondary unicast address |
3036 | * @dev: device | 3040 | * @dev: device |
3037 | * @addr: address to delete | 3041 | * @addr: address to add |
3038 | * @alen: length of @addr | 3042 | * @alen: length of @addr |
3039 | * | 3043 | * |
3040 | * Add a secondary unicast address to the device or increase | 3044 | * Add a secondary unicast address to the device or increase |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 72b4c184dd84..7c52fe277b62 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -140,6 +140,9 @@ static void cleanup_net(struct work_struct *work) | |||
140 | struct pernet_operations *ops; | 140 | struct pernet_operations *ops; |
141 | struct net *net; | 141 | struct net *net; |
142 | 142 | ||
143 | /* Be very certain incoming network packets will not find us */ | ||
144 | rcu_barrier(); | ||
145 | |||
143 | net = container_of(work, struct net, work); | 146 | net = container_of(work, struct net, work); |
144 | 147 | ||
145 | mutex_lock(&net_mutex); | 148 | mutex_lock(&net_mutex); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2df012be973d..7c571560e9d2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1290,12 +1290,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, | |||
1290 | { | 1290 | { |
1291 | unsigned int nr_pages = spd->nr_pages; | 1291 | unsigned int nr_pages = spd->nr_pages; |
1292 | unsigned int poff, plen, len, toff, tlen; | 1292 | unsigned int poff, plen, len, toff, tlen; |
1293 | int headlen, seg; | 1293 | int headlen, seg, error = 0; |
1294 | 1294 | ||
1295 | toff = *offset; | 1295 | toff = *offset; |
1296 | tlen = *total_len; | 1296 | tlen = *total_len; |
1297 | if (!tlen) | 1297 | if (!tlen) { |
1298 | error = 1; | ||
1298 | goto err; | 1299 | goto err; |
1300 | } | ||
1299 | 1301 | ||
1300 | /* | 1302 | /* |
1301 | * if the offset is greater than the linear part, go directly to | 1303 | * if the offset is greater than the linear part, go directly to |
@@ -1337,7 +1339,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, | |||
1337 | * just jump directly to update and return, no point | 1339 | * just jump directly to update and return, no point |
1338 | * in going over fragments when the output is full. | 1340 | * in going over fragments when the output is full. |
1339 | */ | 1341 | */ |
1340 | if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb)) | 1342 | error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb); |
1343 | if (error) | ||
1341 | goto done; | 1344 | goto done; |
1342 | 1345 | ||
1343 | tlen -= plen; | 1346 | tlen -= plen; |
@@ -1367,7 +1370,8 @@ map_frag: | |||
1367 | if (!plen) | 1370 | if (!plen) |
1368 | break; | 1371 | break; |
1369 | 1372 | ||
1370 | if (spd_fill_page(spd, f->page, plen, poff, skb)) | 1373 | error = spd_fill_page(spd, f->page, plen, poff, skb); |
1374 | if (error) | ||
1371 | break; | 1375 | break; |
1372 | 1376 | ||
1373 | tlen -= plen; | 1377 | tlen -= plen; |
@@ -1380,7 +1384,10 @@ done: | |||
1380 | return 0; | 1384 | return 0; |
1381 | } | 1385 | } |
1382 | err: | 1386 | err: |
1383 | return 1; | 1387 | /* update the offset to reflect the linear part skip, if any */ |
1388 | if (!error) | ||
1389 | *offset = toff; | ||
1390 | return error; | ||
1384 | } | 1391 | } |
1385 | 1392 | ||
1386 | /* | 1393 | /* |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 4ed429bd5951..0546a0bc97ea 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -192,14 +192,21 @@ EXPORT_SYMBOL(inet_frag_evictor); | |||
192 | 192 | ||
193 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, | 193 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, |
194 | struct inet_frag_queue *qp_in, struct inet_frags *f, | 194 | struct inet_frag_queue *qp_in, struct inet_frags *f, |
195 | unsigned int hash, void *arg) | 195 | void *arg) |
196 | { | 196 | { |
197 | struct inet_frag_queue *qp; | 197 | struct inet_frag_queue *qp; |
198 | #ifdef CONFIG_SMP | 198 | #ifdef CONFIG_SMP |
199 | struct hlist_node *n; | 199 | struct hlist_node *n; |
200 | #endif | 200 | #endif |
201 | unsigned int hash; | ||
201 | 202 | ||
202 | write_lock(&f->lock); | 203 | write_lock(&f->lock); |
204 | /* | ||
205 | * While we stayed w/o the lock other CPU could update | ||
206 | * the rnd seed, so we need to re-calculate the hash | ||
207 | * chain. Fortunatelly the qp_in can be used to get one. | ||
208 | */ | ||
209 | hash = f->hashfn(qp_in); | ||
203 | #ifdef CONFIG_SMP | 210 | #ifdef CONFIG_SMP |
204 | /* With SMP race we have to recheck hash table, because | 211 | /* With SMP race we have to recheck hash table, because |
205 | * such entry could be created on other cpu, while we | 212 | * such entry could be created on other cpu, while we |
@@ -247,7 +254,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, | |||
247 | } | 254 | } |
248 | 255 | ||
249 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, | 256 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, |
250 | struct inet_frags *f, void *arg, unsigned int hash) | 257 | struct inet_frags *f, void *arg) |
251 | { | 258 | { |
252 | struct inet_frag_queue *q; | 259 | struct inet_frag_queue *q; |
253 | 260 | ||
@@ -255,7 +262,7 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, | |||
255 | if (q == NULL) | 262 | if (q == NULL) |
256 | return NULL; | 263 | return NULL; |
257 | 264 | ||
258 | return inet_frag_intern(nf, q, f, hash, arg); | 265 | return inet_frag_intern(nf, q, f, arg); |
259 | } | 266 | } |
260 | 267 | ||
261 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | 268 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, |
@@ -264,7 +271,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | |||
264 | struct inet_frag_queue *q; | 271 | struct inet_frag_queue *q; |
265 | struct hlist_node *n; | 272 | struct hlist_node *n; |
266 | 273 | ||
267 | read_lock(&f->lock); | ||
268 | hlist_for_each_entry(q, n, &f->hash[hash], list) { | 274 | hlist_for_each_entry(q, n, &f->hash[hash], list) { |
269 | if (q->net == nf && f->match(q, key)) { | 275 | if (q->net == nf && f->match(q, key)) { |
270 | atomic_inc(&q->refcnt); | 276 | atomic_inc(&q->refcnt); |
@@ -274,6 +280,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | |||
274 | } | 280 | } |
275 | read_unlock(&f->lock); | 281 | read_unlock(&f->lock); |
276 | 282 | ||
277 | return inet_frag_create(nf, f, key, hash); | 283 | return inet_frag_create(nf, f, key); |
278 | } | 284 | } |
279 | EXPORT_SYMBOL(inet_frag_find); | 285 | EXPORT_SYMBOL(inet_frag_find); |
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index 4a4d49fca1f2..cfd034a2b96e 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c | |||
@@ -383,8 +383,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, | |||
383 | out2: /* send aggregated SKBs to stack */ | 383 | out2: /* send aggregated SKBs to stack */ |
384 | lro_flush(lro_mgr, lro_desc); | 384 | lro_flush(lro_mgr, lro_desc); |
385 | 385 | ||
386 | out: /* Original SKB has to be posted to stack */ | 386 | out: |
387 | skb->ip_summed = lro_mgr->ip_summed; | ||
388 | return 1; | 387 | return 1; |
389 | } | 388 | } |
390 | 389 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 91e321407313..fbd5804b5d83 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -227,6 +227,8 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) | |||
227 | 227 | ||
228 | arg.iph = iph; | 228 | arg.iph = iph; |
229 | arg.user = user; | 229 | arg.user = user; |
230 | |||
231 | read_lock(&ip4_frags.lock); | ||
230 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); | 232 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); |
231 | 233 | ||
232 | q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); | 234 | q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index cf0850c068f5..c66ac83316e8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -258,6 +258,8 @@ | |||
258 | #include <linux/socket.h> | 258 | #include <linux/socket.h> |
259 | #include <linux/random.h> | 259 | #include <linux/random.h> |
260 | #include <linux/bootmem.h> | 260 | #include <linux/bootmem.h> |
261 | #include <linux/highmem.h> | ||
262 | #include <linux/swap.h> | ||
261 | #include <linux/cache.h> | 263 | #include <linux/cache.h> |
262 | #include <linux/err.h> | 264 | #include <linux/err.h> |
263 | #include <linux/crypto.h> | 265 | #include <linux/crypto.h> |
@@ -2688,7 +2690,7 @@ __setup("thash_entries=", set_thash_entries); | |||
2688 | void __init tcp_init(void) | 2690 | void __init tcp_init(void) |
2689 | { | 2691 | { |
2690 | struct sk_buff *skb = NULL; | 2692 | struct sk_buff *skb = NULL; |
2691 | unsigned long limit; | 2693 | unsigned long nr_pages, limit; |
2692 | int order, i, max_share; | 2694 | int order, i, max_share; |
2693 | 2695 | ||
2694 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); | 2696 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); |
@@ -2757,8 +2759,9 @@ void __init tcp_init(void) | |||
2757 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | 2759 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
2758 | * memory, with a floor of 128 pages. | 2760 | * memory, with a floor of 128 pages. |
2759 | */ | 2761 | */ |
2760 | limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | 2762 | nr_pages = totalram_pages - totalhigh_pages; |
2761 | limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | 2763 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); |
2764 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
2762 | limit = max(limit, 128UL); | 2765 | limit = max(limit, 128UL); |
2763 | sysctl_tcp_mem[0] = limit / 4 * 3; | 2766 | sysctl_tcp_mem[0] = limit / 4 * 3; |
2764 | sysctl_tcp_mem[1] = limit; | 2767 | sysctl_tcp_mem[1] = limit; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 0db9b75c1fa2..4300bcf2ceaf 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2189,7 +2189,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
2189 | } | 2189 | } |
2190 | 2190 | ||
2191 | seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " | 2191 | seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " |
2192 | "%08X %5d %8d %lu %d %p %u %u %u %u %d%n", | 2192 | "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n", |
2193 | i, src, srcp, dest, destp, sk->sk_state, | 2193 | i, src, srcp, dest, destp, sk->sk_state, |
2194 | tp->write_seq - tp->snd_una, | 2194 | tp->write_seq - tp->snd_una, |
2195 | sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : | 2195 | sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : |
@@ -2201,8 +2201,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
2201 | icsk->icsk_probes_out, | 2201 | icsk->icsk_probes_out, |
2202 | sock_i_ino(sk), | 2202 | sock_i_ino(sk), |
2203 | atomic_read(&sk->sk_refcnt), sk, | 2203 | atomic_read(&sk->sk_refcnt), sk, |
2204 | icsk->icsk_rto, | 2204 | jiffies_to_clock_t(icsk->icsk_rto), |
2205 | icsk->icsk_ack.ato, | 2205 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
2206 | (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, | 2206 | (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, |
2207 | tp->snd_cwnd, | 2207 | tp->snd_cwnd, |
2208 | tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, | 2208 | tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index f77a6011c302..34e5a96623ae 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -100,6 +100,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
100 | if (hdr->version != 6) | 100 | if (hdr->version != 6) |
101 | goto err; | 101 | goto err; |
102 | 102 | ||
103 | /* | ||
104 | * RFC4291 2.5.3 | ||
105 | * A packet received on an interface with a destination address | ||
106 | * of loopback must be dropped. | ||
107 | */ | ||
108 | if (!(dev->flags & IFF_LOOPBACK) && | ||
109 | ipv6_addr_loopback(&hdr->daddr)) | ||
110 | goto err; | ||
111 | |||
103 | skb->transport_header = skb->network_header + sizeof(*hdr); | 112 | skb->transport_header = skb->network_header + sizeof(*hdr); |
104 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); | 113 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); |
105 | 114 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index a9988841172a..030c0c956f9d 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -343,18 +343,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
343 | case IPV6_DSTOPTS: | 343 | case IPV6_DSTOPTS: |
344 | { | 344 | { |
345 | struct ipv6_txoptions *opt; | 345 | struct ipv6_txoptions *opt; |
346 | |||
347 | /* remove any sticky options header with a zero option | ||
348 | * length, per RFC3542. | ||
349 | */ | ||
346 | if (optlen == 0) | 350 | if (optlen == 0) |
347 | optval = NULL; | 351 | optval = NULL; |
352 | else if (optlen < sizeof(struct ipv6_opt_hdr) || | ||
353 | optlen & 0x7 || optlen > 8 * 255) | ||
354 | goto e_inval; | ||
348 | 355 | ||
349 | /* hop-by-hop / destination options are privileged option */ | 356 | /* hop-by-hop / destination options are privileged option */ |
350 | retv = -EPERM; | 357 | retv = -EPERM; |
351 | if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) | 358 | if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) |
352 | break; | 359 | break; |
353 | 360 | ||
354 | if (optlen < sizeof(struct ipv6_opt_hdr) || | ||
355 | optlen & 0x7 || optlen > 8 * 255) | ||
356 | goto e_inval; | ||
357 | |||
358 | opt = ipv6_renew_options(sk, np->opt, optname, | 361 | opt = ipv6_renew_options(sk, np->opt, optname, |
359 | (struct ipv6_opt_hdr __user *)optval, | 362 | (struct ipv6_opt_hdr __user *)optval, |
360 | optlen); | 363 | optlen); |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 27a5e8b48d93..f405cea21a8b 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = { | |||
129 | .priority = NF_IP6_PRI_MANGLE, | 129 | .priority = NF_IP6_PRI_MANGLE, |
130 | }, | 130 | }, |
131 | { | 131 | { |
132 | .hook = ip6t_local_hook, | 132 | .hook = ip6t_route_hook, |
133 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
134 | .pf = PF_INET6, | 134 | .pf = PF_INET6, |
135 | .hooknum = NF_INET_LOCAL_IN, | 135 | .hooknum = NF_INET_LOCAL_IN, |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index e65e26e210ee..cf20bc4fd60d 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) | |||
207 | arg.id = id; | 207 | arg.id = id; |
208 | arg.src = src; | 208 | arg.src = src; |
209 | arg.dst = dst; | 209 | arg.dst = dst; |
210 | |||
211 | read_lock_bh(&nf_frags.lock); | ||
210 | hash = ip6qhashfn(id, src, dst); | 212 | hash = ip6qhashfn(id, src, dst); |
211 | 213 | ||
212 | local_bh_disable(); | ||
213 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); | 214 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); |
214 | local_bh_enable(); | 215 | local_bh_enable(); |
215 | if (q == NULL) | 216 | if (q == NULL) |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 13509f906d89..6ab957ec2dd6 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -245,6 +245,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
245 | arg.id = id; | 245 | arg.id = id; |
246 | arg.src = src; | 246 | arg.src = src; |
247 | arg.dst = dst; | 247 | arg.dst = dst; |
248 | |||
249 | read_lock(&ip6_frags.lock); | ||
248 | hash = ip6qhashfn(id, src, dst); | 250 | hash = ip6qhashfn(id, src, dst); |
249 | 251 | ||
250 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); | 252 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index efe036aa3dd1..751e98f9b8b4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -238,7 +238,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr) | |||
238 | static inline struct rt6_info *rt6_device_match(struct net *net, | 238 | static inline struct rt6_info *rt6_device_match(struct net *net, |
239 | struct rt6_info *rt, | 239 | struct rt6_info *rt, |
240 | int oif, | 240 | int oif, |
241 | int strict) | 241 | int flags) |
242 | { | 242 | { |
243 | struct rt6_info *local = NULL; | 243 | struct rt6_info *local = NULL; |
244 | struct rt6_info *sprt; | 244 | struct rt6_info *sprt; |
@@ -251,7 +251,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
251 | if (dev->flags & IFF_LOOPBACK) { | 251 | if (dev->flags & IFF_LOOPBACK) { |
252 | if (sprt->rt6i_idev == NULL || | 252 | if (sprt->rt6i_idev == NULL || |
253 | sprt->rt6i_idev->dev->ifindex != oif) { | 253 | sprt->rt6i_idev->dev->ifindex != oif) { |
254 | if (strict && oif) | 254 | if (flags & RT6_LOOKUP_F_IFACE && oif) |
255 | continue; | 255 | continue; |
256 | if (local && (!oif || | 256 | if (local && (!oif || |
257 | local->rt6i_idev->dev->ifindex == oif)) | 257 | local->rt6i_idev->dev->ifindex == oif)) |
@@ -264,7 +264,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
264 | if (local) | 264 | if (local) |
265 | return local; | 265 | return local; |
266 | 266 | ||
267 | if (strict) | 267 | if (flags & RT6_LOOKUP_F_IFACE) |
268 | return net->ipv6.ip6_null_entry; | 268 | return net->ipv6.ip6_null_entry; |
269 | } | 269 | } |
270 | return rt; | 270 | return rt; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 09be09cc1aa6..30dbab7cc3cc 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1946,7 +1946,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
1946 | 1946 | ||
1947 | seq_printf(seq, | 1947 | seq_printf(seq, |
1948 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " | 1948 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
1949 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", | 1949 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n", |
1950 | i, | 1950 | i, |
1951 | src->s6_addr32[0], src->s6_addr32[1], | 1951 | src->s6_addr32[0], src->s6_addr32[1], |
1952 | src->s6_addr32[2], src->s6_addr32[3], srcp, | 1952 | src->s6_addr32[2], src->s6_addr32[3], srcp, |
@@ -1962,8 +1962,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
1962 | icsk->icsk_probes_out, | 1962 | icsk->icsk_probes_out, |
1963 | sock_i_ino(sp), | 1963 | sock_i_ino(sp), |
1964 | atomic_read(&sp->sk_refcnt), sp, | 1964 | atomic_read(&sp->sk_refcnt), sp, |
1965 | icsk->icsk_rto, | 1965 | jiffies_to_clock_t(icsk->icsk_rto), |
1966 | icsk->icsk_ack.ato, | 1966 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
1967 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, | 1967 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, |
1968 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh | 1968 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh |
1969 | ); | 1969 | ); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index d4893bd17754..6597c779e35a 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -387,6 +387,15 @@ void ieee80211_key_free(struct ieee80211_key *key) | |||
387 | if (!key) | 387 | if (!key) |
388 | return; | 388 | return; |
389 | 389 | ||
390 | if (!key->sdata) { | ||
391 | /* The key has not been linked yet, simply free it | ||
392 | * and don't Oops */ | ||
393 | if (key->conf.alg == ALG_CCMP) | ||
394 | ieee80211_aes_key_free(key->u.ccmp.tfm); | ||
395 | kfree(key); | ||
396 | return; | ||
397 | } | ||
398 | |||
390 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); | 399 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); |
391 | __ieee80211_key_free(key); | 400 | __ieee80211_key_free(key); |
392 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); | 401 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 0099da5b2591..52b2611a6eb6 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -1534,7 +1534,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, | |||
1534 | } | 1534 | } |
1535 | } | 1535 | } |
1536 | list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { | 1536 | list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { |
1537 | if (addr6->valid || iter_addr6++ < skip_addr6) | 1537 | if (!addr6->valid || iter_addr6++ < skip_addr6) |
1538 | continue; | 1538 | continue; |
1539 | if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, | 1539 | if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, |
1540 | iface, | 1540 | iface, |
diff --git a/net/netlink/attr.c b/net/netlink/attr.c index 47bbf45ae5d7..2d106cfe1d27 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c | |||
@@ -132,6 +132,7 @@ errout: | |||
132 | * @maxtype: maximum attribute type to be expected | 132 | * @maxtype: maximum attribute type to be expected |
133 | * @head: head of attribute stream | 133 | * @head: head of attribute stream |
134 | * @len: length of attribute stream | 134 | * @len: length of attribute stream |
135 | * @policy: validation policy | ||
135 | * | 136 | * |
136 | * Parses a stream of attributes and stores a pointer to each attribute in | 137 | * Parses a stream of attributes and stores a pointer to each attribute in |
137 | * the tb array accessable via the attribute type. Attributes with a type | 138 | * the tb array accessable via the attribute type. Attributes with a type |
@@ -194,7 +195,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) | |||
194 | /** | 195 | /** |
195 | * nla_strlcpy - Copy string attribute payload into a sized buffer | 196 | * nla_strlcpy - Copy string attribute payload into a sized buffer |
196 | * @dst: where to copy the string to | 197 | * @dst: where to copy the string to |
197 | * @src: attribute to copy the string from | 198 | * @nla: attribute to copy the string from |
198 | * @dstsize: size of destination buffer | 199 | * @dstsize: size of destination buffer |
199 | * | 200 | * |
200 | * Copies at most dstsize - 1 bytes into the destination buffer. | 201 | * Copies at most dstsize - 1 bytes into the destination buffer. |
@@ -340,9 +341,9 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) | |||
340 | } | 341 | } |
341 | 342 | ||
342 | /** | 343 | /** |
343 | * nla_reserve - reserve room for attribute without header | 344 | * nla_reserve_nohdr - reserve room for attribute without header |
344 | * @skb: socket buffer to reserve room on | 345 | * @skb: socket buffer to reserve room on |
345 | * @len: length of attribute payload | 346 | * @attrlen: length of attribute payload |
346 | * | 347 | * |
347 | * Reserves room for attribute payload without a header. | 348 | * Reserves room for attribute payload without a header. |
348 | * | 349 | * |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 82adfe6447d7..9437b27ff84d 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -106,17 +106,6 @@ config NET_SCH_PRIO | |||
106 | To compile this code as a module, choose M here: the | 106 | To compile this code as a module, choose M here: the |
107 | module will be called sch_prio. | 107 | module will be called sch_prio. |
108 | 108 | ||
109 | config NET_SCH_RR | ||
110 | tristate "Multi Band Round Robin Queuing (RR)" | ||
111 | select NET_SCH_PRIO | ||
112 | ---help--- | ||
113 | Say Y here if you want to use an n-band round robin packet | ||
114 | scheduler. | ||
115 | |||
116 | The module uses sch_prio for its framework and is aliased as | ||
117 | sch_rr, so it will load sch_prio, although it is referred | ||
118 | to using sch_rr. | ||
119 | |||
120 | config NET_SCH_RED | 109 | config NET_SCH_RED |
121 | tristate "Random Early Detection (RED)" | 110 | tristate "Random Early Detection (RED)" |
122 | ---help--- | 111 | ---help--- |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index d355e5e47fe3..13afa7214392 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -468,7 +468,7 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) | |||
468 | 468 | ||
469 | return sch; | 469 | return sch; |
470 | errout: | 470 | errout: |
471 | return ERR_PTR(-err); | 471 | return ERR_PTR(err); |
472 | } | 472 | } |
473 | 473 | ||
474 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, | 474 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f98650cc48d8..43460a1cb6d0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4512,7 +4512,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4512 | if (copy_from_user(&getaddrs, optval, len)) | 4512 | if (copy_from_user(&getaddrs, optval, len)) |
4513 | return -EFAULT; | 4513 | return -EFAULT; |
4514 | 4514 | ||
4515 | if (getaddrs.addr_num <= 0) return -EINVAL; | 4515 | if (getaddrs.addr_num <= 0 || |
4516 | getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) | ||
4517 | return -EINVAL; | ||
4516 | /* | 4518 | /* |
4517 | * For UDP-style sockets, id specifies the association to query. | 4519 | * For UDP-style sockets, id specifies the association to query. |
4518 | * If the id field is set to the value '0' then the locally bound | 4520 | * If the id field is set to the value '0' then the locally bound |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index b4280490cf6e..70ceb1604ad8 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -485,8 +485,8 @@ static int unix_socketpair(struct socket *, struct socket *); | |||
485 | static int unix_accept(struct socket *, struct socket *, int); | 485 | static int unix_accept(struct socket *, struct socket *, int); |
486 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); | 486 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); |
487 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); | 487 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); |
488 | static unsigned int unix_datagram_poll(struct file *, struct socket *, | 488 | static unsigned int unix_dgram_poll(struct file *, struct socket *, |
489 | poll_table *); | 489 | poll_table *); |
490 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); | 490 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); |
491 | static int unix_shutdown(struct socket *, int); | 491 | static int unix_shutdown(struct socket *, int); |
492 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, | 492 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, |
@@ -532,7 +532,7 @@ static const struct proto_ops unix_dgram_ops = { | |||
532 | .socketpair = unix_socketpair, | 532 | .socketpair = unix_socketpair, |
533 | .accept = sock_no_accept, | 533 | .accept = sock_no_accept, |
534 | .getname = unix_getname, | 534 | .getname = unix_getname, |
535 | .poll = unix_datagram_poll, | 535 | .poll = unix_dgram_poll, |
536 | .ioctl = unix_ioctl, | 536 | .ioctl = unix_ioctl, |
537 | .listen = sock_no_listen, | 537 | .listen = sock_no_listen, |
538 | .shutdown = unix_shutdown, | 538 | .shutdown = unix_shutdown, |
@@ -553,7 +553,7 @@ static const struct proto_ops unix_seqpacket_ops = { | |||
553 | .socketpair = unix_socketpair, | 553 | .socketpair = unix_socketpair, |
554 | .accept = unix_accept, | 554 | .accept = unix_accept, |
555 | .getname = unix_getname, | 555 | .getname = unix_getname, |
556 | .poll = unix_datagram_poll, | 556 | .poll = unix_dgram_poll, |
557 | .ioctl = unix_ioctl, | 557 | .ioctl = unix_ioctl, |
558 | .listen = unix_listen, | 558 | .listen = unix_listen, |
559 | .shutdown = unix_shutdown, | 559 | .shutdown = unix_shutdown, |
@@ -1992,29 +1992,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl | |||
1992 | return mask; | 1992 | return mask; |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | 1995 | static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, |
1996 | poll_table *wait) | 1996 | poll_table *wait) |
1997 | { | 1997 | { |
1998 | struct sock *sk = sock->sk, *peer; | 1998 | struct sock *sk = sock->sk, *other; |
1999 | unsigned int mask; | 1999 | unsigned int mask, writable; |
2000 | 2000 | ||
2001 | poll_wait(file, sk->sk_sleep, wait); | 2001 | poll_wait(file, sk->sk_sleep, wait); |
2002 | |||
2003 | peer = unix_peer_get(sk); | ||
2004 | if (peer) { | ||
2005 | if (peer != sk) { | ||
2006 | /* | ||
2007 | * Writability of a connected socket additionally | ||
2008 | * depends on the state of the receive queue of the | ||
2009 | * peer. | ||
2010 | */ | ||
2011 | poll_wait(file, &unix_sk(peer)->peer_wait, wait); | ||
2012 | } else { | ||
2013 | sock_put(peer); | ||
2014 | peer = NULL; | ||
2015 | } | ||
2016 | } | ||
2017 | |||
2018 | mask = 0; | 2002 | mask = 0; |
2019 | 2003 | ||
2020 | /* exceptional events? */ | 2004 | /* exceptional events? */ |
@@ -2040,14 +2024,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | |||
2040 | } | 2024 | } |
2041 | 2025 | ||
2042 | /* writable? */ | 2026 | /* writable? */ |
2043 | if (unix_writable(sk) && !(peer && unix_recvq_full(peer))) | 2027 | writable = unix_writable(sk); |
2028 | if (writable) { | ||
2029 | other = unix_peer_get(sk); | ||
2030 | if (other) { | ||
2031 | if (unix_peer(other) != sk) { | ||
2032 | poll_wait(file, &unix_sk(other)->peer_wait, | ||
2033 | wait); | ||
2034 | if (unix_recvq_full(other)) | ||
2035 | writable = 0; | ||
2036 | } | ||
2037 | |||
2038 | sock_put(other); | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | if (writable) | ||
2044 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 2043 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
2045 | else | 2044 | else |
2046 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 2045 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
2047 | 2046 | ||
2048 | if (peer) | ||
2049 | sock_put(peer); | ||
2050 | |||
2051 | return mask; | 2047 | return mask; |
2052 | } | 2048 | } |
2053 | 2049 | ||