diff options
Diffstat (limited to 'net')
80 files changed, 583 insertions, 464 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index dc6f2f26d023..9eb72505308f 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -331,8 +331,10 @@ static void p9_tag_cleanup(struct p9_client *c) | |||
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | if (c->tagpool) | 334 | if (c->tagpool) { |
335 | p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */ | ||
335 | p9_idpool_destroy(c->tagpool); | 336 | p9_idpool_destroy(c->tagpool); |
337 | } | ||
336 | 338 | ||
337 | /* free requests associated with tags */ | 339 | /* free requests associated with tags */ |
338 | for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { | 340 | for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { |
@@ -944,6 +946,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
944 | int16_t nwqids, count; | 946 | int16_t nwqids, count; |
945 | 947 | ||
946 | err = 0; | 948 | err = 0; |
949 | wqids = NULL; | ||
947 | clnt = oldfid->clnt; | 950 | clnt = oldfid->clnt; |
948 | if (clone) { | 951 | if (clone) { |
949 | fid = p9_fid_create(clnt); | 952 | fid = p9_fid_create(clnt); |
@@ -994,9 +997,11 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
994 | else | 997 | else |
995 | fid->qid = oldfid->qid; | 998 | fid->qid = oldfid->qid; |
996 | 999 | ||
1000 | kfree(wqids); | ||
997 | return fid; | 1001 | return fid; |
998 | 1002 | ||
999 | clunk_fid: | 1003 | clunk_fid: |
1004 | kfree(wqids); | ||
1000 | p9_client_clunk(fid); | 1005 | p9_client_clunk(fid); |
1001 | fid = NULL; | 1006 | fid = NULL; |
1002 | 1007 | ||
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 0ea20c30466c..17c5ba7551a5 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
@@ -426,8 +426,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
426 | 426 | ||
427 | /* Allocate an fcall for the reply */ | 427 | /* Allocate an fcall for the reply */ |
428 | rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL); | 428 | rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL); |
429 | if (!rpl_context) | 429 | if (!rpl_context) { |
430 | err = -ENOMEM; | ||
430 | goto err_close; | 431 | goto err_close; |
432 | } | ||
431 | 433 | ||
432 | /* | 434 | /* |
433 | * If the request has a buffer, steal it, otherwise | 435 | * If the request has a buffer, steal it, otherwise |
@@ -445,8 +447,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
445 | } | 447 | } |
446 | rpl_context->rc = req->rc; | 448 | rpl_context->rc = req->rc; |
447 | if (!rpl_context->rc) { | 449 | if (!rpl_context->rc) { |
448 | kfree(rpl_context); | 450 | err = -ENOMEM; |
449 | goto err_close; | 451 | goto err_free2; |
450 | } | 452 | } |
451 | 453 | ||
452 | /* | 454 | /* |
@@ -458,11 +460,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
458 | */ | 460 | */ |
459 | if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) { | 461 | if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) { |
460 | err = post_recv(client, rpl_context); | 462 | err = post_recv(client, rpl_context); |
461 | if (err) { | 463 | if (err) |
462 | kfree(rpl_context->rc); | 464 | goto err_free1; |
463 | kfree(rpl_context); | ||
464 | goto err_close; | ||
465 | } | ||
466 | } else | 465 | } else |
467 | atomic_dec(&rdma->rq_count); | 466 | atomic_dec(&rdma->rq_count); |
468 | 467 | ||
@@ -471,8 +470,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
471 | 470 | ||
472 | /* Post the request */ | 471 | /* Post the request */ |
473 | c = kmalloc(sizeof *c, GFP_KERNEL); | 472 | c = kmalloc(sizeof *c, GFP_KERNEL); |
474 | if (!c) | 473 | if (!c) { |
475 | goto err_close; | 474 | err = -ENOMEM; |
475 | goto err_free1; | ||
476 | } | ||
476 | c->req = req; | 477 | c->req = req; |
477 | 478 | ||
478 | c->busa = ib_dma_map_single(rdma->cm_id->device, | 479 | c->busa = ib_dma_map_single(rdma->cm_id->device, |
@@ -499,9 +500,15 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
499 | return ib_post_send(rdma->qp, &wr, &bad_wr); | 500 | return ib_post_send(rdma->qp, &wr, &bad_wr); |
500 | 501 | ||
501 | error: | 502 | error: |
503 | kfree(c); | ||
504 | kfree(rpl_context->rc); | ||
505 | kfree(rpl_context); | ||
502 | P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n"); | 506 | P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n"); |
503 | return -EIO; | 507 | return -EIO; |
504 | 508 | err_free1: | |
509 | kfree(rpl_context->rc); | ||
510 | err_free2: | ||
511 | kfree(rpl_context); | ||
505 | err_close: | 512 | err_close: |
506 | spin_lock_irqsave(&rdma->req_lock, flags); | 513 | spin_lock_irqsave(&rdma->req_lock, flags); |
507 | if (rdma->state < P9_RDMA_CLOSING) { | 514 | if (rdma->state < P9_RDMA_CLOSING) { |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index dcfbe99ff81c..b88515936e4b 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -329,7 +329,8 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
329 | 329 | ||
330 | mutex_lock(&virtio_9p_lock); | 330 | mutex_lock(&virtio_9p_lock); |
331 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { | 331 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { |
332 | if (!strncmp(devname, chan->tag, chan->tag_len)) { | 332 | if (!strncmp(devname, chan->tag, chan->tag_len) && |
333 | strlen(devname) == chan->tag_len) { | ||
333 | if (!chan->inuse) { | 334 | if (!chan->inuse) { |
334 | chan->inuse = true; | 335 | chan->inuse = true; |
335 | found = 1; | 336 | found = 1; |
diff --git a/net/Kconfig b/net/Kconfig index e330594d3709..e926884c1675 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -217,7 +217,7 @@ source "net/dns_resolver/Kconfig" | |||
217 | 217 | ||
218 | config RPS | 218 | config RPS |
219 | boolean | 219 | boolean |
220 | depends on SMP && SYSFS | 220 | depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS |
221 | default y | 221 | default y |
222 | 222 | ||
223 | menu "Network testing" | 223 | menu "Network testing" |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 651babdfab38..ad2b232a2055 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -399,12 +399,6 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) | |||
399 | unregister_netdev(net_dev); | 399 | unregister_netdev(net_dev); |
400 | free_netdev(net_dev); | 400 | free_netdev(net_dev); |
401 | } | 401 | } |
402 | read_lock_irq(&devs_lock); | ||
403 | if (list_empty(&br2684_devs)) { | ||
404 | /* last br2684 device */ | ||
405 | unregister_atmdevice_notifier(&atm_dev_notifier); | ||
406 | } | ||
407 | read_unlock_irq(&devs_lock); | ||
408 | return; | 402 | return; |
409 | } | 403 | } |
410 | 404 | ||
@@ -675,7 +669,6 @@ static int br2684_create(void __user *arg) | |||
675 | 669 | ||
676 | if (list_empty(&br2684_devs)) { | 670 | if (list_empty(&br2684_devs)) { |
677 | /* 1st br2684 device */ | 671 | /* 1st br2684 device */ |
678 | register_atmdevice_notifier(&atm_dev_notifier); | ||
679 | brdev->number = 1; | 672 | brdev->number = 1; |
680 | } else | 673 | } else |
681 | brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; | 674 | brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; |
@@ -815,6 +808,7 @@ static int __init br2684_init(void) | |||
815 | return -ENOMEM; | 808 | return -ENOMEM; |
816 | #endif | 809 | #endif |
817 | register_atm_ioctl(&br2684_ioctl_ops); | 810 | register_atm_ioctl(&br2684_ioctl_ops); |
811 | register_atmdevice_notifier(&atm_dev_notifier); | ||
818 | return 0; | 812 | return 0; |
819 | } | 813 | } |
820 | 814 | ||
@@ -830,9 +824,7 @@ static void __exit br2684_exit(void) | |||
830 | #endif | 824 | #endif |
831 | 825 | ||
832 | 826 | ||
833 | /* if not already empty */ | 827 | unregister_atmdevice_notifier(&atm_dev_notifier); |
834 | if (!list_empty(&br2684_devs)) | ||
835 | unregister_atmdevice_notifier(&atm_dev_notifier); | ||
836 | 828 | ||
837 | while (!list_empty(&br2684_devs)) { | 829 | while (!list_empty(&br2684_devs)) { |
838 | net_dev = list_entry_brdev(br2684_devs.next); | 830 | net_dev = list_entry_brdev(br2684_devs.next); |
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c index 2ce79df00680..c7d81436213d 100644 --- a/net/ax25/ax25_ds_timer.c +++ b/net/ax25/ax25_ds_timer.c | |||
@@ -112,8 +112,8 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25) | |||
112 | if (sk) { | 112 | if (sk) { |
113 | sock_hold(sk); | 113 | sock_hold(sk); |
114 | ax25_destroy_socket(ax25); | 114 | ax25_destroy_socket(ax25); |
115 | sock_put(sk); | ||
116 | bh_unlock_sock(sk); | 115 | bh_unlock_sock(sk); |
116 | sock_put(sk); | ||
117 | } else | 117 | } else |
118 | ax25_destroy_socket(ax25); | 118 | ax25_destroy_socket(ax25); |
119 | return; | 119 | return; |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 2c911c0759c2..137f23259a93 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -162,8 +162,8 @@ static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) | |||
162 | if (tmp) { | 162 | if (tmp) { |
163 | memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); | 163 | memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); |
164 | atomic_set(&tmp->use, 1); | 164 | atomic_set(&tmp->use, 1); |
165 | nf_bridge_put(nf_bridge); | ||
166 | } | 165 | } |
166 | nf_bridge_put(nf_bridge); | ||
167 | nf_bridge = tmp; | 167 | nf_bridge = tmp; |
168 | } | 168 | } |
169 | return nf_bridge; | 169 | return nf_bridge; |
@@ -761,9 +761,11 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) | |||
761 | { | 761 | { |
762 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && | 762 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && |
763 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && | 763 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && |
764 | !skb_is_gso(skb)) | 764 | !skb_is_gso(skb)) { |
765 | /* BUG: Should really parse the IP options here. */ | ||
766 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
765 | return ip_fragment(skb, br_dev_queue_push_xmit); | 767 | return ip_fragment(skb, br_dev_queue_push_xmit); |
766 | else | 768 | } else |
767 | return br_dev_queue_push_xmit(skb); | 769 | return br_dev_queue_push_xmit(skb); |
768 | } | 770 | } |
769 | #else | 771 | #else |
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index eb1602022ac0..9a699242d104 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/stddef.h> | 7 | #include <linux/stddef.h> |
8 | #include <linux/spinlock.h> | 8 | #include <linux/spinlock.h> |
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/unaligned/le_byteshift.h> | 10 | #include <asm/unaligned.h> |
11 | #include <net/caif/caif_layer.h> | 11 | #include <net/caif/caif_layer.h> |
12 | #include <net/caif/cfsrvl.h> | 12 | #include <net/caif/cfsrvl.h> |
13 | #include <net/caif/cfpkt.h> | 13 | #include <net/caif/cfpkt.h> |
diff --git a/net/core/dev.c b/net/core/dev.c index 3721fbb9a83c..660dd41aaaa6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2058,16 +2058,16 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
2058 | struct sk_buff *skb) | 2058 | struct sk_buff *skb) |
2059 | { | 2059 | { |
2060 | int queue_index; | 2060 | int queue_index; |
2061 | struct sock *sk = skb->sk; | 2061 | const struct net_device_ops *ops = dev->netdev_ops; |
2062 | 2062 | ||
2063 | queue_index = sk_tx_queue_get(sk); | 2063 | if (ops->ndo_select_queue) { |
2064 | if (queue_index < 0) { | 2064 | queue_index = ops->ndo_select_queue(dev, skb); |
2065 | const struct net_device_ops *ops = dev->netdev_ops; | 2065 | queue_index = dev_cap_txqueue(dev, queue_index); |
2066 | } else { | ||
2067 | struct sock *sk = skb->sk; | ||
2068 | queue_index = sk_tx_queue_get(sk); | ||
2069 | if (queue_index < 0) { | ||
2066 | 2070 | ||
2067 | if (ops->ndo_select_queue) { | ||
2068 | queue_index = ops->ndo_select_queue(dev, skb); | ||
2069 | queue_index = dev_cap_txqueue(dev, queue_index); | ||
2070 | } else { | ||
2071 | queue_index = 0; | 2071 | queue_index = 0; |
2072 | if (dev->real_num_tx_queues > 1) | 2072 | if (dev->real_num_tx_queues > 1) |
2073 | queue_index = skb_tx_hash(dev, skb); | 2073 | queue_index = skb_tx_hash(dev, skb); |
@@ -4845,7 +4845,7 @@ static void rollback_registered_many(struct list_head *head) | |||
4845 | dev = list_first_entry(head, struct net_device, unreg_list); | 4845 | dev = list_first_entry(head, struct net_device, unreg_list); |
4846 | call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); | 4846 | call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); |
4847 | 4847 | ||
4848 | synchronize_net(); | 4848 | rcu_barrier(); |
4849 | 4849 | ||
4850 | list_for_each_entry(dev, head, unreg_list) | 4850 | list_for_each_entry(dev, head, unreg_list) |
4851 | dev_put(dev); | 4851 | dev_put(dev); |
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 9fbe7f7429b0..6743146e4d6b 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -232,7 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | |||
232 | est->last_packets = bstats->packets; | 232 | est->last_packets = bstats->packets; |
233 | est->avpps = rate_est->pps<<10; | 233 | est->avpps = rate_est->pps<<10; |
234 | 234 | ||
235 | spin_lock(&est_tree_lock); | 235 | spin_lock_bh(&est_tree_lock); |
236 | if (!elist[idx].timer.function) { | 236 | if (!elist[idx].timer.function) { |
237 | INIT_LIST_HEAD(&elist[idx].list); | 237 | INIT_LIST_HEAD(&elist[idx].list); |
238 | setup_timer(&elist[idx].timer, est_timer, idx); | 238 | setup_timer(&elist[idx].timer, est_timer, idx); |
@@ -243,7 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | |||
243 | 243 | ||
244 | list_add_rcu(&est->list, &elist[idx].list); | 244 | list_add_rcu(&est->list, &elist[idx].list); |
245 | gen_add_node(est); | 245 | gen_add_node(est); |
246 | spin_unlock(&est_tree_lock); | 246 | spin_unlock_bh(&est_tree_lock); |
247 | 247 | ||
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
@@ -270,7 +270,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | |||
270 | { | 270 | { |
271 | struct gen_estimator *e; | 271 | struct gen_estimator *e; |
272 | 272 | ||
273 | spin_lock(&est_tree_lock); | 273 | spin_lock_bh(&est_tree_lock); |
274 | while ((e = gen_find_node(bstats, rate_est))) { | 274 | while ((e = gen_find_node(bstats, rate_est))) { |
275 | rb_erase(&e->node, &est_root); | 275 | rb_erase(&e->node, &est_root); |
276 | 276 | ||
@@ -281,7 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | |||
281 | list_del_rcu(&e->list); | 281 | list_del_rcu(&e->list); |
282 | call_rcu(&e->e_rcu, __gen_kill_estimator); | 282 | call_rcu(&e->e_rcu, __gen_kill_estimator); |
283 | } | 283 | } |
284 | spin_unlock(&est_tree_lock); | 284 | spin_unlock_bh(&est_tree_lock); |
285 | } | 285 | } |
286 | EXPORT_SYMBOL(gen_kill_estimator); | 286 | EXPORT_SYMBOL(gen_kill_estimator); |
287 | 287 | ||
@@ -320,9 +320,9 @@ bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, | |||
320 | 320 | ||
321 | ASSERT_RTNL(); | 321 | ASSERT_RTNL(); |
322 | 322 | ||
323 | spin_lock(&est_tree_lock); | 323 | spin_lock_bh(&est_tree_lock); |
324 | res = gen_find_node(bstats, rate_est) != NULL; | 324 | res = gen_find_node(bstats, rate_est) != NULL; |
325 | spin_unlock(&est_tree_lock); | 325 | spin_unlock_bh(&est_tree_lock); |
326 | 326 | ||
327 | return res; | 327 | return res; |
328 | } | 328 | } |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 1cd98df412df..e6b133b77ccb 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -35,9 +35,10 @@ | |||
35 | * in any case. | 35 | * in any case. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) | 38 | long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) |
39 | { | 39 | { |
40 | int size, err, ct; | 40 | int size, ct; |
41 | long err; | ||
41 | 42 | ||
42 | if (m->msg_namelen) { | 43 | if (m->msg_namelen) { |
43 | if (mode == VERIFY_READ) { | 44 | if (mode == VERIFY_READ) { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3a2513f0d0c3..c83b421341c0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2573,6 +2573,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
2573 | __copy_skb_header(nskb, skb); | 2573 | __copy_skb_header(nskb, skb); |
2574 | nskb->mac_len = skb->mac_len; | 2574 | nskb->mac_len = skb->mac_len; |
2575 | 2575 | ||
2576 | /* nskb and skb might have different headroom */ | ||
2577 | if (nskb->ip_summed == CHECKSUM_PARTIAL) | ||
2578 | nskb->csum_start += skb_headroom(nskb) - headroom; | ||
2579 | |||
2576 | skb_reset_mac_header(nskb); | 2580 | skb_reset_mac_header(nskb); |
2577 | skb_set_network_header(nskb, skb->mac_len); | 2581 | skb_set_network_header(nskb, skb->mac_len); |
2578 | nskb->transport_header = (nskb->network_header + | 2582 | nskb->transport_header = (nskb->network_header + |
@@ -2703,7 +2707,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2703 | return -E2BIG; | 2707 | return -E2BIG; |
2704 | 2708 | ||
2705 | headroom = skb_headroom(p); | 2709 | headroom = skb_headroom(p); |
2706 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | 2710 | nskb = alloc_skb(headroom + skb_gro_offset(p), GFP_ATOMIC); |
2707 | if (unlikely(!nskb)) | 2711 | if (unlikely(!nskb)) |
2708 | return -ENOMEM; | 2712 | return -ENOMEM; |
2709 | 2713 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index b05b9b6ddb87..ef30e9d286e7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1351,9 +1351,9 @@ int sock_i_uid(struct sock *sk) | |||
1351 | { | 1351 | { |
1352 | int uid; | 1352 | int uid; |
1353 | 1353 | ||
1354 | read_lock(&sk->sk_callback_lock); | 1354 | read_lock_bh(&sk->sk_callback_lock); |
1355 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; | 1355 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; |
1356 | read_unlock(&sk->sk_callback_lock); | 1356 | read_unlock_bh(&sk->sk_callback_lock); |
1357 | return uid; | 1357 | return uid; |
1358 | } | 1358 | } |
1359 | EXPORT_SYMBOL(sock_i_uid); | 1359 | EXPORT_SYMBOL(sock_i_uid); |
@@ -1362,9 +1362,9 @@ unsigned long sock_i_ino(struct sock *sk) | |||
1362 | { | 1362 | { |
1363 | unsigned long ino; | 1363 | unsigned long ino; |
1364 | 1364 | ||
1365 | read_lock(&sk->sk_callback_lock); | 1365 | read_lock_bh(&sk->sk_callback_lock); |
1366 | ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; | 1366 | ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; |
1367 | read_unlock(&sk->sk_callback_lock); | 1367 | read_unlock_bh(&sk->sk_callback_lock); |
1368 | return ino; | 1368 | return ino; |
1369 | } | 1369 | } |
1370 | EXPORT_SYMBOL(sock_i_ino); | 1370 | EXPORT_SYMBOL(sock_i_ino); |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 7c3a7d191249..571f8950ed06 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -46,7 +46,7 @@ config IP_ADVANCED_ROUTER | |||
46 | rp_filter on use: | 46 | rp_filter on use: |
47 | 47 | ||
48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter | 48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter |
49 | and | 49 | or |
50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter | 50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter |
51 | 51 | ||
52 | Note that some distributions enable it in startup scripts. | 52 | Note that some distributions enable it in startup scripts. |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index f0550941df7b..721a8a37b45c 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
@@ -62,8 +62,11 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
62 | } | 62 | } |
63 | if (!inet->inet_saddr) | 63 | if (!inet->inet_saddr) |
64 | inet->inet_saddr = rt->rt_src; /* Update source address */ | 64 | inet->inet_saddr = rt->rt_src; /* Update source address */ |
65 | if (!inet->inet_rcv_saddr) | 65 | if (!inet->inet_rcv_saddr) { |
66 | inet->inet_rcv_saddr = rt->rt_src; | 66 | inet->inet_rcv_saddr = rt->rt_src; |
67 | if (sk->sk_prot->rehash) | ||
68 | sk->sk_prot->rehash(sk); | ||
69 | } | ||
67 | inet->inet_daddr = rt->rt_dst; | 70 | inet->inet_daddr = rt->rt_dst; |
68 | inet->inet_dport = usin->sin_port; | 71 | inet->inet_dport = usin->sin_port; |
69 | sk->sk_state = TCP_ESTABLISHED; | 72 | sk->sk_state = TCP_ESTABLISHED; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index a43968918350..7d02a9f999fa 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -246,6 +246,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
246 | 246 | ||
247 | struct fib_result res; | 247 | struct fib_result res; |
248 | int no_addr, rpf, accept_local; | 248 | int no_addr, rpf, accept_local; |
249 | bool dev_match; | ||
249 | int ret; | 250 | int ret; |
250 | struct net *net; | 251 | struct net *net; |
251 | 252 | ||
@@ -273,12 +274,22 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
273 | } | 274 | } |
274 | *spec_dst = FIB_RES_PREFSRC(res); | 275 | *spec_dst = FIB_RES_PREFSRC(res); |
275 | fib_combine_itag(itag, &res); | 276 | fib_combine_itag(itag, &res); |
277 | dev_match = false; | ||
278 | |||
276 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 279 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
277 | if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1) | 280 | for (ret = 0; ret < res.fi->fib_nhs; ret++) { |
281 | struct fib_nh *nh = &res.fi->fib_nh[ret]; | ||
282 | |||
283 | if (nh->nh_dev == dev) { | ||
284 | dev_match = true; | ||
285 | break; | ||
286 | } | ||
287 | } | ||
278 | #else | 288 | #else |
279 | if (FIB_RES_DEV(res) == dev) | 289 | if (FIB_RES_DEV(res) == dev) |
290 | dev_match = true; | ||
280 | #endif | 291 | #endif |
281 | { | 292 | if (dev_match) { |
282 | ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; | 293 | ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; |
283 | fib_res_put(&res); | 294 | fib_res_put(&res); |
284 | return ret; | 295 | return ret; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 79d057a939ba..4a8e370862bc 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -186,7 +186,9 @@ static inline struct tnode *node_parent_rcu(struct node *node) | |||
186 | { | 186 | { |
187 | struct tnode *ret = node_parent(node); | 187 | struct tnode *ret = node_parent(node); |
188 | 188 | ||
189 | return rcu_dereference(ret); | 189 | return rcu_dereference_check(ret, |
190 | rcu_read_lock_held() || | ||
191 | lockdep_rtnl_is_held()); | ||
190 | } | 192 | } |
191 | 193 | ||
192 | /* Same as rcu_assign_pointer | 194 | /* Same as rcu_assign_pointer |
@@ -1753,7 +1755,9 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) | |||
1753 | 1755 | ||
1754 | static struct leaf *trie_firstleaf(struct trie *t) | 1756 | static struct leaf *trie_firstleaf(struct trie *t) |
1755 | { | 1757 | { |
1756 | struct tnode *n = (struct tnode *) rcu_dereference(t->trie); | 1758 | struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie, |
1759 | rcu_read_lock_held() || | ||
1760 | lockdep_rtnl_is_held()); | ||
1757 | 1761 | ||
1758 | if (!n) | 1762 | if (!n) |
1759 | return NULL; | 1763 | return NULL; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index a1ad0e7180d2..1fdcacd36ce7 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -834,7 +834,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, | |||
834 | int mark = 0; | 834 | int mark = 0; |
835 | 835 | ||
836 | 836 | ||
837 | if (len == 8) { | 837 | if (len == 8 || IGMP_V2_SEEN(in_dev)) { |
838 | if (ih->code == 0) { | 838 | if (ih->code == 0) { |
839 | /* Alas, old v1 router presents here. */ | 839 | /* Alas, old v1 router presents here. */ |
840 | 840 | ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 945b20a5ad50..35c93e8b6a46 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <net/netns/generic.h> | 45 | #include <net/netns/generic.h> |
46 | #include <net/rtnetlink.h> | 46 | #include <net/rtnetlink.h> |
47 | 47 | ||
48 | #ifdef CONFIG_IPV6 | 48 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
49 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
50 | #include <net/ip6_fib.h> | 50 | #include <net/ip6_fib.h> |
51 | #include <net/ip6_route.h> | 51 | #include <net/ip6_route.h> |
@@ -699,7 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
699 | if ((dst = rt->rt_gateway) == 0) | 699 | if ((dst = rt->rt_gateway) == 0) |
700 | goto tx_error_icmp; | 700 | goto tx_error_icmp; |
701 | } | 701 | } |
702 | #ifdef CONFIG_IPV6 | 702 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
703 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 703 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
704 | struct in6_addr *addr6; | 704 | struct in6_addr *addr6; |
705 | int addr_type; | 705 | int addr_type; |
@@ -774,7 +774,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
774 | goto tx_error; | 774 | goto tx_error; |
775 | } | 775 | } |
776 | } | 776 | } |
777 | #ifdef CONFIG_IPV6 | 777 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
778 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 778 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); | 779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); |
780 | 780 | ||
@@ -850,7 +850,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
850 | if ((iph->ttl = tiph->ttl) == 0) { | 850 | if ((iph->ttl = tiph->ttl) == 0) { |
851 | if (skb->protocol == htons(ETH_P_IP)) | 851 | if (skb->protocol == htons(ETH_P_IP)) |
852 | iph->ttl = old_iph->ttl; | 852 | iph->ttl = old_iph->ttl; |
853 | #ifdef CONFIG_IPV6 | 853 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
854 | else if (skb->protocol == htons(ETH_P_IPV6)) | 854 | else if (skb->protocol == htons(ETH_P_IPV6)) |
855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; | 855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; |
856 | #endif | 856 | #endif |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 04b69896df5f..7649d7750075 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -488,9 +488,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
488 | * we can switch to copy when see the first bad fragment. | 488 | * we can switch to copy when see the first bad fragment. |
489 | */ | 489 | */ |
490 | if (skb_has_frags(skb)) { | 490 | if (skb_has_frags(skb)) { |
491 | struct sk_buff *frag; | 491 | struct sk_buff *frag, *frag2; |
492 | int first_len = skb_pagelen(skb); | 492 | int first_len = skb_pagelen(skb); |
493 | int truesizes = 0; | ||
494 | 493 | ||
495 | if (first_len - hlen > mtu || | 494 | if (first_len - hlen > mtu || |
496 | ((first_len - hlen) & 7) || | 495 | ((first_len - hlen) & 7) || |
@@ -503,18 +502,18 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
503 | if (frag->len > mtu || | 502 | if (frag->len > mtu || |
504 | ((frag->len & 7) && frag->next) || | 503 | ((frag->len & 7) && frag->next) || |
505 | skb_headroom(frag) < hlen) | 504 | skb_headroom(frag) < hlen) |
506 | goto slow_path; | 505 | goto slow_path_clean; |
507 | 506 | ||
508 | /* Partially cloned skb? */ | 507 | /* Partially cloned skb? */ |
509 | if (skb_shared(frag)) | 508 | if (skb_shared(frag)) |
510 | goto slow_path; | 509 | goto slow_path_clean; |
511 | 510 | ||
512 | BUG_ON(frag->sk); | 511 | BUG_ON(frag->sk); |
513 | if (skb->sk) { | 512 | if (skb->sk) { |
514 | frag->sk = skb->sk; | 513 | frag->sk = skb->sk; |
515 | frag->destructor = sock_wfree; | 514 | frag->destructor = sock_wfree; |
516 | } | 515 | } |
517 | truesizes += frag->truesize; | 516 | skb->truesize -= frag->truesize; |
518 | } | 517 | } |
519 | 518 | ||
520 | /* Everything is OK. Generate! */ | 519 | /* Everything is OK. Generate! */ |
@@ -524,7 +523,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
524 | frag = skb_shinfo(skb)->frag_list; | 523 | frag = skb_shinfo(skb)->frag_list; |
525 | skb_frag_list_init(skb); | 524 | skb_frag_list_init(skb); |
526 | skb->data_len = first_len - skb_headlen(skb); | 525 | skb->data_len = first_len - skb_headlen(skb); |
527 | skb->truesize -= truesizes; | ||
528 | skb->len = first_len; | 526 | skb->len = first_len; |
529 | iph->tot_len = htons(first_len); | 527 | iph->tot_len = htons(first_len); |
530 | iph->frag_off = htons(IP_MF); | 528 | iph->frag_off = htons(IP_MF); |
@@ -576,6 +574,15 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
576 | } | 574 | } |
577 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); | 575 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
578 | return err; | 576 | return err; |
577 | |||
578 | slow_path_clean: | ||
579 | skb_walk_frags(skb, frag2) { | ||
580 | if (frag2 == frag) | ||
581 | break; | ||
582 | frag2->sk = NULL; | ||
583 | frag2->destructor = NULL; | ||
584 | skb->truesize += frag2->truesize; | ||
585 | } | ||
579 | } | 586 | } |
580 | 587 | ||
581 | slow_path: | 588 | slow_path: |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 6c40a8c46e79..64b70ad162e3 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -1129,6 +1129,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1129 | case IP_HDRINCL: | 1129 | case IP_HDRINCL: |
1130 | val = inet->hdrincl; | 1130 | val = inet->hdrincl; |
1131 | break; | 1131 | break; |
1132 | case IP_NODEFRAG: | ||
1133 | val = inet->nodefrag; | ||
1134 | break; | ||
1132 | case IP_MTU_DISCOVER: | 1135 | case IP_MTU_DISCOVER: |
1133 | val = inet->pmtudisc; | 1136 | val = inet->pmtudisc; |
1134 | break; | 1137 | break; |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index b254dafaf429..43eec80c0e7c 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -112,6 +112,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
112 | /* ip_route_me_harder expects skb->dst to be set */ | 112 | /* ip_route_me_harder expects skb->dst to be set */ |
113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); | 113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); |
114 | 114 | ||
115 | nskb->protocol = htons(ETH_P_IP); | ||
115 | if (ip_route_me_harder(nskb, addr_type)) | 116 | if (ip_route_me_harder(nskb, addr_type)) |
116 | goto free_nskb; | 117 | goto free_nskb; |
117 | 118 | ||
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index eab8de32f200..f3a9b42b16c6 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -66,9 +66,11 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | |||
66 | const struct net_device *out, | 66 | const struct net_device *out, |
67 | int (*okfn)(struct sk_buff *)) | 67 | int (*okfn)(struct sk_buff *)) |
68 | { | 68 | { |
69 | struct sock *sk = skb->sk; | ||
69 | struct inet_sock *inet = inet_sk(skb->sk); | 70 | struct inet_sock *inet = inet_sk(skb->sk); |
70 | 71 | ||
71 | if (inet && inet->nodefrag) | 72 | if (sk && (sk->sk_family == PF_INET) && |
73 | inet->nodefrag) | ||
72 | return NF_ACCEPT; | 74 | return NF_ACCEPT; |
73 | 75 | ||
74 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 76 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 1679e2c0963d..ee5f419d0a56 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -893,13 +893,15 @@ static void fast_csum(__sum16 *csum, | |||
893 | unsigned char s[4]; | 893 | unsigned char s[4]; |
894 | 894 | ||
895 | if (offset & 1) { | 895 | if (offset & 1) { |
896 | s[0] = s[2] = 0; | 896 | s[0] = ~0; |
897 | s[1] = ~*optr; | 897 | s[1] = ~*optr; |
898 | s[2] = 0; | ||
898 | s[3] = *nptr; | 899 | s[3] = *nptr; |
899 | } else { | 900 | } else { |
900 | s[1] = s[3] = 0; | ||
901 | s[0] = ~*optr; | 901 | s[0] = ~*optr; |
902 | s[1] = ~0; | ||
902 | s[2] = *nptr; | 903 | s[2] = *nptr; |
904 | s[3] = 0; | ||
903 | } | 905 | } |
904 | 906 | ||
905 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); | 907 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3f56b6e6c6aa..ac6559cb54f9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1231,7 +1231,7 @@ restart: | |||
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | if (net_ratelimit()) | 1233 | if (net_ratelimit()) |
1234 | printk(KERN_WARNING "Neighbour table overflow.\n"); | 1234 | printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); |
1235 | rt_drop(rt); | 1235 | rt_drop(rt); |
1236 | return -ENOBUFS; | 1236 | return -ENOBUFS; |
1237 | } | 1237 | } |
@@ -2738,6 +2738,11 @@ slow_output: | |||
2738 | } | 2738 | } |
2739 | EXPORT_SYMBOL_GPL(__ip_route_output_key); | 2739 | EXPORT_SYMBOL_GPL(__ip_route_output_key); |
2740 | 2740 | ||
2741 | static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie) | ||
2742 | { | ||
2743 | return NULL; | ||
2744 | } | ||
2745 | |||
2741 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2746 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
2742 | { | 2747 | { |
2743 | } | 2748 | } |
@@ -2746,7 +2751,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2746 | .family = AF_INET, | 2751 | .family = AF_INET, |
2747 | .protocol = cpu_to_be16(ETH_P_IP), | 2752 | .protocol = cpu_to_be16(ETH_P_IP), |
2748 | .destroy = ipv4_dst_destroy, | 2753 | .destroy = ipv4_dst_destroy, |
2749 | .check = ipv4_dst_check, | 2754 | .check = ipv4_blackhole_dst_check, |
2750 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2755 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2751 | .entries = ATOMIC_INIT(0), | 2756 | .entries = ATOMIC_INIT(0), |
2752 | }; | 2757 | }; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 176e11aaea77..f115ea68a4ef 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -386,8 +386,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
386 | */ | 386 | */ |
387 | 387 | ||
388 | mask = 0; | 388 | mask = 0; |
389 | if (sk->sk_err) | ||
390 | mask = POLLERR; | ||
391 | 389 | ||
392 | /* | 390 | /* |
393 | * POLLHUP is certainly not done right. But poll() doesn't | 391 | * POLLHUP is certainly not done right. But poll() doesn't |
@@ -451,11 +449,17 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
451 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 449 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
452 | mask |= POLLOUT | POLLWRNORM; | 450 | mask |= POLLOUT | POLLWRNORM; |
453 | } | 451 | } |
454 | } | 452 | } else |
453 | mask |= POLLOUT | POLLWRNORM; | ||
455 | 454 | ||
456 | if (tp->urg_data & TCP_URG_VALID) | 455 | if (tp->urg_data & TCP_URG_VALID) |
457 | mask |= POLLPRI; | 456 | mask |= POLLPRI; |
458 | } | 457 | } |
458 | /* This barrier is coupled with smp_wmb() in tcp_reset() */ | ||
459 | smp_rmb(); | ||
460 | if (sk->sk_err) | ||
461 | mask |= POLLERR; | ||
462 | |||
459 | return mask; | 463 | return mask; |
460 | } | 464 | } |
461 | EXPORT_SYMBOL(tcp_poll); | 465 | EXPORT_SYMBOL(tcp_poll); |
@@ -939,7 +943,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
939 | sg = sk->sk_route_caps & NETIF_F_SG; | 943 | sg = sk->sk_route_caps & NETIF_F_SG; |
940 | 944 | ||
941 | while (--iovlen >= 0) { | 945 | while (--iovlen >= 0) { |
942 | int seglen = iov->iov_len; | 946 | size_t seglen = iov->iov_len; |
943 | unsigned char __user *from = iov->iov_base; | 947 | unsigned char __user *from = iov->iov_base; |
944 | 948 | ||
945 | iov++; | 949 | iov++; |
@@ -2011,11 +2015,8 @@ adjudge_to_death: | |||
2011 | } | 2015 | } |
2012 | } | 2016 | } |
2013 | if (sk->sk_state != TCP_CLOSE) { | 2017 | if (sk->sk_state != TCP_CLOSE) { |
2014 | int orphan_count = percpu_counter_read_positive( | ||
2015 | sk->sk_prot->orphan_count); | ||
2016 | |||
2017 | sk_mem_reclaim(sk); | 2018 | sk_mem_reclaim(sk); |
2018 | if (tcp_too_many_orphans(sk, orphan_count)) { | 2019 | if (tcp_too_many_orphans(sk, 0)) { |
2019 | if (net_ratelimit()) | 2020 | if (net_ratelimit()) |
2020 | printk(KERN_INFO "TCP: too many of orphaned " | 2021 | printk(KERN_INFO "TCP: too many of orphaned " |
2021 | "sockets\n"); | 2022 | "sockets\n"); |
@@ -3212,7 +3213,7 @@ void __init tcp_init(void) | |||
3212 | { | 3213 | { |
3213 | struct sk_buff *skb = NULL; | 3214 | struct sk_buff *skb = NULL; |
3214 | unsigned long nr_pages, limit; | 3215 | unsigned long nr_pages, limit; |
3215 | int order, i, max_share; | 3216 | int i, max_share, cnt; |
3216 | unsigned long jiffy = jiffies; | 3217 | unsigned long jiffy = jiffies; |
3217 | 3218 | ||
3218 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); | 3219 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); |
@@ -3261,22 +3262,12 @@ void __init tcp_init(void) | |||
3261 | INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain); | 3262 | INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain); |
3262 | } | 3263 | } |
3263 | 3264 | ||
3264 | /* Try to be a bit smarter and adjust defaults depending | 3265 | |
3265 | * on available memory. | 3266 | cnt = tcp_hashinfo.ehash_mask + 1; |
3266 | */ | 3267 | |
3267 | for (order = 0; ((1 << order) << PAGE_SHIFT) < | 3268 | tcp_death_row.sysctl_max_tw_buckets = cnt / 2; |
3268 | (tcp_hashinfo.bhash_size * sizeof(struct inet_bind_hashbucket)); | 3269 | sysctl_tcp_max_orphans = cnt / 2; |
3269 | order++) | 3270 | sysctl_max_syn_backlog = max(128, cnt / 256); |
3270 | ; | ||
3271 | if (order >= 4) { | ||
3272 | tcp_death_row.sysctl_max_tw_buckets = 180000; | ||
3273 | sysctl_tcp_max_orphans = 4096 << (order - 4); | ||
3274 | sysctl_max_syn_backlog = 1024; | ||
3275 | } else if (order < 3) { | ||
3276 | tcp_death_row.sysctl_max_tw_buckets >>= (3 - order); | ||
3277 | sysctl_tcp_max_orphans >>= (3 - order); | ||
3278 | sysctl_max_syn_backlog = 128; | ||
3279 | } | ||
3280 | 3271 | ||
3281 | /* Set the pressure threshold to be a fraction of global memory that | 3272 | /* Set the pressure threshold to be a fraction of global memory that |
3282 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | 3273 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 0ec9bd0ae94f..850c737e08e2 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -196,10 +196,10 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen) | |||
196 | int tcp_set_allowed_congestion_control(char *val) | 196 | int tcp_set_allowed_congestion_control(char *val) |
197 | { | 197 | { |
198 | struct tcp_congestion_ops *ca; | 198 | struct tcp_congestion_ops *ca; |
199 | char *clone, *name; | 199 | char *saved_clone, *clone, *name; |
200 | int ret = 0; | 200 | int ret = 0; |
201 | 201 | ||
202 | clone = kstrdup(val, GFP_USER); | 202 | saved_clone = clone = kstrdup(val, GFP_USER); |
203 | if (!clone) | 203 | if (!clone) |
204 | return -ENOMEM; | 204 | return -ENOMEM; |
205 | 205 | ||
@@ -226,6 +226,7 @@ int tcp_set_allowed_congestion_control(char *val) | |||
226 | } | 226 | } |
227 | out: | 227 | out: |
228 | spin_unlock(&tcp_cong_list_lock); | 228 | spin_unlock(&tcp_cong_list_lock); |
229 | kfree(saved_clone); | ||
229 | 230 | ||
230 | return ret; | 231 | return ret; |
231 | } | 232 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e663b78a2ef6..b55f60f6fcbe 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2545,7 +2545,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2545 | cnt += tcp_skb_pcount(skb); | 2545 | cnt += tcp_skb_pcount(skb); |
2546 | 2546 | ||
2547 | if (cnt > packets) { | 2547 | if (cnt > packets) { |
2548 | if (tcp_is_sack(tp) || (oldcnt >= packets)) | 2548 | if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) || |
2549 | (oldcnt >= packets)) | ||
2549 | break; | 2550 | break; |
2550 | 2551 | ||
2551 | mss = skb_shinfo(skb)->gso_size; | 2552 | mss = skb_shinfo(skb)->gso_size; |
@@ -4048,6 +4049,8 @@ static void tcp_reset(struct sock *sk) | |||
4048 | default: | 4049 | default: |
4049 | sk->sk_err = ECONNRESET; | 4050 | sk->sk_err = ECONNRESET; |
4050 | } | 4051 | } |
4052 | /* This barrier is coupled with smp_rmb() in tcp_poll() */ | ||
4053 | smp_wmb(); | ||
4051 | 4054 | ||
4052 | if (!sock_flag(sk, SOCK_DEAD)) | 4055 | if (!sock_flag(sk, SOCK_DEAD)) |
4053 | sk->sk_error_report(sk); | 4056 | sk->sk_error_report(sk); |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 808bb920c9f5..c35b469e851c 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -66,18 +66,18 @@ static void tcp_write_err(struct sock *sk) | |||
66 | static int tcp_out_of_resources(struct sock *sk, int do_reset) | 66 | static int tcp_out_of_resources(struct sock *sk, int do_reset) |
67 | { | 67 | { |
68 | struct tcp_sock *tp = tcp_sk(sk); | 68 | struct tcp_sock *tp = tcp_sk(sk); |
69 | int orphans = percpu_counter_read_positive(&tcp_orphan_count); | 69 | int shift = 0; |
70 | 70 | ||
71 | /* If peer does not open window for long time, or did not transmit | 71 | /* If peer does not open window for long time, or did not transmit |
72 | * anything for long time, penalize it. */ | 72 | * anything for long time, penalize it. */ |
73 | if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) | 73 | if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) |
74 | orphans <<= 1; | 74 | shift++; |
75 | 75 | ||
76 | /* If some dubious ICMP arrived, penalize even more. */ | 76 | /* If some dubious ICMP arrived, penalize even more. */ |
77 | if (sk->sk_err_soft) | 77 | if (sk->sk_err_soft) |
78 | orphans <<= 1; | 78 | shift++; |
79 | 79 | ||
80 | if (tcp_too_many_orphans(sk, orphans)) { | 80 | if (tcp_too_many_orphans(sk, shift)) { |
81 | if (net_ratelimit()) | 81 | if (net_ratelimit()) |
82 | printk(KERN_INFO "Out of socket memory\n"); | 82 | printk(KERN_INFO "Out of socket memory\n"); |
83 | 83 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 32e0bef60d0a..fb23c2e63b52 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1260,6 +1260,49 @@ void udp_lib_unhash(struct sock *sk) | |||
1260 | } | 1260 | } |
1261 | EXPORT_SYMBOL(udp_lib_unhash); | 1261 | EXPORT_SYMBOL(udp_lib_unhash); |
1262 | 1262 | ||
1263 | /* | ||
1264 | * inet_rcv_saddr was changed, we must rehash secondary hash | ||
1265 | */ | ||
1266 | void udp_lib_rehash(struct sock *sk, u16 newhash) | ||
1267 | { | ||
1268 | if (sk_hashed(sk)) { | ||
1269 | struct udp_table *udptable = sk->sk_prot->h.udp_table; | ||
1270 | struct udp_hslot *hslot, *hslot2, *nhslot2; | ||
1271 | |||
1272 | hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); | ||
1273 | nhslot2 = udp_hashslot2(udptable, newhash); | ||
1274 | udp_sk(sk)->udp_portaddr_hash = newhash; | ||
1275 | if (hslot2 != nhslot2) { | ||
1276 | hslot = udp_hashslot(udptable, sock_net(sk), | ||
1277 | udp_sk(sk)->udp_port_hash); | ||
1278 | /* we must lock primary chain too */ | ||
1279 | spin_lock_bh(&hslot->lock); | ||
1280 | |||
1281 | spin_lock(&hslot2->lock); | ||
1282 | hlist_nulls_del_init_rcu(&udp_sk(sk)->udp_portaddr_node); | ||
1283 | hslot2->count--; | ||
1284 | spin_unlock(&hslot2->lock); | ||
1285 | |||
1286 | spin_lock(&nhslot2->lock); | ||
1287 | hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, | ||
1288 | &nhslot2->head); | ||
1289 | nhslot2->count++; | ||
1290 | spin_unlock(&nhslot2->lock); | ||
1291 | |||
1292 | spin_unlock_bh(&hslot->lock); | ||
1293 | } | ||
1294 | } | ||
1295 | } | ||
1296 | EXPORT_SYMBOL(udp_lib_rehash); | ||
1297 | |||
1298 | static void udp_v4_rehash(struct sock *sk) | ||
1299 | { | ||
1300 | u16 new_hash = udp4_portaddr_hash(sock_net(sk), | ||
1301 | inet_sk(sk)->inet_rcv_saddr, | ||
1302 | inet_sk(sk)->inet_num); | ||
1303 | udp_lib_rehash(sk, new_hash); | ||
1304 | } | ||
1305 | |||
1263 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | 1306 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) |
1264 | { | 1307 | { |
1265 | int rc; | 1308 | int rc; |
@@ -1843,6 +1886,7 @@ struct proto udp_prot = { | |||
1843 | .backlog_rcv = __udp_queue_rcv_skb, | 1886 | .backlog_rcv = __udp_queue_rcv_skb, |
1844 | .hash = udp_lib_hash, | 1887 | .hash = udp_lib_hash, |
1845 | .unhash = udp_lib_unhash, | 1888 | .unhash = udp_lib_unhash, |
1889 | .rehash = udp_v4_rehash, | ||
1846 | .get_port = udp_v4_get_port, | 1890 | .get_port = udp_v4_get_port, |
1847 | .memory_allocated = &udp_memory_allocated, | 1891 | .memory_allocated = &udp_memory_allocated, |
1848 | .sysctl_mem = sysctl_udp_mem, | 1892 | .sysctl_mem = sysctl_udp_mem, |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 869078d4eeb9..a580349f0b8a 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -61,7 +61,7 @@ static int xfrm4_get_saddr(struct net *net, | |||
61 | 61 | ||
62 | static int xfrm4_get_tos(struct flowi *fl) | 62 | static int xfrm4_get_tos(struct flowi *fl) |
63 | { | 63 | { |
64 | return fl->fl4_tos; | 64 | return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */ |
65 | } | 65 | } |
66 | 66 | ||
67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, | 67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 1ef1366a0a03..47947624eccc 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
@@ -21,21 +21,25 @@ static int xfrm4_init_flags(struct xfrm_state *x) | |||
21 | } | 21 | } |
22 | 22 | ||
23 | static void | 23 | static void |
24 | __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 24 | __xfrm4_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
25 | struct xfrm_tmpl *tmpl, | 25 | { |
26 | xfrm_address_t *daddr, xfrm_address_t *saddr) | 26 | sel->daddr.a4 = fl->fl4_dst; |
27 | sel->saddr.a4 = fl->fl4_src; | ||
28 | sel->dport = xfrm_flowi_dport(fl); | ||
29 | sel->dport_mask = htons(0xffff); | ||
30 | sel->sport = xfrm_flowi_sport(fl); | ||
31 | sel->sport_mask = htons(0xffff); | ||
32 | sel->family = AF_INET; | ||
33 | sel->prefixlen_d = 32; | ||
34 | sel->prefixlen_s = 32; | ||
35 | sel->proto = fl->proto; | ||
36 | sel->ifindex = fl->oif; | ||
37 | } | ||
38 | |||
39 | static void | ||
40 | xfrm4_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
41 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
27 | { | 42 | { |
28 | x->sel.daddr.a4 = fl->fl4_dst; | ||
29 | x->sel.saddr.a4 = fl->fl4_src; | ||
30 | x->sel.dport = xfrm_flowi_dport(fl); | ||
31 | x->sel.dport_mask = htons(0xffff); | ||
32 | x->sel.sport = xfrm_flowi_sport(fl); | ||
33 | x->sel.sport_mask = htons(0xffff); | ||
34 | x->sel.family = AF_INET; | ||
35 | x->sel.prefixlen_d = 32; | ||
36 | x->sel.prefixlen_s = 32; | ||
37 | x->sel.proto = fl->proto; | ||
38 | x->sel.ifindex = fl->oif; | ||
39 | x->id = tmpl->id; | 43 | x->id = tmpl->id; |
40 | if (x->id.daddr.a4 == 0) | 44 | if (x->id.daddr.a4 == 0) |
41 | x->id.daddr.a4 = daddr->a4; | 45 | x->id.daddr.a4 = daddr->a4; |
@@ -70,6 +74,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { | |||
70 | .owner = THIS_MODULE, | 74 | .owner = THIS_MODULE, |
71 | .init_flags = xfrm4_init_flags, | 75 | .init_flags = xfrm4_init_flags, |
72 | .init_tempsel = __xfrm4_init_tempsel, | 76 | .init_tempsel = __xfrm4_init_tempsel, |
77 | .init_temprop = xfrm4_init_temprop, | ||
73 | .output = xfrm4_output, | 78 | .output = xfrm4_output, |
74 | .extract_input = xfrm4_extract_input, | 79 | .extract_input = xfrm4_extract_input, |
75 | .extract_output = xfrm4_extract_output, | 80 | .extract_output = xfrm4_extract_output, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ab70a3fbcafa..324fac3b6c16 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4637,10 +4637,12 @@ int __init addrconf_init(void) | |||
4637 | if (err < 0) { | 4637 | if (err < 0) { |
4638 | printk(KERN_CRIT "IPv6 Addrconf:" | 4638 | printk(KERN_CRIT "IPv6 Addrconf:" |
4639 | " cannot initialize default policy table: %d.\n", err); | 4639 | " cannot initialize default policy table: %d.\n", err); |
4640 | return err; | 4640 | goto out; |
4641 | } | 4641 | } |
4642 | 4642 | ||
4643 | register_pernet_subsys(&addrconf_ops); | 4643 | err = register_pernet_subsys(&addrconf_ops); |
4644 | if (err < 0) | ||
4645 | goto out_addrlabel; | ||
4644 | 4646 | ||
4645 | /* The addrconf netdev notifier requires that loopback_dev | 4647 | /* The addrconf netdev notifier requires that loopback_dev |
4646 | * has it's ipv6 private information allocated and setup | 4648 | * has it's ipv6 private information allocated and setup |
@@ -4692,7 +4694,9 @@ errout: | |||
4692 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4694 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4693 | errlo: | 4695 | errlo: |
4694 | unregister_pernet_subsys(&addrconf_ops); | 4696 | unregister_pernet_subsys(&addrconf_ops); |
4695 | 4697 | out_addrlabel: | |
4698 | ipv6_addr_label_cleanup(); | ||
4699 | out: | ||
4696 | return err; | 4700 | return err; |
4697 | } | 4701 | } |
4698 | 4702 | ||
@@ -4703,6 +4707,7 @@ void addrconf_cleanup(void) | |||
4703 | 4707 | ||
4704 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4708 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4705 | unregister_pernet_subsys(&addrconf_ops); | 4709 | unregister_pernet_subsys(&addrconf_ops); |
4710 | ipv6_addr_label_cleanup(); | ||
4706 | 4711 | ||
4707 | rtnl_lock(); | 4712 | rtnl_lock(); |
4708 | 4713 | ||
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index f0e774cea386..8175f802651b 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -393,6 +393,11 @@ int __init ipv6_addr_label_init(void) | |||
393 | return register_pernet_subsys(&ipv6_addr_label_ops); | 393 | return register_pernet_subsys(&ipv6_addr_label_ops); |
394 | } | 394 | } |
395 | 395 | ||
396 | void ipv6_addr_label_cleanup(void) | ||
397 | { | ||
398 | unregister_pernet_subsys(&ipv6_addr_label_ops); | ||
399 | } | ||
400 | |||
396 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { | 401 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { |
397 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, | 402 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, |
398 | [IFAL_LABEL] = { .len = sizeof(u32), }, | 403 | [IFAL_LABEL] = { .len = sizeof(u32), }, |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 7d929a22cbc2..ef371aa01ac5 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -105,9 +105,12 @@ ipv4_connected: | |||
105 | if (ipv6_addr_any(&np->saddr)) | 105 | if (ipv6_addr_any(&np->saddr)) |
106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
107 | 107 | ||
108 | if (ipv6_addr_any(&np->rcv_saddr)) | 108 | if (ipv6_addr_any(&np->rcv_saddr)) { |
109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, | 109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, |
110 | &np->rcv_saddr); | 110 | &np->rcv_saddr); |
111 | if (sk->sk_prot->rehash) | ||
112 | sk->sk_prot->rehash(sk); | ||
113 | } | ||
111 | 114 | ||
112 | goto out; | 115 | goto out; |
113 | } | 116 | } |
@@ -181,6 +184,8 @@ ipv4_connected: | |||
181 | if (ipv6_addr_any(&np->rcv_saddr)) { | 184 | if (ipv6_addr_any(&np->rcv_saddr)) { |
182 | ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); | 185 | ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); |
183 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 186 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
187 | if (sk->sk_prot->rehash) | ||
188 | sk->sk_prot->rehash(sk); | ||
184 | } | 189 | } |
185 | 190 | ||
186 | ip6_dst_store(sk, dst, | 191 | ip6_dst_store(sk, dst, |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d40b330c0ee6..980912ed7a38 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -639,7 +639,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
639 | 639 | ||
640 | if (skb_has_frags(skb)) { | 640 | if (skb_has_frags(skb)) { |
641 | int first_len = skb_pagelen(skb); | 641 | int first_len = skb_pagelen(skb); |
642 | int truesizes = 0; | 642 | struct sk_buff *frag2; |
643 | 643 | ||
644 | if (first_len - hlen > mtu || | 644 | if (first_len - hlen > mtu || |
645 | ((first_len - hlen) & 7) || | 645 | ((first_len - hlen) & 7) || |
@@ -651,18 +651,18 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
651 | if (frag->len > mtu || | 651 | if (frag->len > mtu || |
652 | ((frag->len & 7) && frag->next) || | 652 | ((frag->len & 7) && frag->next) || |
653 | skb_headroom(frag) < hlen) | 653 | skb_headroom(frag) < hlen) |
654 | goto slow_path; | 654 | goto slow_path_clean; |
655 | 655 | ||
656 | /* Partially cloned skb? */ | 656 | /* Partially cloned skb? */ |
657 | if (skb_shared(frag)) | 657 | if (skb_shared(frag)) |
658 | goto slow_path; | 658 | goto slow_path_clean; |
659 | 659 | ||
660 | BUG_ON(frag->sk); | 660 | BUG_ON(frag->sk); |
661 | if (skb->sk) { | 661 | if (skb->sk) { |
662 | frag->sk = skb->sk; | 662 | frag->sk = skb->sk; |
663 | frag->destructor = sock_wfree; | 663 | frag->destructor = sock_wfree; |
664 | truesizes += frag->truesize; | ||
665 | } | 664 | } |
665 | skb->truesize -= frag->truesize; | ||
666 | } | 666 | } |
667 | 667 | ||
668 | err = 0; | 668 | err = 0; |
@@ -693,7 +693,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
693 | 693 | ||
694 | first_len = skb_pagelen(skb); | 694 | first_len = skb_pagelen(skb); |
695 | skb->data_len = first_len - skb_headlen(skb); | 695 | skb->data_len = first_len - skb_headlen(skb); |
696 | skb->truesize -= truesizes; | ||
697 | skb->len = first_len; | 696 | skb->len = first_len; |
698 | ipv6_hdr(skb)->payload_len = htons(first_len - | 697 | ipv6_hdr(skb)->payload_len = htons(first_len - |
699 | sizeof(struct ipv6hdr)); | 698 | sizeof(struct ipv6hdr)); |
@@ -756,6 +755,15 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
756 | IPSTATS_MIB_FRAGFAILS); | 755 | IPSTATS_MIB_FRAGFAILS); |
757 | dst_release(&rt->dst); | 756 | dst_release(&rt->dst); |
758 | return err; | 757 | return err; |
758 | |||
759 | slow_path_clean: | ||
760 | skb_walk_frags(skb, frag2) { | ||
761 | if (frag2 == frag) | ||
762 | break; | ||
763 | frag2->sk = NULL; | ||
764 | frag2->destructor = NULL; | ||
765 | skb->truesize += frag2->truesize; | ||
766 | } | ||
759 | } | 767 | } |
760 | 768 | ||
761 | slow_path: | 769 | slow_path: |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 13ef5bc05cf5..578f3c1a16db 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -113,14 +113,6 @@ static void nf_skb_free(struct sk_buff *skb) | |||
113 | kfree_skb(NFCT_FRAG6_CB(skb)->orig); | 113 | kfree_skb(NFCT_FRAG6_CB(skb)->orig); |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Memory Tracking Functions. */ | ||
117 | static void frag_kfree_skb(struct sk_buff *skb) | ||
118 | { | ||
119 | atomic_sub(skb->truesize, &nf_init_frags.mem); | ||
120 | nf_skb_free(skb); | ||
121 | kfree_skb(skb); | ||
122 | } | ||
123 | |||
124 | /* Destruction primitives. */ | 116 | /* Destruction primitives. */ |
125 | 117 | ||
126 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) | 118 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) |
@@ -282,66 +274,22 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, | |||
282 | } | 274 | } |
283 | 275 | ||
284 | found: | 276 | found: |
285 | /* We found where to put this one. Check for overlap with | 277 | /* RFC5722, Section 4: |
286 | * preceding fragment, and, if needed, align things so that | 278 | * When reassembling an IPv6 datagram, if |
287 | * any overlaps are eliminated. | 279 | * one or more its constituent fragments is determined to be an |
288 | */ | 280 | * overlapping fragment, the entire datagram (and any constituent |
289 | if (prev) { | 281 | * fragments, including those not yet received) MUST be silently |
290 | int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset; | 282 | * discarded. |
291 | |||
292 | if (i > 0) { | ||
293 | offset += i; | ||
294 | if (end <= offset) { | ||
295 | pr_debug("overlap\n"); | ||
296 | goto err; | ||
297 | } | ||
298 | if (!pskb_pull(skb, i)) { | ||
299 | pr_debug("Can't pull\n"); | ||
300 | goto err; | ||
301 | } | ||
302 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) | ||
303 | skb->ip_summed = CHECKSUM_NONE; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* Look for overlap with succeeding segments. | ||
308 | * If we can merge fragments, do it. | ||
309 | */ | 283 | */ |
310 | while (next && NFCT_FRAG6_CB(next)->offset < end) { | ||
311 | /* overlap is 'i' bytes */ | ||
312 | int i = end - NFCT_FRAG6_CB(next)->offset; | ||
313 | |||
314 | if (i < next->len) { | ||
315 | /* Eat head of the next overlapped fragment | ||
316 | * and leave the loop. The next ones cannot overlap. | ||
317 | */ | ||
318 | pr_debug("Eat head of the overlapped parts.: %d", i); | ||
319 | if (!pskb_pull(next, i)) | ||
320 | goto err; | ||
321 | 284 | ||
322 | /* next fragment */ | 285 | /* Check for overlap with preceding fragment. */ |
323 | NFCT_FRAG6_CB(next)->offset += i; | 286 | if (prev && |
324 | fq->q.meat -= i; | 287 | (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0) |
325 | if (next->ip_summed != CHECKSUM_UNNECESSARY) | 288 | goto discard_fq; |
326 | next->ip_summed = CHECKSUM_NONE; | ||
327 | break; | ||
328 | } else { | ||
329 | struct sk_buff *free_it = next; | ||
330 | |||
331 | /* Old fragmnet is completely overridden with | ||
332 | * new one drop it. | ||
333 | */ | ||
334 | next = next->next; | ||
335 | 289 | ||
336 | if (prev) | 290 | /* Look for overlap with succeeding segment. */ |
337 | prev->next = next; | 291 | if (next && NFCT_FRAG6_CB(next)->offset < end) |
338 | else | 292 | goto discard_fq; |
339 | fq->q.fragments = next; | ||
340 | |||
341 | fq->q.meat -= free_it->len; | ||
342 | frag_kfree_skb(free_it); | ||
343 | } | ||
344 | } | ||
345 | 293 | ||
346 | NFCT_FRAG6_CB(skb)->offset = offset; | 294 | NFCT_FRAG6_CB(skb)->offset = offset; |
347 | 295 | ||
@@ -371,6 +319,8 @@ found: | |||
371 | write_unlock(&nf_frags.lock); | 319 | write_unlock(&nf_frags.lock); |
372 | return 0; | 320 | return 0; |
373 | 321 | ||
322 | discard_fq: | ||
323 | fq_kill(fq); | ||
374 | err: | 324 | err: |
375 | return -1; | 325 | return -1; |
376 | } | 326 | } |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 545c4141b755..64cfef1b0a4c 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -149,13 +149,6 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a) | |||
149 | } | 149 | } |
150 | EXPORT_SYMBOL(ip6_frag_match); | 150 | EXPORT_SYMBOL(ip6_frag_match); |
151 | 151 | ||
152 | /* Memory Tracking Functions. */ | ||
153 | static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb) | ||
154 | { | ||
155 | atomic_sub(skb->truesize, &nf->mem); | ||
156 | kfree_skb(skb); | ||
157 | } | ||
158 | |||
159 | void ip6_frag_init(struct inet_frag_queue *q, void *a) | 152 | void ip6_frag_init(struct inet_frag_queue *q, void *a) |
160 | { | 153 | { |
161 | struct frag_queue *fq = container_of(q, struct frag_queue, q); | 154 | struct frag_queue *fq = container_of(q, struct frag_queue, q); |
@@ -346,58 +339,22 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
346 | } | 339 | } |
347 | 340 | ||
348 | found: | 341 | found: |
349 | /* We found where to put this one. Check for overlap with | 342 | /* RFC5722, Section 4: |
350 | * preceding fragment, and, if needed, align things so that | 343 | * When reassembling an IPv6 datagram, if |
351 | * any overlaps are eliminated. | 344 | * one or more its constituent fragments is determined to be an |
345 | * overlapping fragment, the entire datagram (and any constituent | ||
346 | * fragments, including those not yet received) MUST be silently | ||
347 | * discarded. | ||
352 | */ | 348 | */ |
353 | if (prev) { | ||
354 | int i = (FRAG6_CB(prev)->offset + prev->len) - offset; | ||
355 | 349 | ||
356 | if (i > 0) { | 350 | /* Check for overlap with preceding fragment. */ |
357 | offset += i; | 351 | if (prev && |
358 | if (end <= offset) | 352 | (FRAG6_CB(prev)->offset + prev->len) - offset > 0) |
359 | goto err; | 353 | goto discard_fq; |
360 | if (!pskb_pull(skb, i)) | ||
361 | goto err; | ||
362 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) | ||
363 | skb->ip_summed = CHECKSUM_NONE; | ||
364 | } | ||
365 | } | ||
366 | 354 | ||
367 | /* Look for overlap with succeeding segments. | 355 | /* Look for overlap with succeeding segment. */ |
368 | * If we can merge fragments, do it. | 356 | if (next && FRAG6_CB(next)->offset < end) |
369 | */ | 357 | goto discard_fq; |
370 | while (next && FRAG6_CB(next)->offset < end) { | ||
371 | int i = end - FRAG6_CB(next)->offset; /* overlap is 'i' bytes */ | ||
372 | |||
373 | if (i < next->len) { | ||
374 | /* Eat head of the next overlapped fragment | ||
375 | * and leave the loop. The next ones cannot overlap. | ||
376 | */ | ||
377 | if (!pskb_pull(next, i)) | ||
378 | goto err; | ||
379 | FRAG6_CB(next)->offset += i; /* next fragment */ | ||
380 | fq->q.meat -= i; | ||
381 | if (next->ip_summed != CHECKSUM_UNNECESSARY) | ||
382 | next->ip_summed = CHECKSUM_NONE; | ||
383 | break; | ||
384 | } else { | ||
385 | struct sk_buff *free_it = next; | ||
386 | |||
387 | /* Old fragment is completely overridden with | ||
388 | * new one drop it. | ||
389 | */ | ||
390 | next = next->next; | ||
391 | |||
392 | if (prev) | ||
393 | prev->next = next; | ||
394 | else | ||
395 | fq->q.fragments = next; | ||
396 | |||
397 | fq->q.meat -= free_it->len; | ||
398 | frag_kfree_skb(fq->q.net, free_it); | ||
399 | } | ||
400 | } | ||
401 | 358 | ||
402 | FRAG6_CB(skb)->offset = offset; | 359 | FRAG6_CB(skb)->offset = offset; |
403 | 360 | ||
@@ -436,6 +393,8 @@ found: | |||
436 | write_unlock(&ip6_frags.lock); | 393 | write_unlock(&ip6_frags.lock); |
437 | return -1; | 394 | return -1; |
438 | 395 | ||
396 | discard_fq: | ||
397 | fq_kill(fq); | ||
439 | err: | 398 | err: |
440 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 399 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
441 | IPSTATS_MIB_REASMFAILS); | 400 | IPSTATS_MIB_REASMFAILS); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d126365ac046..8323136bdc54 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -670,7 +670,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad | |||
670 | 670 | ||
671 | if (net_ratelimit()) | 671 | if (net_ratelimit()) |
672 | printk(KERN_WARNING | 672 | printk(KERN_WARNING |
673 | "Neighbour table overflow.\n"); | 673 | "ipv6: Neighbour table overflow.\n"); |
674 | dst_free(&rt->dst); | 674 | dst_free(&rt->dst); |
675 | return NULL; | 675 | return NULL; |
676 | } | 676 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 1dd1affdead2..5acb3560ff15 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -111,6 +111,15 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
111 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr); | 111 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void udp_v6_rehash(struct sock *sk) | ||
115 | { | ||
116 | u16 new_hash = udp6_portaddr_hash(sock_net(sk), | ||
117 | &inet6_sk(sk)->rcv_saddr, | ||
118 | inet_sk(sk)->inet_num); | ||
119 | |||
120 | udp_lib_rehash(sk, new_hash); | ||
121 | } | ||
122 | |||
114 | static inline int compute_score(struct sock *sk, struct net *net, | 123 | static inline int compute_score(struct sock *sk, struct net *net, |
115 | unsigned short hnum, | 124 | unsigned short hnum, |
116 | struct in6_addr *saddr, __be16 sport, | 125 | struct in6_addr *saddr, __be16 sport, |
@@ -1447,6 +1456,7 @@ struct proto udpv6_prot = { | |||
1447 | .backlog_rcv = udpv6_queue_rcv_skb, | 1456 | .backlog_rcv = udpv6_queue_rcv_skb, |
1448 | .hash = udp_lib_hash, | 1457 | .hash = udp_lib_hash, |
1449 | .unhash = udp_lib_unhash, | 1458 | .unhash = udp_lib_unhash, |
1459 | .rehash = udp_v6_rehash, | ||
1450 | .get_port = udp_v6_get_port, | 1460 | .get_port = udp_v6_get_port, |
1451 | .memory_allocated = &udp_memory_allocated, | 1461 | .memory_allocated = &udp_memory_allocated, |
1452 | .sysctl_mem = sysctl_udp_mem, | 1462 | .sysctl_mem = sysctl_udp_mem, |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index f417b77fa0e1..a67575d472a3 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -20,23 +20,27 @@ | |||
20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
21 | 21 | ||
22 | static void | 22 | static void |
23 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 23 | __xfrm6_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
24 | struct xfrm_tmpl *tmpl, | ||
25 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
26 | { | 24 | { |
27 | /* Initialize temporary selector matching only | 25 | /* Initialize temporary selector matching only |
28 | * to current session. */ | 26 | * to current session. */ |
29 | ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst); | 27 | ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst); |
30 | ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src); | 28 | ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src); |
31 | x->sel.dport = xfrm_flowi_dport(fl); | 29 | sel->dport = xfrm_flowi_dport(fl); |
32 | x->sel.dport_mask = htons(0xffff); | 30 | sel->dport_mask = htons(0xffff); |
33 | x->sel.sport = xfrm_flowi_sport(fl); | 31 | sel->sport = xfrm_flowi_sport(fl); |
34 | x->sel.sport_mask = htons(0xffff); | 32 | sel->sport_mask = htons(0xffff); |
35 | x->sel.family = AF_INET6; | 33 | sel->family = AF_INET6; |
36 | x->sel.prefixlen_d = 128; | 34 | sel->prefixlen_d = 128; |
37 | x->sel.prefixlen_s = 128; | 35 | sel->prefixlen_s = 128; |
38 | x->sel.proto = fl->proto; | 36 | sel->proto = fl->proto; |
39 | x->sel.ifindex = fl->oif; | 37 | sel->ifindex = fl->oif; |
38 | } | ||
39 | |||
40 | static void | ||
41 | xfrm6_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
42 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
43 | { | ||
40 | x->id = tmpl->id; | 44 | x->id = tmpl->id; |
41 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) | 45 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) |
42 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); | 46 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); |
@@ -168,6 +172,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
168 | .eth_proto = htons(ETH_P_IPV6), | 172 | .eth_proto = htons(ETH_P_IPV6), |
169 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
170 | .init_tempsel = __xfrm6_init_tempsel, | 174 | .init_tempsel = __xfrm6_init_tempsel, |
175 | .init_temprop = xfrm6_init_temprop, | ||
171 | .tmpl_sort = __xfrm6_tmpl_sort, | 176 | .tmpl_sort = __xfrm6_tmpl_sort, |
172 | .state_sort = __xfrm6_state_sort, | 177 | .state_sort = __xfrm6_state_sort, |
173 | .output = xfrm6_output, | 178 | .output = xfrm6_output, |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 79986a674f6e..fd55b5135de5 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -824,8 +824,8 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
824 | 824 | ||
825 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); | 825 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); |
826 | if (err < 0) { | 826 | if (err < 0) { |
827 | kfree(self->ias_obj->name); | 827 | irias_delete_object(self->ias_obj); |
828 | kfree(self->ias_obj); | 828 | self->ias_obj = NULL; |
829 | goto out; | 829 | goto out; |
830 | } | 830 | } |
831 | 831 | ||
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index a788f9e9427d..6130f9d9dbe1 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c | |||
@@ -1102,7 +1102,7 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len) | |||
1102 | memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ | 1102 | memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ |
1103 | le16_to_cpus(&val_len); n+=2; | 1103 | le16_to_cpus(&val_len); n+=2; |
1104 | 1104 | ||
1105 | if (val_len > 1016) { | 1105 | if (val_len >= 1016) { |
1106 | IRDA_DEBUG(2, "%s(), parameter length to long\n", __func__ ); | 1106 | IRDA_DEBUG(2, "%s(), parameter length to long\n", __func__ ); |
1107 | return -RSP_INVALID_COMMAND_FORMAT; | 1107 | return -RSP_INVALID_COMMAND_FORMAT; |
1108 | } | 1108 | } |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 58c6c4cda73b..1ae697681bc7 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -132,7 +132,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, | |||
132 | printk("\n"); | 132 | printk("\n"); |
133 | } | 133 | } |
134 | 134 | ||
135 | if (data_len < ETH_HLEN) | 135 | if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) |
136 | goto error; | 136 | goto error; |
137 | 137 | ||
138 | secpath_reset(skb); | 138 | secpath_reset(skb); |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 023ba820236f..582612998211 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -1024,7 +1024,8 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, | |||
1024 | { | 1024 | { |
1025 | struct sock *sk = sock->sk; | 1025 | struct sock *sk = sock->sk; |
1026 | struct llc_sock *llc = llc_sk(sk); | 1026 | struct llc_sock *llc = llc_sk(sk); |
1027 | int rc = -EINVAL, opt; | 1027 | unsigned int opt; |
1028 | int rc = -EINVAL; | ||
1028 | 1029 | ||
1029 | lock_sock(sk); | 1030 | lock_sock(sk); |
1030 | if (unlikely(level != SOL_LLC || optlen != sizeof(int))) | 1031 | if (unlikely(level != SOL_LLC || optlen != sizeof(int))) |
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c index e4dae0244d76..cf4aea3ba30f 100644 --- a/net/llc/llc_station.c +++ b/net/llc/llc_station.c | |||
@@ -689,7 +689,7 @@ static void llc_station_rcv(struct sk_buff *skb) | |||
689 | 689 | ||
690 | int __init llc_station_init(void) | 690 | int __init llc_station_init(void) |
691 | { | 691 | { |
692 | u16 rc = -ENOBUFS; | 692 | int rc = -ENOBUFS; |
693 | struct sk_buff *skb; | 693 | struct sk_buff *skb; |
694 | struct llc_station_state_ev *ev; | 694 | struct llc_station_state_ev *ev; |
695 | 695 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 798a91b100cc..ded5c3843e06 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -732,6 +732,12 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
732 | 732 | ||
733 | rtnl_unlock(); | 733 | rtnl_unlock(); |
734 | 734 | ||
735 | /* | ||
736 | * Now all work items will be gone, but the | ||
737 | * timer might still be armed, so delete it | ||
738 | */ | ||
739 | del_timer_sync(&local->work_timer); | ||
740 | |||
735 | cancel_work_sync(&local->reconfig_filter); | 741 | cancel_work_sync(&local->reconfig_filter); |
736 | 742 | ||
737 | ieee80211_clear_tx_pending(local); | 743 | ieee80211_clear_tx_pending(local); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 4f8ddba48011..4c2f89df5cce 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -924,6 +924,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
924 | 924 | ||
925 | ip_vs_out_stats(cp, skb); | 925 | ip_vs_out_stats(cp, skb); |
926 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); | 926 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); |
927 | ip_vs_update_conntrack(skb, cp, 0); | ||
927 | ip_vs_conn_put(cp); | 928 | ip_vs_conn_put(cp); |
928 | 929 | ||
929 | skb->ipvs_property = 1; | 930 | skb->ipvs_property = 1; |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index f228a17ec649..7e9af5b76d9e 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/netfilter.h> | 45 | #include <linux/netfilter.h> |
46 | #include <net/netfilter/nf_conntrack.h> | 46 | #include <net/netfilter/nf_conntrack.h> |
47 | #include <net/netfilter/nf_conntrack_expect.h> | 47 | #include <net/netfilter/nf_conntrack_expect.h> |
48 | #include <net/netfilter/nf_nat.h> | ||
48 | #include <net/netfilter/nf_nat_helper.h> | 49 | #include <net/netfilter/nf_nat_helper.h> |
49 | #include <linux/gfp.h> | 50 | #include <linux/gfp.h> |
50 | #include <net/protocol.h> | 51 | #include <net/protocol.h> |
@@ -359,7 +360,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
359 | buf_len = strlen(buf); | 360 | buf_len = strlen(buf); |
360 | 361 | ||
361 | ct = nf_ct_get(skb, &ctinfo); | 362 | ct = nf_ct_get(skb, &ctinfo); |
362 | if (ct && !nf_ct_is_untracked(ct)) { | 363 | if (ct && !nf_ct_is_untracked(ct) && nfct_nat(ct)) { |
363 | /* If mangling fails this function will return 0 | 364 | /* If mangling fails this function will return 0 |
364 | * which will cause the packet to be dropped. | 365 | * which will cause the packet to be dropped. |
365 | * Mangling can only fail under memory pressure, | 366 | * Mangling can only fail under memory pressure, |
@@ -409,7 +410,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
409 | union nf_inet_addr to; | 410 | union nf_inet_addr to; |
410 | __be16 port; | 411 | __be16 port; |
411 | struct ip_vs_conn *n_cp; | 412 | struct ip_vs_conn *n_cp; |
412 | struct nf_conn *ct; | ||
413 | 413 | ||
414 | #ifdef CONFIG_IP_VS_IPV6 | 414 | #ifdef CONFIG_IP_VS_IPV6 |
415 | /* This application helper doesn't work with IPv6 yet, | 415 | /* This application helper doesn't work with IPv6 yet, |
@@ -496,11 +496,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
496 | ip_vs_control_add(n_cp, cp); | 496 | ip_vs_control_add(n_cp, cp); |
497 | } | 497 | } |
498 | 498 | ||
499 | ct = (struct nf_conn *)skb->nfct; | ||
500 | if (ct && ct != &nf_conntrack_untracked) | ||
501 | ip_vs_expect_related(skb, ct, n_cp, | ||
502 | IPPROTO_TCP, &n_cp->dport, 1); | ||
503 | |||
504 | /* | 499 | /* |
505 | * Move tunnel to listen state | 500 | * Move tunnel to listen state |
506 | */ | 501 | */ |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 21e1a5e9b9d3..49df6bea6a2d 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -349,8 +349,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
349 | } | 349 | } |
350 | #endif | 350 | #endif |
351 | 351 | ||
352 | static void | 352 | void |
353 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) | 353 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) |
354 | { | 354 | { |
355 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; | 355 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; |
356 | struct nf_conntrack_tuple new_tuple; | 356 | struct nf_conntrack_tuple new_tuple; |
@@ -365,11 +365,17 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) | |||
365 | * real-server we will see RIP->DIP. | 365 | * real-server we will see RIP->DIP. |
366 | */ | 366 | */ |
367 | new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; | 367 | new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
368 | new_tuple.src.u3 = cp->daddr; | 368 | if (outin) |
369 | new_tuple.src.u3 = cp->daddr; | ||
370 | else | ||
371 | new_tuple.dst.u3 = cp->vaddr; | ||
369 | /* | 372 | /* |
370 | * This will also take care of UDP and other protocols. | 373 | * This will also take care of UDP and other protocols. |
371 | */ | 374 | */ |
372 | new_tuple.src.u.tcp.port = cp->dport; | 375 | if (outin) |
376 | new_tuple.src.u.tcp.port = cp->dport; | ||
377 | else | ||
378 | new_tuple.dst.u.tcp.port = cp->vport; | ||
373 | nf_conntrack_alter_reply(ct, &new_tuple); | 379 | nf_conntrack_alter_reply(ct, &new_tuple); |
374 | } | 380 | } |
375 | 381 | ||
@@ -428,7 +434,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
428 | 434 | ||
429 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); | 435 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); |
430 | 436 | ||
431 | ip_vs_update_conntrack(skb, cp); | 437 | ip_vs_update_conntrack(skb, cp, 1); |
432 | 438 | ||
433 | /* FIXME: when application helper enlarges the packet and the length | 439 | /* FIXME: when application helper enlarges the packet and the length |
434 | is larger than the MTU of outgoing device, there will be still | 440 | is larger than the MTU of outgoing device, there will be still |
@@ -506,7 +512,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
506 | 512 | ||
507 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); | 513 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); |
508 | 514 | ||
509 | ip_vs_update_conntrack(skb, cp); | 515 | ip_vs_update_conntrack(skb, cp, 1); |
510 | 516 | ||
511 | /* FIXME: when application helper enlarges the packet and the length | 517 | /* FIXME: when application helper enlarges the packet and the length |
512 | is larger than the MTU of outgoing device, there will be still | 518 | is larger than the MTU of outgoing device, there will be still |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 7dcf7a404190..8d9e4c949b96 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -48,15 +48,17 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) | |||
48 | { | 48 | { |
49 | unsigned int off, len; | 49 | unsigned int off, len; |
50 | struct nf_ct_ext_type *t; | 50 | struct nf_ct_ext_type *t; |
51 | size_t alloc_size; | ||
51 | 52 | ||
52 | rcu_read_lock(); | 53 | rcu_read_lock(); |
53 | t = rcu_dereference(nf_ct_ext_types[id]); | 54 | t = rcu_dereference(nf_ct_ext_types[id]); |
54 | BUG_ON(t == NULL); | 55 | BUG_ON(t == NULL); |
55 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); | 56 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); |
56 | len = off + t->len; | 57 | len = off + t->len; |
58 | alloc_size = t->alloc_size; | ||
57 | rcu_read_unlock(); | 59 | rcu_read_unlock(); |
58 | 60 | ||
59 | *ext = kzalloc(t->alloc_size, gfp); | 61 | *ext = kzalloc(alloc_size, gfp); |
60 | if (!*ext) | 62 | if (!*ext) |
61 | return NULL; | 63 | return NULL; |
62 | 64 | ||
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 53d892210a04..f64de9544866 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1376,7 +1376,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1376 | unsigned int msglen, origlen; | 1376 | unsigned int msglen, origlen; |
1377 | const char *dptr, *end; | 1377 | const char *dptr, *end; |
1378 | s16 diff, tdiff = 0; | 1378 | s16 diff, tdiff = 0; |
1379 | int ret; | 1379 | int ret = NF_ACCEPT; |
1380 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; | 1380 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; |
1381 | 1381 | ||
1382 | if (ctinfo != IP_CT_ESTABLISHED && | 1382 | if (ctinfo != IP_CT_ESTABLISHED && |
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index 5490fc37c92d..daab8c4a903c 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c | |||
@@ -70,7 +70,11 @@ nf_tproxy_destructor(struct sk_buff *skb) | |||
70 | int | 70 | int |
71 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) | 71 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) |
72 | { | 72 | { |
73 | if (inet_sk(sk)->transparent) { | 73 | bool transparent = (sk->sk_state == TCP_TIME_WAIT) ? |
74 | inet_twsk(sk)->tw_transparent : | ||
75 | inet_sk(sk)->transparent; | ||
76 | |||
77 | if (transparent) { | ||
74 | skb_orphan(skb); | 78 | skb_orphan(skb); |
75 | skb->sk = sk; | 79 | skb->sk = sk; |
76 | skb->destructor = nf_tproxy_destructor; | 80 | skb->destructor = nf_tproxy_destructor; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 980fe4ad0016..cd96ed3ccee4 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -2102,6 +2102,26 @@ static void __net_exit netlink_net_exit(struct net *net) | |||
2102 | #endif | 2102 | #endif |
2103 | } | 2103 | } |
2104 | 2104 | ||
2105 | static void __init netlink_add_usersock_entry(void) | ||
2106 | { | ||
2107 | unsigned long *listeners; | ||
2108 | int groups = 32; | ||
2109 | |||
2110 | listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head), | ||
2111 | GFP_KERNEL); | ||
2112 | if (!listeners) | ||
2113 | panic("netlink_add_usersock_entry: Cannot allocate listneres\n"); | ||
2114 | |||
2115 | netlink_table_grab(); | ||
2116 | |||
2117 | nl_table[NETLINK_USERSOCK].groups = groups; | ||
2118 | nl_table[NETLINK_USERSOCK].listeners = listeners; | ||
2119 | nl_table[NETLINK_USERSOCK].module = THIS_MODULE; | ||
2120 | nl_table[NETLINK_USERSOCK].registered = 1; | ||
2121 | |||
2122 | netlink_table_ungrab(); | ||
2123 | } | ||
2124 | |||
2105 | static struct pernet_operations __net_initdata netlink_net_ops = { | 2125 | static struct pernet_operations __net_initdata netlink_net_ops = { |
2106 | .init = netlink_net_init, | 2126 | .init = netlink_net_init, |
2107 | .exit = netlink_net_exit, | 2127 | .exit = netlink_net_exit, |
@@ -2150,6 +2170,8 @@ static int __init netlink_proto_init(void) | |||
2150 | hash->rehash_time = jiffies; | 2170 | hash->rehash_time = jiffies; |
2151 | } | 2171 | } |
2152 | 2172 | ||
2173 | netlink_add_usersock_entry(); | ||
2174 | |||
2153 | sock_register(&netlink_family_ops); | 2175 | sock_register(&netlink_family_ops); |
2154 | register_pernet_subsys(&netlink_net_ops); | 2176 | register_pernet_subsys(&netlink_net_ops); |
2155 | /* The netlink device handler may be needed early. */ | 2177 | /* The netlink device handler may be needed early. */ |
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index c397524c039c..c519939e8da9 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -43,7 +43,7 @@ void rds_tcp_state_change(struct sock *sk) | |||
43 | struct rds_connection *conn; | 43 | struct rds_connection *conn; |
44 | struct rds_tcp_connection *tc; | 44 | struct rds_tcp_connection *tc; |
45 | 45 | ||
46 | read_lock(&sk->sk_callback_lock); | 46 | read_lock_bh(&sk->sk_callback_lock); |
47 | conn = sk->sk_user_data; | 47 | conn = sk->sk_user_data; |
48 | if (conn == NULL) { | 48 | if (conn == NULL) { |
49 | state_change = sk->sk_state_change; | 49 | state_change = sk->sk_state_change; |
@@ -68,7 +68,7 @@ void rds_tcp_state_change(struct sock *sk) | |||
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | out: | 70 | out: |
71 | read_unlock(&sk->sk_callback_lock); | 71 | read_unlock_bh(&sk->sk_callback_lock); |
72 | state_change(sk); | 72 | state_change(sk); |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 975183fe6950..27844f231d10 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -114,7 +114,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) | |||
114 | 114 | ||
115 | rdsdebug("listen data ready sk %p\n", sk); | 115 | rdsdebug("listen data ready sk %p\n", sk); |
116 | 116 | ||
117 | read_lock(&sk->sk_callback_lock); | 117 | read_lock_bh(&sk->sk_callback_lock); |
118 | ready = sk->sk_user_data; | 118 | ready = sk->sk_user_data; |
119 | if (ready == NULL) { /* check for teardown race */ | 119 | if (ready == NULL) { /* check for teardown race */ |
120 | ready = sk->sk_data_ready; | 120 | ready = sk->sk_data_ready; |
@@ -131,7 +131,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) | |||
131 | queue_work(rds_wq, &rds_tcp_listen_work); | 131 | queue_work(rds_wq, &rds_tcp_listen_work); |
132 | 132 | ||
133 | out: | 133 | out: |
134 | read_unlock(&sk->sk_callback_lock); | 134 | read_unlock_bh(&sk->sk_callback_lock); |
135 | ready(sk, bytes); | 135 | ready(sk, bytes); |
136 | } | 136 | } |
137 | 137 | ||
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 1aba6878fa5d..e43797404102 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c | |||
@@ -324,7 +324,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) | |||
324 | 324 | ||
325 | rdsdebug("data ready sk %p bytes %d\n", sk, bytes); | 325 | rdsdebug("data ready sk %p bytes %d\n", sk, bytes); |
326 | 326 | ||
327 | read_lock(&sk->sk_callback_lock); | 327 | read_lock_bh(&sk->sk_callback_lock); |
328 | conn = sk->sk_user_data; | 328 | conn = sk->sk_user_data; |
329 | if (conn == NULL) { /* check for teardown race */ | 329 | if (conn == NULL) { /* check for teardown race */ |
330 | ready = sk->sk_data_ready; | 330 | ready = sk->sk_data_ready; |
@@ -338,7 +338,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) | |||
338 | if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) | 338 | if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) |
339 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); | 339 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); |
340 | out: | 340 | out: |
341 | read_unlock(&sk->sk_callback_lock); | 341 | read_unlock_bh(&sk->sk_callback_lock); |
342 | ready(sk, bytes); | 342 | ready(sk, bytes); |
343 | } | 343 | } |
344 | 344 | ||
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index a28b895ff0d1..2f012a07d94d 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c | |||
@@ -224,7 +224,7 @@ void rds_tcp_write_space(struct sock *sk) | |||
224 | struct rds_connection *conn; | 224 | struct rds_connection *conn; |
225 | struct rds_tcp_connection *tc; | 225 | struct rds_tcp_connection *tc; |
226 | 226 | ||
227 | read_lock(&sk->sk_callback_lock); | 227 | read_lock_bh(&sk->sk_callback_lock); |
228 | conn = sk->sk_user_data; | 228 | conn = sk->sk_user_data; |
229 | if (conn == NULL) { | 229 | if (conn == NULL) { |
230 | write_space = sk->sk_write_space; | 230 | write_space = sk->sk_write_space; |
@@ -244,7 +244,7 @@ void rds_tcp_write_space(struct sock *sk) | |||
244 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 244 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
245 | 245 | ||
246 | out: | 246 | out: |
247 | read_unlock(&sk->sk_callback_lock); | 247 | read_unlock_bh(&sk->sk_callback_lock); |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * write_space is only called when data leaves tcp's send queue if | 250 | * write_space is only called when data leaves tcp's send queue if |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 8e45e76a95f5..d952e7eac188 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -679,7 +679,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
679 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) | 679 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) |
680 | return -EINVAL; | 680 | return -EINVAL; |
681 | 681 | ||
682 | if (addr->srose_ndigis > ROSE_MAX_DIGIS) | 682 | if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) |
683 | return -EINVAL; | 683 | return -EINVAL; |
684 | 684 | ||
685 | if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { | 685 | if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { |
@@ -739,7 +739,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le | |||
739 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) | 739 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) |
740 | return -EINVAL; | 740 | return -EINVAL; |
741 | 741 | ||
742 | if (addr->srose_ndigis > ROSE_MAX_DIGIS) | 742 | if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) |
743 | return -EINVAL; | 743 | return -EINVAL; |
744 | 744 | ||
745 | /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ | 745 | /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 537a48732e9e..7ebf7439b478 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -350,22 +350,19 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
350 | { | 350 | { |
351 | unsigned char *b = skb_tail_pointer(skb); | 351 | unsigned char *b = skb_tail_pointer(skb); |
352 | struct tcf_police *police = a->priv; | 352 | struct tcf_police *police = a->priv; |
353 | struct tc_police opt; | 353 | struct tc_police opt = { |
354 | 354 | .index = police->tcf_index, | |
355 | opt.index = police->tcf_index; | 355 | .action = police->tcf_action, |
356 | opt.action = police->tcf_action; | 356 | .mtu = police->tcfp_mtu, |
357 | opt.mtu = police->tcfp_mtu; | 357 | .burst = police->tcfp_burst, |
358 | opt.burst = police->tcfp_burst; | 358 | .refcnt = police->tcf_refcnt - ref, |
359 | opt.refcnt = police->tcf_refcnt - ref; | 359 | .bindcnt = police->tcf_bindcnt - bind, |
360 | opt.bindcnt = police->tcf_bindcnt - bind; | 360 | }; |
361 | |||
361 | if (police->tcfp_R_tab) | 362 | if (police->tcfp_R_tab) |
362 | opt.rate = police->tcfp_R_tab->rate; | 363 | opt.rate = police->tcfp_R_tab->rate; |
363 | else | ||
364 | memset(&opt.rate, 0, sizeof(opt.rate)); | ||
365 | if (police->tcfp_P_tab) | 364 | if (police->tcfp_P_tab) |
366 | opt.peakrate = police->tcfp_P_tab->rate; | 365 | opt.peakrate = police->tcfp_P_tab->rate; |
367 | else | ||
368 | memset(&opt.peakrate, 0, sizeof(opt.peakrate)); | ||
369 | NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); | 366 | NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); |
370 | if (police->tcfp_result) | 367 | if (police->tcfp_result) |
371 | NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); | 368 | NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 340662789529..6318e1136b83 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -255,10 +255,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, | |||
255 | error = -EINVAL; | 255 | error = -EINVAL; |
256 | goto err_out; | 256 | goto err_out; |
257 | } | 257 | } |
258 | if (!list_empty(&flow->list)) { | ||
259 | error = -EEXIST; | ||
260 | goto err_out; | ||
261 | } | ||
262 | } else { | 258 | } else { |
263 | int i; | 259 | int i; |
264 | unsigned long cl; | 260 | unsigned long cl; |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index abd904be4287..47496098d35c 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -761,8 +761,8 @@ init_vf(struct hfsc_class *cl, unsigned int len) | |||
761 | if (f != cl->cl_f) { | 761 | if (f != cl->cl_f) { |
762 | cl->cl_f = f; | 762 | cl->cl_f = f; |
763 | cftree_update(cl); | 763 | cftree_update(cl); |
764 | update_cfmin(cl->cl_parent); | ||
765 | } | 764 | } |
765 | update_cfmin(cl->cl_parent); | ||
766 | } | 766 | } |
767 | } | 767 | } |
768 | 768 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index a646681f5acd..bcc4590ccaf2 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -92,7 +92,6 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, | |||
92 | SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__, | 92 | SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__, |
93 | packet, vtag); | 93 | packet, vtag); |
94 | 94 | ||
95 | sctp_packet_reset(packet); | ||
96 | packet->vtag = vtag; | 95 | packet->vtag = vtag; |
97 | 96 | ||
98 | if (ecn_capable && sctp_packet_empty(packet)) { | 97 | if (ecn_capable && sctp_packet_empty(packet)) { |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 24b2cd555637..d344dc481ccc 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1232,6 +1232,18 @@ out: | |||
1232 | return 0; | 1232 | return 0; |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static bool list_has_sctp_addr(const struct list_head *list, | ||
1236 | union sctp_addr *ipaddr) | ||
1237 | { | ||
1238 | struct sctp_transport *addr; | ||
1239 | |||
1240 | list_for_each_entry(addr, list, transports) { | ||
1241 | if (sctp_cmp_addr_exact(ipaddr, &addr->ipaddr)) | ||
1242 | return true; | ||
1243 | } | ||
1244 | |||
1245 | return false; | ||
1246 | } | ||
1235 | /* A restart is occurring, check to make sure no new addresses | 1247 | /* A restart is occurring, check to make sure no new addresses |
1236 | * are being added as we may be under a takeover attack. | 1248 | * are being added as we may be under a takeover attack. |
1237 | */ | 1249 | */ |
@@ -1240,10 +1252,10 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, | |||
1240 | struct sctp_chunk *init, | 1252 | struct sctp_chunk *init, |
1241 | sctp_cmd_seq_t *commands) | 1253 | sctp_cmd_seq_t *commands) |
1242 | { | 1254 | { |
1243 | struct sctp_transport *new_addr, *addr; | 1255 | struct sctp_transport *new_addr; |
1244 | int found; | 1256 | int ret = 1; |
1245 | 1257 | ||
1246 | /* Implementor's Guide - Sectin 5.2.2 | 1258 | /* Implementor's Guide - Section 5.2.2 |
1247 | * ... | 1259 | * ... |
1248 | * Before responding the endpoint MUST check to see if the | 1260 | * Before responding the endpoint MUST check to see if the |
1249 | * unexpected INIT adds new addresses to the association. If new | 1261 | * unexpected INIT adds new addresses to the association. If new |
@@ -1254,31 +1266,19 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, | |||
1254 | /* Search through all current addresses and make sure | 1266 | /* Search through all current addresses and make sure |
1255 | * we aren't adding any new ones. | 1267 | * we aren't adding any new ones. |
1256 | */ | 1268 | */ |
1257 | new_addr = NULL; | ||
1258 | found = 0; | ||
1259 | |||
1260 | list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, | 1269 | list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, |
1261 | transports) { | 1270 | transports) { |
1262 | found = 0; | 1271 | if (!list_has_sctp_addr(&asoc->peer.transport_addr_list, |
1263 | list_for_each_entry(addr, &asoc->peer.transport_addr_list, | 1272 | &new_addr->ipaddr)) { |
1264 | transports) { | 1273 | sctp_sf_send_restart_abort(&new_addr->ipaddr, init, |
1265 | if (sctp_cmp_addr_exact(&new_addr->ipaddr, | 1274 | commands); |
1266 | &addr->ipaddr)) { | 1275 | ret = 0; |
1267 | found = 1; | ||
1268 | break; | ||
1269 | } | ||
1270 | } | ||
1271 | if (!found) | ||
1272 | break; | 1276 | break; |
1273 | } | 1277 | } |
1274 | |||
1275 | /* If a new address was added, ABORT the sender. */ | ||
1276 | if (!found && new_addr) { | ||
1277 | sctp_sf_send_restart_abort(&new_addr->ipaddr, init, commands); | ||
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | /* Return success if all addresses were found. */ | 1280 | /* Return success if all addresses were found. */ |
1281 | return found; | 1281 | return ret; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /* Populate the verification/tie tags based on overlapping INIT | 1284 | /* Populate the verification/tie tags based on overlapping INIT |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 36cb66022a27..e9eaaf7d43c1 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -38,7 +38,7 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { | |||
38 | static LIST_HEAD(cred_unused); | 38 | static LIST_HEAD(cred_unused); |
39 | static unsigned long number_cred_unused; | 39 | static unsigned long number_cred_unused; |
40 | 40 | ||
41 | #define MAX_HASHTABLE_BITS (10) | 41 | #define MAX_HASHTABLE_BITS (14) |
42 | static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) | 42 | static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) |
43 | { | 43 | { |
44 | unsigned long num; | 44 | unsigned long num; |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index dcfc66bab2bb..12c485982814 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -745,17 +745,18 @@ gss_pipe_release(struct inode *inode) | |||
745 | struct rpc_inode *rpci = RPC_I(inode); | 745 | struct rpc_inode *rpci = RPC_I(inode); |
746 | struct gss_upcall_msg *gss_msg; | 746 | struct gss_upcall_msg *gss_msg; |
747 | 747 | ||
748 | restart: | ||
748 | spin_lock(&inode->i_lock); | 749 | spin_lock(&inode->i_lock); |
749 | while (!list_empty(&rpci->in_downcall)) { | 750 | list_for_each_entry(gss_msg, &rpci->in_downcall, list) { |
750 | 751 | ||
751 | gss_msg = list_entry(rpci->in_downcall.next, | 752 | if (!list_empty(&gss_msg->msg.list)) |
752 | struct gss_upcall_msg, list); | 753 | continue; |
753 | gss_msg->msg.errno = -EPIPE; | 754 | gss_msg->msg.errno = -EPIPE; |
754 | atomic_inc(&gss_msg->count); | 755 | atomic_inc(&gss_msg->count); |
755 | __gss_unhash_msg(gss_msg); | 756 | __gss_unhash_msg(gss_msg); |
756 | spin_unlock(&inode->i_lock); | 757 | spin_unlock(&inode->i_lock); |
757 | gss_release_msg(gss_msg); | 758 | gss_release_msg(gss_msg); |
758 | spin_lock(&inode->i_lock); | 759 | goto restart; |
759 | } | 760 | } |
760 | spin_unlock(&inode->i_lock); | 761 | spin_unlock(&inode->i_lock); |
761 | 762 | ||
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 032644610524..778e5dfc5144 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
@@ -237,6 +237,7 @@ get_key(const void *p, const void *end, | |||
237 | if (!supported_gss_krb5_enctype(alg)) { | 237 | if (!supported_gss_krb5_enctype(alg)) { |
238 | printk(KERN_WARNING "gss_kerberos_mech: unsupported " | 238 | printk(KERN_WARNING "gss_kerberos_mech: unsupported " |
239 | "encryption key algorithm %d\n", alg); | 239 | "encryption key algorithm %d\n", alg); |
240 | p = ERR_PTR(-EINVAL); | ||
240 | goto out_err; | 241 | goto out_err; |
241 | } | 242 | } |
242 | p = simple_get_netobj(p, end, &key); | 243 | p = simple_get_netobj(p, end, &key); |
@@ -282,15 +283,19 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) | |||
282 | ctx->enctype = ENCTYPE_DES_CBC_RAW; | 283 | ctx->enctype = ENCTYPE_DES_CBC_RAW; |
283 | 284 | ||
284 | ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); | 285 | ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); |
285 | if (ctx->gk5e == NULL) | 286 | if (ctx->gk5e == NULL) { |
287 | p = ERR_PTR(-EINVAL); | ||
286 | goto out_err; | 288 | goto out_err; |
289 | } | ||
287 | 290 | ||
288 | /* The downcall format was designed before we completely understood | 291 | /* The downcall format was designed before we completely understood |
289 | * the uses of the context fields; so it includes some stuff we | 292 | * the uses of the context fields; so it includes some stuff we |
290 | * just give some minimal sanity-checking, and some we ignore | 293 | * just give some minimal sanity-checking, and some we ignore |
291 | * completely (like the next twenty bytes): */ | 294 | * completely (like the next twenty bytes): */ |
292 | if (unlikely(p + 20 > end || p + 20 < p)) | 295 | if (unlikely(p + 20 > end || p + 20 < p)) { |
296 | p = ERR_PTR(-EFAULT); | ||
293 | goto out_err; | 297 | goto out_err; |
298 | } | ||
294 | p += 20; | 299 | p += 20; |
295 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); | 300 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); |
296 | if (IS_ERR(p)) | 301 | if (IS_ERR(p)) |
@@ -619,6 +624,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, | |||
619 | if (ctx->seq_send64 != ctx->seq_send) { | 624 | if (ctx->seq_send64 != ctx->seq_send) { |
620 | dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__, | 625 | dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__, |
621 | (long unsigned)ctx->seq_send64, ctx->seq_send); | 626 | (long unsigned)ctx->seq_send64, ctx->seq_send); |
627 | p = ERR_PTR(-EINVAL); | ||
622 | goto out_err; | 628 | goto out_err; |
623 | } | 629 | } |
624 | p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); | 630 | p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index dc3f1f5ed865..adade3d313f2 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c | |||
@@ -100,6 +100,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len, | |||
100 | if (version != 1) { | 100 | if (version != 1) { |
101 | dprintk("RPC: unknown spkm3 token format: " | 101 | dprintk("RPC: unknown spkm3 token format: " |
102 | "obsolete nfs-utils?\n"); | 102 | "obsolete nfs-utils?\n"); |
103 | p = ERR_PTR(-EINVAL); | ||
103 | goto out_err_free_ctx; | 104 | goto out_err_free_ctx; |
104 | } | 105 | } |
105 | 106 | ||
@@ -135,8 +136,10 @@ gss_import_sec_context_spkm3(const void *p, size_t len, | |||
135 | if (IS_ERR(p)) | 136 | if (IS_ERR(p)) |
136 | goto out_err_free_intg_alg; | 137 | goto out_err_free_intg_alg; |
137 | 138 | ||
138 | if (p != end) | 139 | if (p != end) { |
140 | p = ERR_PTR(-EFAULT); | ||
139 | goto out_err_free_intg_key; | 141 | goto out_err_free_intg_key; |
142 | } | ||
140 | 143 | ||
141 | ctx_id->internal_ctx_id = ctx; | 144 | ctx_id->internal_ctx_id = ctx; |
142 | 145 | ||
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 2388d83b68ff..fa5549079d79 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
226 | goto out_no_principal; | 226 | goto out_no_principal; |
227 | } | 227 | } |
228 | 228 | ||
229 | kref_init(&clnt->cl_kref); | 229 | atomic_set(&clnt->cl_count, 1); |
230 | 230 | ||
231 | err = rpc_setup_pipedir(clnt, program->pipe_dir_name); | 231 | err = rpc_setup_pipedir(clnt, program->pipe_dir_name); |
232 | if (err < 0) | 232 | if (err < 0) |
@@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
390 | if (new->cl_principal == NULL) | 390 | if (new->cl_principal == NULL) |
391 | goto out_no_principal; | 391 | goto out_no_principal; |
392 | } | 392 | } |
393 | kref_init(&new->cl_kref); | 393 | atomic_set(&new->cl_count, 1); |
394 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); | 394 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); |
395 | if (err != 0) | 395 | if (err != 0) |
396 | goto out_no_path; | 396 | goto out_no_path; |
397 | if (new->cl_auth) | 397 | if (new->cl_auth) |
398 | atomic_inc(&new->cl_auth->au_count); | 398 | atomic_inc(&new->cl_auth->au_count); |
399 | xprt_get(clnt->cl_xprt); | 399 | xprt_get(clnt->cl_xprt); |
400 | kref_get(&clnt->cl_kref); | 400 | atomic_inc(&clnt->cl_count); |
401 | rpc_register_client(new); | 401 | rpc_register_client(new); |
402 | rpciod_up(); | 402 | rpciod_up(); |
403 | return new; | 403 | return new; |
@@ -465,10 +465,8 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); | |||
465 | * Free an RPC client | 465 | * Free an RPC client |
466 | */ | 466 | */ |
467 | static void | 467 | static void |
468 | rpc_free_client(struct kref *kref) | 468 | rpc_free_client(struct rpc_clnt *clnt) |
469 | { | 469 | { |
470 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
471 | |||
472 | dprintk("RPC: destroying %s client for %s\n", | 470 | dprintk("RPC: destroying %s client for %s\n", |
473 | clnt->cl_protname, clnt->cl_server); | 471 | clnt->cl_protname, clnt->cl_server); |
474 | if (!IS_ERR(clnt->cl_path.dentry)) { | 472 | if (!IS_ERR(clnt->cl_path.dentry)) { |
@@ -495,12 +493,10 @@ out_free: | |||
495 | * Free an RPC client | 493 | * Free an RPC client |
496 | */ | 494 | */ |
497 | static void | 495 | static void |
498 | rpc_free_auth(struct kref *kref) | 496 | rpc_free_auth(struct rpc_clnt *clnt) |
499 | { | 497 | { |
500 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
501 | |||
502 | if (clnt->cl_auth == NULL) { | 498 | if (clnt->cl_auth == NULL) { |
503 | rpc_free_client(kref); | 499 | rpc_free_client(clnt); |
504 | return; | 500 | return; |
505 | } | 501 | } |
506 | 502 | ||
@@ -509,10 +505,11 @@ rpc_free_auth(struct kref *kref) | |||
509 | * release remaining GSS contexts. This mechanism ensures | 505 | * release remaining GSS contexts. This mechanism ensures |
510 | * that it can do so safely. | 506 | * that it can do so safely. |
511 | */ | 507 | */ |
512 | kref_init(kref); | 508 | atomic_inc(&clnt->cl_count); |
513 | rpcauth_release(clnt->cl_auth); | 509 | rpcauth_release(clnt->cl_auth); |
514 | clnt->cl_auth = NULL; | 510 | clnt->cl_auth = NULL; |
515 | kref_put(kref, rpc_free_client); | 511 | if (atomic_dec_and_test(&clnt->cl_count)) |
512 | rpc_free_client(clnt); | ||
516 | } | 513 | } |
517 | 514 | ||
518 | /* | 515 | /* |
@@ -525,7 +522,8 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
525 | 522 | ||
526 | if (list_empty(&clnt->cl_tasks)) | 523 | if (list_empty(&clnt->cl_tasks)) |
527 | wake_up(&destroy_wait); | 524 | wake_up(&destroy_wait); |
528 | kref_put(&clnt->cl_kref, rpc_free_auth); | 525 | if (atomic_dec_and_test(&clnt->cl_count)) |
526 | rpc_free_auth(clnt); | ||
529 | } | 527 | } |
530 | 528 | ||
531 | /** | 529 | /** |
@@ -588,7 +586,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) | |||
588 | if (clnt != NULL) { | 586 | if (clnt != NULL) { |
589 | rpc_task_release_client(task); | 587 | rpc_task_release_client(task); |
590 | task->tk_client = clnt; | 588 | task->tk_client = clnt; |
591 | kref_get(&clnt->cl_kref); | 589 | atomic_inc(&clnt->cl_count); |
592 | if (clnt->cl_softrtry) | 590 | if (clnt->cl_softrtry) |
593 | task->tk_flags |= RPC_TASK_SOFT; | 591 | task->tk_flags |= RPC_TASK_SOFT; |
594 | /* Add to the client's list of all tasks */ | 592 | /* Add to the client's list of all tasks */ |
@@ -931,7 +929,7 @@ call_reserveresult(struct rpc_task *task) | |||
931 | task->tk_status = 0; | 929 | task->tk_status = 0; |
932 | if (status >= 0) { | 930 | if (status >= 0) { |
933 | if (task->tk_rqstp) { | 931 | if (task->tk_rqstp) { |
934 | task->tk_action = call_allocate; | 932 | task->tk_action = call_refresh; |
935 | return; | 933 | return; |
936 | } | 934 | } |
937 | 935 | ||
@@ -966,13 +964,54 @@ call_reserveresult(struct rpc_task *task) | |||
966 | } | 964 | } |
967 | 965 | ||
968 | /* | 966 | /* |
969 | * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. | 967 | * 2. Bind and/or refresh the credentials |
968 | */ | ||
969 | static void | ||
970 | call_refresh(struct rpc_task *task) | ||
971 | { | ||
972 | dprint_status(task); | ||
973 | |||
974 | task->tk_action = call_refreshresult; | ||
975 | task->tk_status = 0; | ||
976 | task->tk_client->cl_stats->rpcauthrefresh++; | ||
977 | rpcauth_refreshcred(task); | ||
978 | } | ||
979 | |||
980 | /* | ||
981 | * 2a. Process the results of a credential refresh | ||
982 | */ | ||
983 | static void | ||
984 | call_refreshresult(struct rpc_task *task) | ||
985 | { | ||
986 | int status = task->tk_status; | ||
987 | |||
988 | dprint_status(task); | ||
989 | |||
990 | task->tk_status = 0; | ||
991 | task->tk_action = call_allocate; | ||
992 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
993 | return; | ||
994 | switch (status) { | ||
995 | case -EACCES: | ||
996 | rpc_exit(task, -EACCES); | ||
997 | return; | ||
998 | case -ENOMEM: | ||
999 | rpc_exit(task, -ENOMEM); | ||
1000 | return; | ||
1001 | case -ETIMEDOUT: | ||
1002 | rpc_delay(task, 3*HZ); | ||
1003 | } | ||
1004 | task->tk_action = call_refresh; | ||
1005 | } | ||
1006 | |||
1007 | /* | ||
1008 | * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc. | ||
970 | * (Note: buffer memory is freed in xprt_release). | 1009 | * (Note: buffer memory is freed in xprt_release). |
971 | */ | 1010 | */ |
972 | static void | 1011 | static void |
973 | call_allocate(struct rpc_task *task) | 1012 | call_allocate(struct rpc_task *task) |
974 | { | 1013 | { |
975 | unsigned int slack = task->tk_client->cl_auth->au_cslack; | 1014 | unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; |
976 | struct rpc_rqst *req = task->tk_rqstp; | 1015 | struct rpc_rqst *req = task->tk_rqstp; |
977 | struct rpc_xprt *xprt = task->tk_xprt; | 1016 | struct rpc_xprt *xprt = task->tk_xprt; |
978 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; | 1017 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
@@ -980,7 +1019,7 @@ call_allocate(struct rpc_task *task) | |||
980 | dprint_status(task); | 1019 | dprint_status(task); |
981 | 1020 | ||
982 | task->tk_status = 0; | 1021 | task->tk_status = 0; |
983 | task->tk_action = call_refresh; | 1022 | task->tk_action = call_bind; |
984 | 1023 | ||
985 | if (req->rq_buffer) | 1024 | if (req->rq_buffer) |
986 | return; | 1025 | return; |
@@ -1017,47 +1056,6 @@ call_allocate(struct rpc_task *task) | |||
1017 | rpc_exit(task, -ERESTARTSYS); | 1056 | rpc_exit(task, -ERESTARTSYS); |
1018 | } | 1057 | } |
1019 | 1058 | ||
1020 | /* | ||
1021 | * 2a. Bind and/or refresh the credentials | ||
1022 | */ | ||
1023 | static void | ||
1024 | call_refresh(struct rpc_task *task) | ||
1025 | { | ||
1026 | dprint_status(task); | ||
1027 | |||
1028 | task->tk_action = call_refreshresult; | ||
1029 | task->tk_status = 0; | ||
1030 | task->tk_client->cl_stats->rpcauthrefresh++; | ||
1031 | rpcauth_refreshcred(task); | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * 2b. Process the results of a credential refresh | ||
1036 | */ | ||
1037 | static void | ||
1038 | call_refreshresult(struct rpc_task *task) | ||
1039 | { | ||
1040 | int status = task->tk_status; | ||
1041 | |||
1042 | dprint_status(task); | ||
1043 | |||
1044 | task->tk_status = 0; | ||
1045 | task->tk_action = call_bind; | ||
1046 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
1047 | return; | ||
1048 | switch (status) { | ||
1049 | case -EACCES: | ||
1050 | rpc_exit(task, -EACCES); | ||
1051 | return; | ||
1052 | case -ENOMEM: | ||
1053 | rpc_exit(task, -ENOMEM); | ||
1054 | return; | ||
1055 | case -ETIMEDOUT: | ||
1056 | rpc_delay(task, 3*HZ); | ||
1057 | } | ||
1058 | task->tk_action = call_refresh; | ||
1059 | } | ||
1060 | |||
1061 | static inline int | 1059 | static inline int |
1062 | rpc_task_need_encode(struct rpc_task *task) | 1060 | rpc_task_need_encode(struct rpc_task *task) |
1063 | { | 1061 | { |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 95ccbcf45d3e..8c8eef2b8f26 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -48,7 +48,7 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, | |||
48 | return; | 48 | return; |
49 | do { | 49 | do { |
50 | msg = list_entry(head->next, struct rpc_pipe_msg, list); | 50 | msg = list_entry(head->next, struct rpc_pipe_msg, list); |
51 | list_del(&msg->list); | 51 | list_del_init(&msg->list); |
52 | msg->errno = err; | 52 | msg->errno = err; |
53 | destroy_msg(msg); | 53 | destroy_msg(msg); |
54 | } while (!list_empty(head)); | 54 | } while (!list_empty(head)); |
@@ -208,7 +208,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
208 | if (msg != NULL) { | 208 | if (msg != NULL) { |
209 | spin_lock(&inode->i_lock); | 209 | spin_lock(&inode->i_lock); |
210 | msg->errno = -EAGAIN; | 210 | msg->errno = -EAGAIN; |
211 | list_del(&msg->list); | 211 | list_del_init(&msg->list); |
212 | spin_unlock(&inode->i_lock); | 212 | spin_unlock(&inode->i_lock); |
213 | rpci->ops->destroy_msg(msg); | 213 | rpci->ops->destroy_msg(msg); |
214 | } | 214 | } |
@@ -268,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
268 | if (res < 0 || msg->len == msg->copied) { | 268 | if (res < 0 || msg->len == msg->copied) { |
269 | filp->private_data = NULL; | 269 | filp->private_data = NULL; |
270 | spin_lock(&inode->i_lock); | 270 | spin_lock(&inode->i_lock); |
271 | list_del(&msg->list); | 271 | list_del_init(&msg->list); |
272 | spin_unlock(&inode->i_lock); | 272 | spin_unlock(&inode->i_lock); |
273 | rpci->ops->destroy_msg(msg); | 273 | rpci->ops->destroy_msg(msg); |
274 | } | 274 | } |
@@ -371,21 +371,23 @@ rpc_show_info(struct seq_file *m, void *v) | |||
371 | static int | 371 | static int |
372 | rpc_info_open(struct inode *inode, struct file *file) | 372 | rpc_info_open(struct inode *inode, struct file *file) |
373 | { | 373 | { |
374 | struct rpc_clnt *clnt; | 374 | struct rpc_clnt *clnt = NULL; |
375 | int ret = single_open(file, rpc_show_info, NULL); | 375 | int ret = single_open(file, rpc_show_info, NULL); |
376 | 376 | ||
377 | if (!ret) { | 377 | if (!ret) { |
378 | struct seq_file *m = file->private_data; | 378 | struct seq_file *m = file->private_data; |
379 | mutex_lock(&inode->i_mutex); | 379 | |
380 | clnt = RPC_I(inode)->private; | 380 | spin_lock(&file->f_path.dentry->d_lock); |
381 | if (clnt) { | 381 | if (!d_unhashed(file->f_path.dentry)) |
382 | kref_get(&clnt->cl_kref); | 382 | clnt = RPC_I(inode)->private; |
383 | if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { | ||
384 | spin_unlock(&file->f_path.dentry->d_lock); | ||
383 | m->private = clnt; | 385 | m->private = clnt; |
384 | } else { | 386 | } else { |
387 | spin_unlock(&file->f_path.dentry->d_lock); | ||
385 | single_release(inode, file); | 388 | single_release(inode, file); |
386 | ret = -EINVAL; | 389 | ret = -EINVAL; |
387 | } | 390 | } |
388 | mutex_unlock(&inode->i_mutex); | ||
389 | } | 391 | } |
390 | return ret; | 392 | return ret; |
391 | } | 393 | } |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index b6309db56226..fe9306bf10cc 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -800,7 +800,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
800 | u32 _xid; | 800 | u32 _xid; |
801 | __be32 *xp; | 801 | __be32 *xp; |
802 | 802 | ||
803 | read_lock(&sk->sk_callback_lock); | 803 | read_lock_bh(&sk->sk_callback_lock); |
804 | dprintk("RPC: xs_udp_data_ready...\n"); | 804 | dprintk("RPC: xs_udp_data_ready...\n"); |
805 | if (!(xprt = xprt_from_sock(sk))) | 805 | if (!(xprt = xprt_from_sock(sk))) |
806 | goto out; | 806 | goto out; |
@@ -852,7 +852,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
852 | dropit: | 852 | dropit: |
853 | skb_free_datagram(sk, skb); | 853 | skb_free_datagram(sk, skb); |
854 | out: | 854 | out: |
855 | read_unlock(&sk->sk_callback_lock); | 855 | read_unlock_bh(&sk->sk_callback_lock); |
856 | } | 856 | } |
857 | 857 | ||
858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) | 858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) |
@@ -1229,7 +1229,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1229 | 1229 | ||
1230 | dprintk("RPC: xs_tcp_data_ready...\n"); | 1230 | dprintk("RPC: xs_tcp_data_ready...\n"); |
1231 | 1231 | ||
1232 | read_lock(&sk->sk_callback_lock); | 1232 | read_lock_bh(&sk->sk_callback_lock); |
1233 | if (!(xprt = xprt_from_sock(sk))) | 1233 | if (!(xprt = xprt_from_sock(sk))) |
1234 | goto out; | 1234 | goto out; |
1235 | if (xprt->shutdown) | 1235 | if (xprt->shutdown) |
@@ -1248,7 +1248,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); | 1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); |
1249 | } while (read > 0); | 1249 | } while (read > 0); |
1250 | out: | 1250 | out: |
1251 | read_unlock(&sk->sk_callback_lock); | 1251 | read_unlock_bh(&sk->sk_callback_lock); |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | /* | 1254 | /* |
@@ -1301,7 +1301,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1301 | { | 1301 | { |
1302 | struct rpc_xprt *xprt; | 1302 | struct rpc_xprt *xprt; |
1303 | 1303 | ||
1304 | read_lock(&sk->sk_callback_lock); | 1304 | read_lock_bh(&sk->sk_callback_lock); |
1305 | if (!(xprt = xprt_from_sock(sk))) | 1305 | if (!(xprt = xprt_from_sock(sk))) |
1306 | goto out; | 1306 | goto out; |
1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); | 1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); |
@@ -1313,7 +1313,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1313 | 1313 | ||
1314 | switch (sk->sk_state) { | 1314 | switch (sk->sk_state) { |
1315 | case TCP_ESTABLISHED: | 1315 | case TCP_ESTABLISHED: |
1316 | spin_lock_bh(&xprt->transport_lock); | 1316 | spin_lock(&xprt->transport_lock); |
1317 | if (!xprt_test_and_set_connected(xprt)) { | 1317 | if (!xprt_test_and_set_connected(xprt)) { |
1318 | struct sock_xprt *transport = container_of(xprt, | 1318 | struct sock_xprt *transport = container_of(xprt, |
1319 | struct sock_xprt, xprt); | 1319 | struct sock_xprt, xprt); |
@@ -1327,7 +1327,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1327 | 1327 | ||
1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1329 | } | 1329 | } |
1330 | spin_unlock_bh(&xprt->transport_lock); | 1330 | spin_unlock(&xprt->transport_lock); |
1331 | break; | 1331 | break; |
1332 | case TCP_FIN_WAIT1: | 1332 | case TCP_FIN_WAIT1: |
1333 | /* The client initiated a shutdown of the socket */ | 1333 | /* The client initiated a shutdown of the socket */ |
@@ -1365,7 +1365,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1365 | xs_sock_mark_closed(xprt); | 1365 | xs_sock_mark_closed(xprt); |
1366 | } | 1366 | } |
1367 | out: | 1367 | out: |
1368 | read_unlock(&sk->sk_callback_lock); | 1368 | read_unlock_bh(&sk->sk_callback_lock); |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | /** | 1371 | /** |
@@ -1376,7 +1376,7 @@ static void xs_error_report(struct sock *sk) | |||
1376 | { | 1376 | { |
1377 | struct rpc_xprt *xprt; | 1377 | struct rpc_xprt *xprt; |
1378 | 1378 | ||
1379 | read_lock(&sk->sk_callback_lock); | 1379 | read_lock_bh(&sk->sk_callback_lock); |
1380 | if (!(xprt = xprt_from_sock(sk))) | 1380 | if (!(xprt = xprt_from_sock(sk))) |
1381 | goto out; | 1381 | goto out; |
1382 | dprintk("RPC: %s client %p...\n" | 1382 | dprintk("RPC: %s client %p...\n" |
@@ -1384,7 +1384,7 @@ static void xs_error_report(struct sock *sk) | |||
1384 | __func__, xprt, sk->sk_err); | 1384 | __func__, xprt, sk->sk_err); |
1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1386 | out: | 1386 | out: |
1387 | read_unlock(&sk->sk_callback_lock); | 1387 | read_unlock_bh(&sk->sk_callback_lock); |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | static void xs_write_space(struct sock *sk) | 1390 | static void xs_write_space(struct sock *sk) |
@@ -1416,13 +1416,13 @@ static void xs_write_space(struct sock *sk) | |||
1416 | */ | 1416 | */ |
1417 | static void xs_udp_write_space(struct sock *sk) | 1417 | static void xs_udp_write_space(struct sock *sk) |
1418 | { | 1418 | { |
1419 | read_lock(&sk->sk_callback_lock); | 1419 | read_lock_bh(&sk->sk_callback_lock); |
1420 | 1420 | ||
1421 | /* from net/core/sock.c:sock_def_write_space */ | 1421 | /* from net/core/sock.c:sock_def_write_space */ |
1422 | if (sock_writeable(sk)) | 1422 | if (sock_writeable(sk)) |
1423 | xs_write_space(sk); | 1423 | xs_write_space(sk); |
1424 | 1424 | ||
1425 | read_unlock(&sk->sk_callback_lock); | 1425 | read_unlock_bh(&sk->sk_callback_lock); |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | /** | 1428 | /** |
@@ -1437,13 +1437,13 @@ static void xs_udp_write_space(struct sock *sk) | |||
1437 | */ | 1437 | */ |
1438 | static void xs_tcp_write_space(struct sock *sk) | 1438 | static void xs_tcp_write_space(struct sock *sk) |
1439 | { | 1439 | { |
1440 | read_lock(&sk->sk_callback_lock); | 1440 | read_lock_bh(&sk->sk_callback_lock); |
1441 | 1441 | ||
1442 | /* from net/core/stream.c:sk_stream_write_space */ | 1442 | /* from net/core/stream.c:sk_stream_write_space */ |
1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
1444 | xs_write_space(sk); | 1444 | xs_write_space(sk); |
1445 | 1445 | ||
1446 | read_unlock(&sk->sk_callback_lock); | 1446 | read_unlock_bh(&sk->sk_callback_lock); |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) | 1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4414a18c63b4..0b39b2451ea5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -692,6 +692,7 @@ static int unix_autobind(struct socket *sock) | |||
692 | static u32 ordernum = 1; | 692 | static u32 ordernum = 1; |
693 | struct unix_address *addr; | 693 | struct unix_address *addr; |
694 | int err; | 694 | int err; |
695 | unsigned int retries = 0; | ||
695 | 696 | ||
696 | mutex_lock(&u->readlock); | 697 | mutex_lock(&u->readlock); |
697 | 698 | ||
@@ -717,9 +718,17 @@ retry: | |||
717 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, | 718 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, |
718 | addr->hash)) { | 719 | addr->hash)) { |
719 | spin_unlock(&unix_table_lock); | 720 | spin_unlock(&unix_table_lock); |
720 | /* Sanity yield. It is unusual case, but yet... */ | 721 | /* |
721 | if (!(ordernum&0xFF)) | 722 | * __unix_find_socket_byname() may take long time if many names |
722 | yield(); | 723 | * are already in use. |
724 | */ | ||
725 | cond_resched(); | ||
726 | /* Give up if all names seems to be in use. */ | ||
727 | if (retries++ == 0xFFFFF) { | ||
728 | err = -ENOSPC; | ||
729 | kfree(addr); | ||
730 | goto out; | ||
731 | } | ||
723 | goto retry; | 732 | goto retry; |
724 | } | 733 | } |
725 | addr->hash ^= sk->sk_type; | 734 | addr->hash ^= sk->sk_type; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 541e2fff5e9c..d6d046b9f6f2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -475,12 +475,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
475 | mutex_lock(&cfg80211_mutex); | 475 | mutex_lock(&cfg80211_mutex); |
476 | 476 | ||
477 | res = device_add(&rdev->wiphy.dev); | 477 | res = device_add(&rdev->wiphy.dev); |
478 | if (res) | 478 | if (res) { |
479 | goto out_unlock; | 479 | mutex_unlock(&cfg80211_mutex); |
480 | 480 | return res; | |
481 | res = rfkill_register(rdev->rfkill); | 481 | } |
482 | if (res) | ||
483 | goto out_rm_dev; | ||
484 | 482 | ||
485 | /* set up regulatory info */ | 483 | /* set up regulatory info */ |
486 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | 484 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); |
@@ -509,13 +507,18 @@ int wiphy_register(struct wiphy *wiphy) | |||
509 | cfg80211_debugfs_rdev_add(rdev); | 507 | cfg80211_debugfs_rdev_add(rdev); |
510 | mutex_unlock(&cfg80211_mutex); | 508 | mutex_unlock(&cfg80211_mutex); |
511 | 509 | ||
510 | /* | ||
511 | * due to a locking dependency this has to be outside of the | ||
512 | * cfg80211_mutex lock | ||
513 | */ | ||
514 | res = rfkill_register(rdev->rfkill); | ||
515 | if (res) | ||
516 | goto out_rm_dev; | ||
517 | |||
512 | return 0; | 518 | return 0; |
513 | 519 | ||
514 | out_rm_dev: | 520 | out_rm_dev: |
515 | device_del(&rdev->wiphy.dev); | 521 | device_del(&rdev->wiphy.dev); |
516 | |||
517 | out_unlock: | ||
518 | mutex_unlock(&cfg80211_mutex); | ||
519 | return res; | 522 | return res; |
520 | } | 523 | } |
521 | EXPORT_SYMBOL(wiphy_register); | 524 | EXPORT_SYMBOL(wiphy_register); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index bb5e0a5ecfa1..7e5c3a45f811 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1420,6 +1420,9 @@ int cfg80211_wext_giwessid(struct net_device *dev, | |||
1420 | { | 1420 | { |
1421 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1421 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1422 | 1422 | ||
1423 | data->flags = 0; | ||
1424 | data->length = 0; | ||
1425 | |||
1423 | switch (wdev->iftype) { | 1426 | switch (wdev->iftype) { |
1424 | case NL80211_IFTYPE_ADHOC: | 1427 | case NL80211_IFTYPE_ADHOC: |
1425 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); | 1428 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); |
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 0ef17bc42bac..8f5116f5af19 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c | |||
@@ -782,6 +782,22 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
782 | } | 782 | } |
783 | } | 783 | } |
784 | 784 | ||
785 | if (IW_IS_GET(cmd) && !(descr->flags & IW_DESCR_FLAG_NOMAX)) { | ||
786 | /* | ||
787 | * If this is a GET, but not NOMAX, it means that the extra | ||
788 | * data is not bounded by userspace, but by max_tokens. Thus | ||
789 | * set the length to max_tokens. This matches the extra data | ||
790 | * allocation. | ||
791 | * The driver should fill it with the number of tokens it | ||
792 | * provided, and it may check iwp->length rather than having | ||
793 | * knowledge of max_tokens. If the driver doesn't change the | ||
794 | * iwp->length, this ioctl just copies back max_token tokens | ||
795 | * filled with zeroes. Hopefully the driver isn't claiming | ||
796 | * them to be valid data. | ||
797 | */ | ||
798 | iwp->length = descr->max_tokens; | ||
799 | } | ||
800 | |||
785 | err = handler(dev, info, (union iwreq_data *) iwp, extra); | 801 | err = handler(dev, info, (union iwreq_data *) iwp, extra); |
786 | 802 | ||
787 | iwp->length += essid_compat; | 803 | iwp->length += essid_compat; |
diff --git a/net/wireless/wext-priv.c b/net/wireless/wext-priv.c index 3feb28e41c53..674d426a9d24 100644 --- a/net/wireless/wext-priv.c +++ b/net/wireless/wext-priv.c | |||
@@ -152,7 +152,7 @@ static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
152 | } else if (!iwp->pointer) | 152 | } else if (!iwp->pointer) |
153 | return -EFAULT; | 153 | return -EFAULT; |
154 | 154 | ||
155 | extra = kmalloc(extra_size, GFP_KERNEL); | 155 | extra = kzalloc(extra_size, GFP_KERNEL); |
156 | if (!extra) | 156 | if (!extra) |
157 | return -ENOMEM; | 157 | return -ENOMEM; |
158 | 158 | ||
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index a3cca0a94346..64f2ae1fdc15 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
@@ -101,7 +101,7 @@ resume: | |||
101 | err = -EHOSTUNREACH; | 101 | err = -EHOSTUNREACH; |
102 | goto error_nolock; | 102 | goto error_nolock; |
103 | } | 103 | } |
104 | skb_dst_set_noref(skb, dst); | 104 | skb_dst_set(skb, dst_clone(dst)); |
105 | x = dst->xfrm; | 105 | x = dst->xfrm; |
106 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); | 106 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); |
107 | 107 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2b3ed7ad4933..cbab6e1a8c9c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1175,9 +1175,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl, | |||
1175 | tmpl->mode == XFRM_MODE_BEET) { | 1175 | tmpl->mode == XFRM_MODE_BEET) { |
1176 | remote = &tmpl->id.daddr; | 1176 | remote = &tmpl->id.daddr; |
1177 | local = &tmpl->saddr; | 1177 | local = &tmpl->saddr; |
1178 | family = tmpl->encap_family; | 1178 | if (xfrm_addr_any(local, tmpl->encap_family)) { |
1179 | if (xfrm_addr_any(local, family)) { | 1179 | error = xfrm_get_saddr(net, &tmp, remote, tmpl->encap_family); |
1180 | error = xfrm_get_saddr(net, &tmp, remote, family); | ||
1181 | if (error) | 1180 | if (error) |
1182 | goto fail; | 1181 | goto fail; |
1183 | local = &tmp; | 1182 | local = &tmp; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5208b12fbfb4..eb96ce52f178 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -656,15 +656,23 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) | |||
656 | EXPORT_SYMBOL(xfrm_sad_getinfo); | 656 | EXPORT_SYMBOL(xfrm_sad_getinfo); |
657 | 657 | ||
658 | static int | 658 | static int |
659 | xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 659 | xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl, |
660 | struct xfrm_tmpl *tmpl, | 660 | struct xfrm_tmpl *tmpl, |
661 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 661 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
662 | unsigned short family) | 662 | unsigned short family) |
663 | { | 663 | { |
664 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); | 664 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); |
665 | if (!afinfo) | 665 | if (!afinfo) |
666 | return -1; | 666 | return -1; |
667 | afinfo->init_tempsel(x, fl, tmpl, daddr, saddr); | 667 | afinfo->init_tempsel(&x->sel, fl); |
668 | |||
669 | if (family != tmpl->encap_family) { | ||
670 | xfrm_state_put_afinfo(afinfo); | ||
671 | afinfo = xfrm_state_get_afinfo(tmpl->encap_family); | ||
672 | if (!afinfo) | ||
673 | return -1; | ||
674 | } | ||
675 | afinfo->init_temprop(x, tmpl, daddr, saddr); | ||
668 | xfrm_state_put_afinfo(afinfo); | 676 | xfrm_state_put_afinfo(afinfo); |
669 | return 0; | 677 | return 0; |
670 | } | 678 | } |
@@ -790,37 +798,38 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
790 | int error = 0; | 798 | int error = 0; |
791 | struct xfrm_state *best = NULL; | 799 | struct xfrm_state *best = NULL; |
792 | u32 mark = pol->mark.v & pol->mark.m; | 800 | u32 mark = pol->mark.v & pol->mark.m; |
801 | unsigned short encap_family = tmpl->encap_family; | ||
793 | 802 | ||
794 | to_put = NULL; | 803 | to_put = NULL; |
795 | 804 | ||
796 | spin_lock_bh(&xfrm_state_lock); | 805 | spin_lock_bh(&xfrm_state_lock); |
797 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family); | 806 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); |
798 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { | 807 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
799 | if (x->props.family == family && | 808 | if (x->props.family == encap_family && |
800 | x->props.reqid == tmpl->reqid && | 809 | x->props.reqid == tmpl->reqid && |
801 | (mark & x->mark.m) == x->mark.v && | 810 | (mark & x->mark.m) == x->mark.v && |
802 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 811 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
803 | xfrm_state_addr_check(x, daddr, saddr, family) && | 812 | xfrm_state_addr_check(x, daddr, saddr, encap_family) && |
804 | tmpl->mode == x->props.mode && | 813 | tmpl->mode == x->props.mode && |
805 | tmpl->id.proto == x->id.proto && | 814 | tmpl->id.proto == x->id.proto && |
806 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) | 815 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) |
807 | xfrm_state_look_at(pol, x, fl, family, daddr, saddr, | 816 | xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, |
808 | &best, &acquire_in_progress, &error); | 817 | &best, &acquire_in_progress, &error); |
809 | } | 818 | } |
810 | if (best) | 819 | if (best) |
811 | goto found; | 820 | goto found; |
812 | 821 | ||
813 | h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family); | 822 | h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family); |
814 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { | 823 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { |
815 | if (x->props.family == family && | 824 | if (x->props.family == encap_family && |
816 | x->props.reqid == tmpl->reqid && | 825 | x->props.reqid == tmpl->reqid && |
817 | (mark & x->mark.m) == x->mark.v && | 826 | (mark & x->mark.m) == x->mark.v && |
818 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 827 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
819 | xfrm_state_addr_check(x, daddr, saddr, family) && | 828 | xfrm_state_addr_check(x, daddr, saddr, encap_family) && |
820 | tmpl->mode == x->props.mode && | 829 | tmpl->mode == x->props.mode && |
821 | tmpl->id.proto == x->id.proto && | 830 | tmpl->id.proto == x->id.proto && |
822 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) | 831 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) |
823 | xfrm_state_look_at(pol, x, fl, family, daddr, saddr, | 832 | xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, |
824 | &best, &acquire_in_progress, &error); | 833 | &best, &acquire_in_progress, &error); |
825 | } | 834 | } |
826 | 835 | ||
@@ -829,7 +838,7 @@ found: | |||
829 | if (!x && !error && !acquire_in_progress) { | 838 | if (!x && !error && !acquire_in_progress) { |
830 | if (tmpl->id.spi && | 839 | if (tmpl->id.spi && |
831 | (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, | 840 | (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, |
832 | tmpl->id.proto, family)) != NULL) { | 841 | tmpl->id.proto, encap_family)) != NULL) { |
833 | to_put = x0; | 842 | to_put = x0; |
834 | error = -EEXIST; | 843 | error = -EEXIST; |
835 | goto out; | 844 | goto out; |
@@ -839,9 +848,9 @@ found: | |||
839 | error = -ENOMEM; | 848 | error = -ENOMEM; |
840 | goto out; | 849 | goto out; |
841 | } | 850 | } |
842 | /* Initialize temporary selector matching only | 851 | /* Initialize temporary state matching only |
843 | * to current session. */ | 852 | * to current session. */ |
844 | xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family); | 853 | xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family); |
845 | memcpy(&x->mark, &pol->mark, sizeof(x->mark)); | 854 | memcpy(&x->mark, &pol->mark, sizeof(x->mark)); |
846 | 855 | ||
847 | error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); | 856 | error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); |
@@ -856,10 +865,10 @@ found: | |||
856 | x->km.state = XFRM_STATE_ACQ; | 865 | x->km.state = XFRM_STATE_ACQ; |
857 | list_add(&x->km.all, &net->xfrm.state_all); | 866 | list_add(&x->km.all, &net->xfrm.state_all); |
858 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); | 867 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); |
859 | h = xfrm_src_hash(net, daddr, saddr, family); | 868 | h = xfrm_src_hash(net, daddr, saddr, encap_family); |
860 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); | 869 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); |
861 | if (x->id.spi) { | 870 | if (x->id.spi) { |
862 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family); | 871 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family); |
863 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); | 872 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); |
864 | } | 873 | } |
865 | x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; | 874 | x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14ed4b1f27c..8bae6b22c846 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1801,7 +1801,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); | 1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); |
1802 | struct xfrm_usersa_info *p = &ue->state; | 1802 | struct xfrm_usersa_info *p = &ue->state; |
1803 | struct xfrm_mark m; | 1803 | struct xfrm_mark m; |
1804 | u32 mark = xfrm_mark_get(attrs, &m);; | 1804 | u32 mark = xfrm_mark_get(attrs, &m); |
1805 | 1805 | ||
1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); | 1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); |
1807 | 1807 | ||