diff options
Diffstat (limited to 'net')
46 files changed, 395 insertions, 231 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 5bf5f227dbe..8af95b2dddd 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -582,11 +582,9 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt) | |||
| 582 | 582 | ||
| 583 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | 583 | memset(&fid->qid, 0, sizeof(struct p9_qid)); |
| 584 | fid->mode = -1; | 584 | fid->mode = -1; |
| 585 | fid->rdir_fpos = 0; | ||
| 586 | fid->uid = current_fsuid(); | 585 | fid->uid = current_fsuid(); |
| 587 | fid->clnt = clnt; | 586 | fid->clnt = clnt; |
| 588 | fid->aux = NULL; | 587 | fid->rdir = NULL; |
| 589 | |||
| 590 | spin_lock_irqsave(&clnt->lock, flags); | 588 | spin_lock_irqsave(&clnt->lock, flags); |
| 591 | list_add(&fid->flist, &clnt->fidlist); | 589 | list_add(&fid->flist, &clnt->fidlist); |
| 592 | spin_unlock_irqrestore(&clnt->lock, flags); | 590 | spin_unlock_irqrestore(&clnt->lock, flags); |
| @@ -609,6 +607,7 @@ static void p9_fid_destroy(struct p9_fid *fid) | |||
| 609 | spin_lock_irqsave(&clnt->lock, flags); | 607 | spin_lock_irqsave(&clnt->lock, flags); |
| 610 | list_del(&fid->flist); | 608 | list_del(&fid->flist); |
| 611 | spin_unlock_irqrestore(&clnt->lock, flags); | 609 | spin_unlock_irqrestore(&clnt->lock, flags); |
| 610 | kfree(fid->rdir); | ||
| 612 | kfree(fid); | 611 | kfree(fid); |
| 613 | } | 612 | } |
| 614 | 613 | ||
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index b2e07f0dd29..ea1e3daabef 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | #include <net/9p/transport.h> | 43 | #include <net/9p/transport.h> |
| 44 | #include <linux/scatterlist.h> | 44 | #include <linux/scatterlist.h> |
| 45 | #include <linux/virtio.h> | 45 | #include <linux/virtio.h> |
| 46 | #include <linux/virtio_ids.h> | ||
| 47 | #include <linux/virtio_9p.h> | 46 | #include <linux/virtio_9p.h> |
| 48 | 47 | ||
| 49 | #define VIRTQUEUE_NUM 128 | 48 | #define VIRTQUEUE_NUM 128 |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 7f939ce2980..2bc6f6a8de6 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
| @@ -92,6 +92,8 @@ static void add_conn(struct work_struct *work) | |||
| 92 | 92 | ||
| 93 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); | 93 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); |
| 94 | 94 | ||
| 95 | dev_set_drvdata(&conn->dev, conn); | ||
| 96 | |||
| 95 | if (device_add(&conn->dev) < 0) { | 97 | if (device_add(&conn->dev) < 0) { |
| 96 | BT_ERR("Failed to register connection device"); | 98 | BT_ERR("Failed to register connection device"); |
| 97 | return; | 99 | return; |
| @@ -144,8 +146,6 @@ void hci_conn_init_sysfs(struct hci_conn *conn) | |||
| 144 | conn->dev.class = bt_class; | 146 | conn->dev.class = bt_class; |
| 145 | conn->dev.parent = &hdev->dev; | 147 | conn->dev.parent = &hdev->dev; |
| 146 | 148 | ||
| 147 | dev_set_drvdata(&conn->dev, conn); | ||
| 148 | |||
| 149 | device_initialize(&conn->dev); | 149 | device_initialize(&conn->dev); |
| 150 | 150 | ||
| 151 | INIT_WORK(&conn->work_add, add_conn); | 151 | INIT_WORK(&conn->work_add, add_conn); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 555d9da1869..77e9fb130ad 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -555,12 +555,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
| 555 | 555 | ||
| 556 | conn->feat_mask = 0; | 556 | conn->feat_mask = 0; |
| 557 | 557 | ||
| 558 | setup_timer(&conn->info_timer, l2cap_info_timeout, | ||
| 559 | (unsigned long) conn); | ||
| 560 | |||
| 561 | spin_lock_init(&conn->lock); | 558 | spin_lock_init(&conn->lock); |
| 562 | rwlock_init(&conn->chan_list.lock); | 559 | rwlock_init(&conn->chan_list.lock); |
| 563 | 560 | ||
| 561 | setup_timer(&conn->info_timer, l2cap_info_timeout, | ||
| 562 | (unsigned long) conn); | ||
| 563 | |||
| 564 | conn->disc_reason = 0x13; | 564 | conn->disc_reason = 0x13; |
| 565 | 565 | ||
| 566 | return conn; | 566 | return conn; |
| @@ -783,6 +783,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
| 783 | /* Default config options */ | 783 | /* Default config options */ |
| 784 | pi->conf_len = 0; | 784 | pi->conf_len = 0; |
| 785 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 785 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
| 786 | skb_queue_head_init(TX_QUEUE(sk)); | ||
| 787 | skb_queue_head_init(SREJ_QUEUE(sk)); | ||
| 788 | INIT_LIST_HEAD(SREJ_LIST(sk)); | ||
| 786 | } | 789 | } |
| 787 | 790 | ||
| 788 | static struct proto l2cap_proto = { | 791 | static struct proto l2cap_proto = { |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b1b3b0fbf41..4a9f5273265 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -377,12 +377,16 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 377 | struct net_bridge_port *p; | 377 | struct net_bridge_port *p; |
| 378 | int err = 0; | 378 | int err = 0; |
| 379 | 379 | ||
| 380 | if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) | 380 | /* Don't allow bridging non-ethernet like devices */ |
| 381 | if ((dev->flags & IFF_LOOPBACK) || | ||
| 382 | dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN) | ||
| 381 | return -EINVAL; | 383 | return -EINVAL; |
| 382 | 384 | ||
| 385 | /* No bridging of bridges */ | ||
| 383 | if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) | 386 | if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) |
| 384 | return -ELOOP; | 387 | return -ELOOP; |
| 385 | 388 | ||
| 389 | /* Device is already being bridged */ | ||
| 386 | if (dev->br_port != NULL) | 390 | if (dev->br_port != NULL) |
| 387 | return -EBUSY; | 391 | return -EBUSY; |
| 388 | 392 | ||
diff --git a/net/can/bcm.c b/net/can/bcm.c index 597da4f8f88..e8d58f33fe0 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
| @@ -132,23 +132,27 @@ static inline struct bcm_sock *bcm_sk(const struct sock *sk) | |||
| 132 | /* | 132 | /* |
| 133 | * procfs functions | 133 | * procfs functions |
| 134 | */ | 134 | */ |
| 135 | static char *bcm_proc_getifname(int ifindex) | 135 | static char *bcm_proc_getifname(char *result, int ifindex) |
| 136 | { | 136 | { |
| 137 | struct net_device *dev; | 137 | struct net_device *dev; |
| 138 | 138 | ||
| 139 | if (!ifindex) | 139 | if (!ifindex) |
| 140 | return "any"; | 140 | return "any"; |
| 141 | 141 | ||
| 142 | /* no usage counting */ | 142 | read_lock(&dev_base_lock); |
| 143 | dev = __dev_get_by_index(&init_net, ifindex); | 143 | dev = __dev_get_by_index(&init_net, ifindex); |
| 144 | if (dev) | 144 | if (dev) |
| 145 | return dev->name; | 145 | strcpy(result, dev->name); |
| 146 | else | ||
| 147 | strcpy(result, "???"); | ||
| 148 | read_unlock(&dev_base_lock); | ||
| 146 | 149 | ||
| 147 | return "???"; | 150 | return result; |
| 148 | } | 151 | } |
| 149 | 152 | ||
| 150 | static int bcm_proc_show(struct seq_file *m, void *v) | 153 | static int bcm_proc_show(struct seq_file *m, void *v) |
| 151 | { | 154 | { |
| 155 | char ifname[IFNAMSIZ]; | ||
| 152 | struct sock *sk = (struct sock *)m->private; | 156 | struct sock *sk = (struct sock *)m->private; |
| 153 | struct bcm_sock *bo = bcm_sk(sk); | 157 | struct bcm_sock *bo = bcm_sk(sk); |
| 154 | struct bcm_op *op; | 158 | struct bcm_op *op; |
| @@ -157,7 +161,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) | |||
| 157 | seq_printf(m, " / sk %p", sk); | 161 | seq_printf(m, " / sk %p", sk); |
| 158 | seq_printf(m, " / bo %p", bo); | 162 | seq_printf(m, " / bo %p", bo); |
| 159 | seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs); | 163 | seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs); |
| 160 | seq_printf(m, " / bound %s", bcm_proc_getifname(bo->ifindex)); | 164 | seq_printf(m, " / bound %s", bcm_proc_getifname(ifname, bo->ifindex)); |
| 161 | seq_printf(m, " <<<\n"); | 165 | seq_printf(m, " <<<\n"); |
| 162 | 166 | ||
| 163 | list_for_each_entry(op, &bo->rx_ops, list) { | 167 | list_for_each_entry(op, &bo->rx_ops, list) { |
| @@ -169,7 +173,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) | |||
| 169 | continue; | 173 | continue; |
| 170 | 174 | ||
| 171 | seq_printf(m, "rx_op: %03X %-5s ", | 175 | seq_printf(m, "rx_op: %03X %-5s ", |
| 172 | op->can_id, bcm_proc_getifname(op->ifindex)); | 176 | op->can_id, bcm_proc_getifname(ifname, op->ifindex)); |
| 173 | seq_printf(m, "[%d]%c ", op->nframes, | 177 | seq_printf(m, "[%d]%c ", op->nframes, |
| 174 | (op->flags & RX_CHECK_DLC)?'d':' '); | 178 | (op->flags & RX_CHECK_DLC)?'d':' '); |
| 175 | if (op->kt_ival1.tv64) | 179 | if (op->kt_ival1.tv64) |
| @@ -194,7 +198,8 @@ static int bcm_proc_show(struct seq_file *m, void *v) | |||
| 194 | list_for_each_entry(op, &bo->tx_ops, list) { | 198 | list_for_each_entry(op, &bo->tx_ops, list) { |
| 195 | 199 | ||
| 196 | seq_printf(m, "tx_op: %03X %s [%d] ", | 200 | seq_printf(m, "tx_op: %03X %s [%d] ", |
| 197 | op->can_id, bcm_proc_getifname(op->ifindex), | 201 | op->can_id, |
| 202 | bcm_proc_getifname(ifname, op->ifindex), | ||
| 198 | op->nframes); | 203 | op->nframes); |
| 199 | 204 | ||
| 200 | if (op->kt_ival1.tv64) | 205 | if (op->kt_ival1.tv64) |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 1c6cf3a1a4f..4ade3011bb3 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
| @@ -224,6 +224,15 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) | |||
| 224 | consume_skb(skb); | 224 | consume_skb(skb); |
| 225 | sk_mem_reclaim_partial(sk); | 225 | sk_mem_reclaim_partial(sk); |
| 226 | } | 226 | } |
| 227 | EXPORT_SYMBOL(skb_free_datagram); | ||
| 228 | |||
| 229 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) | ||
| 230 | { | ||
| 231 | lock_sock(sk); | ||
| 232 | skb_free_datagram(sk, skb); | ||
| 233 | release_sock(sk); | ||
| 234 | } | ||
| 235 | EXPORT_SYMBOL(skb_free_datagram_locked); | ||
| 227 | 236 | ||
| 228 | /** | 237 | /** |
| 229 | * skb_kill_datagram - Free a datagram skbuff forcibly | 238 | * skb_kill_datagram - Free a datagram skbuff forcibly |
| @@ -752,5 +761,4 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, | |||
| 752 | EXPORT_SYMBOL(datagram_poll); | 761 | EXPORT_SYMBOL(datagram_poll); |
| 753 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); | 762 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); |
| 754 | EXPORT_SYMBOL(skb_copy_datagram_iovec); | 763 | EXPORT_SYMBOL(skb_copy_datagram_iovec); |
| 755 | EXPORT_SYMBOL(skb_free_datagram); | ||
| 756 | EXPORT_SYMBOL(skb_recv_datagram); | 764 | EXPORT_SYMBOL(skb_recv_datagram); |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 86acdba0a97..6eb8d47cbf3 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -335,6 +335,7 @@ struct pktgen_dev { | |||
| 335 | __u32 cur_src_mac_offset; | 335 | __u32 cur_src_mac_offset; |
| 336 | __be32 cur_saddr; | 336 | __be32 cur_saddr; |
| 337 | __be32 cur_daddr; | 337 | __be32 cur_daddr; |
| 338 | __u16 ip_id; | ||
| 338 | __u16 cur_udp_dst; | 339 | __u16 cur_udp_dst; |
| 339 | __u16 cur_udp_src; | 340 | __u16 cur_udp_src; |
| 340 | __u16 cur_queue_map; | 341 | __u16 cur_queue_map; |
| @@ -2630,6 +2631,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
| 2630 | iph->protocol = IPPROTO_UDP; /* UDP */ | 2631 | iph->protocol = IPPROTO_UDP; /* UDP */ |
| 2631 | iph->saddr = pkt_dev->cur_saddr; | 2632 | iph->saddr = pkt_dev->cur_saddr; |
| 2632 | iph->daddr = pkt_dev->cur_daddr; | 2633 | iph->daddr = pkt_dev->cur_daddr; |
| 2634 | iph->id = htons(pkt_dev->ip_id); | ||
| 2635 | pkt_dev->ip_id++; | ||
| 2633 | iph->frag_off = 0; | 2636 | iph->frag_off = 0; |
| 2634 | iplen = 20 + 8 + datalen; | 2637 | iplen = 20 + 8 + datalen; |
| 2635 | iph->tot_len = htons(iplen); | 2638 | iph->tot_len = htons(iplen); |
| @@ -2641,24 +2644,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
| 2641 | skb->dev = odev; | 2644 | skb->dev = odev; |
| 2642 | skb->pkt_type = PACKET_HOST; | 2645 | skb->pkt_type = PACKET_HOST; |
| 2643 | 2646 | ||
| 2644 | if (pkt_dev->nfrags <= 0) | 2647 | if (pkt_dev->nfrags <= 0) { |
| 2645 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); | 2648 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); |
| 2646 | else { | 2649 | memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr)); |
| 2650 | } else { | ||
| 2647 | int frags = pkt_dev->nfrags; | 2651 | int frags = pkt_dev->nfrags; |
| 2648 | int i; | 2652 | int i, len; |
| 2649 | 2653 | ||
| 2650 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); | 2654 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); |
| 2651 | 2655 | ||
| 2652 | if (frags > MAX_SKB_FRAGS) | 2656 | if (frags > MAX_SKB_FRAGS) |
| 2653 | frags = MAX_SKB_FRAGS; | 2657 | frags = MAX_SKB_FRAGS; |
| 2654 | if (datalen > frags * PAGE_SIZE) { | 2658 | if (datalen > frags * PAGE_SIZE) { |
| 2655 | skb_put(skb, datalen - frags * PAGE_SIZE); | 2659 | len = datalen - frags * PAGE_SIZE; |
| 2660 | memset(skb_put(skb, len), 0, len); | ||
| 2656 | datalen = frags * PAGE_SIZE; | 2661 | datalen = frags * PAGE_SIZE; |
| 2657 | } | 2662 | } |
| 2658 | 2663 | ||
| 2659 | i = 0; | 2664 | i = 0; |
| 2660 | while (datalen > 0) { | 2665 | while (datalen > 0) { |
| 2661 | struct page *page = alloc_pages(GFP_KERNEL, 0); | 2666 | struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); |
| 2662 | skb_shinfo(skb)->frags[i].page = page; | 2667 | skb_shinfo(skb)->frags[i].page = page; |
| 2663 | skb_shinfo(skb)->frags[i].page_offset = 0; | 2668 | skb_shinfo(skb)->frags[i].page_offset = 0; |
| 2664 | skb_shinfo(skb)->frags[i].size = | 2669 | skb_shinfo(skb)->frags[i].size = |
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 26b0ab1e9f5..2036568beea 100644 --- a/net/decnet/sysctl_net_decnet.c +++ b/net/decnet/sysctl_net_decnet.c | |||
| @@ -263,11 +263,10 @@ static int dn_def_dev_strategy(ctl_table *table, | |||
| 263 | return -ENODEV; | 263 | return -ENODEV; |
| 264 | 264 | ||
| 265 | rv = -ENODEV; | 265 | rv = -ENODEV; |
| 266 | if (dev->dn_ptr != NULL) { | 266 | if (dev->dn_ptr != NULL) |
| 267 | rv = dn_dev_set_default(dev, 1); | 267 | rv = dn_dev_set_default(dev, 1); |
| 268 | if (rv) | 268 | if (rv) |
| 269 | dev_put(dev); | 269 | dev_put(dev); |
| 270 | } | ||
| 271 | } | 270 | } |
| 272 | 271 | ||
| 273 | return rv; | 272 | return rv; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index e2f95059256..aa00398be80 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -229,14 +229,17 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, | |||
| 229 | */ | 229 | */ |
| 230 | 230 | ||
| 231 | int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | 231 | int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, |
| 232 | struct net_device *dev, __be32 *spec_dst, u32 *itag) | 232 | struct net_device *dev, __be32 *spec_dst, |
| 233 | u32 *itag, u32 mark) | ||
| 233 | { | 234 | { |
| 234 | struct in_device *in_dev; | 235 | struct in_device *in_dev; |
| 235 | struct flowi fl = { .nl_u = { .ip4_u = | 236 | struct flowi fl = { .nl_u = { .ip4_u = |
| 236 | { .daddr = src, | 237 | { .daddr = src, |
| 237 | .saddr = dst, | 238 | .saddr = dst, |
| 238 | .tos = tos } }, | 239 | .tos = tos } }, |
| 240 | .mark = mark, | ||
| 239 | .iif = oif }; | 241 | .iif = oif }; |
| 242 | |||
| 240 | struct fib_result res; | 243 | struct fib_result res; |
| 241 | int no_addr, rpf; | 244 | int no_addr, rpf; |
| 242 | int ret; | 245 | int ret; |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 4351ca2cf0b..537731b3bcb 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
| @@ -446,6 +446,28 @@ extern int sysctl_tcp_synack_retries; | |||
| 446 | 446 | ||
| 447 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); | 447 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); |
| 448 | 448 | ||
| 449 | /* Decide when to expire the request and when to resend SYN-ACK */ | ||
| 450 | static inline void syn_ack_recalc(struct request_sock *req, const int thresh, | ||
| 451 | const int max_retries, | ||
| 452 | const u8 rskq_defer_accept, | ||
| 453 | int *expire, int *resend) | ||
| 454 | { | ||
| 455 | if (!rskq_defer_accept) { | ||
| 456 | *expire = req->retrans >= thresh; | ||
| 457 | *resend = 1; | ||
| 458 | return; | ||
| 459 | } | ||
| 460 | *expire = req->retrans >= thresh && | ||
| 461 | (!inet_rsk(req)->acked || req->retrans >= max_retries); | ||
| 462 | /* | ||
| 463 | * Do not resend while waiting for data after ACK, | ||
| 464 | * start to resend on end of deferring period to give | ||
| 465 | * last chance for data or ACK to create established socket. | ||
| 466 | */ | ||
| 467 | *resend = !inet_rsk(req)->acked || | ||
| 468 | req->retrans >= rskq_defer_accept - 1; | ||
| 469 | } | ||
| 470 | |||
| 449 | void inet_csk_reqsk_queue_prune(struct sock *parent, | 471 | void inet_csk_reqsk_queue_prune(struct sock *parent, |
| 450 | const unsigned long interval, | 472 | const unsigned long interval, |
| 451 | const unsigned long timeout, | 473 | const unsigned long timeout, |
| @@ -501,9 +523,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
| 501 | reqp=&lopt->syn_table[i]; | 523 | reqp=&lopt->syn_table[i]; |
| 502 | while ((req = *reqp) != NULL) { | 524 | while ((req = *reqp) != NULL) { |
| 503 | if (time_after_eq(now, req->expires)) { | 525 | if (time_after_eq(now, req->expires)) { |
| 504 | if ((req->retrans < thresh || | 526 | int expire = 0, resend = 0; |
| 505 | (inet_rsk(req)->acked && req->retrans < max_retries)) | 527 | |
| 506 | && !req->rsk_ops->rtx_syn_ack(parent, req)) { | 528 | syn_ack_recalc(req, thresh, max_retries, |
| 529 | queue->rskq_defer_accept, | ||
| 530 | &expire, &resend); | ||
| 531 | if (!expire && | ||
| 532 | (!resend || | ||
| 533 | !req->rsk_ops->rtx_syn_ack(parent, req) || | ||
| 534 | inet_rsk(req)->acked)) { | ||
| 507 | unsigned long timeo; | 535 | unsigned long timeo; |
| 508 | 536 | ||
| 509 | if (req->retrans++ == 0) | 537 | if (req->retrans++ == 0) |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 41ada9904d3..14333385262 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -1464,7 +1464,7 @@ static void ipgre_tap_setup(struct net_device *dev) | |||
| 1464 | 1464 | ||
| 1465 | ether_setup(dev); | 1465 | ether_setup(dev); |
| 1466 | 1466 | ||
| 1467 | dev->netdev_ops = &ipgre_netdev_ops; | 1467 | dev->netdev_ops = &ipgre_tap_netdev_ops; |
| 1468 | dev->destructor = free_netdev; | 1468 | dev->destructor = free_netdev; |
| 1469 | 1469 | ||
| 1470 | dev->iflink = 0; | 1470 | dev->iflink = 0; |
| @@ -1525,25 +1525,29 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], | |||
| 1525 | if (t->dev != dev) | 1525 | if (t->dev != dev) |
| 1526 | return -EEXIST; | 1526 | return -EEXIST; |
| 1527 | } else { | 1527 | } else { |
| 1528 | unsigned nflags = 0; | ||
| 1529 | |||
| 1530 | t = nt; | 1528 | t = nt; |
| 1531 | 1529 | ||
| 1532 | if (ipv4_is_multicast(p.iph.daddr)) | 1530 | if (dev->type != ARPHRD_ETHER) { |
| 1533 | nflags = IFF_BROADCAST; | 1531 | unsigned nflags = 0; |
| 1534 | else if (p.iph.daddr) | ||
| 1535 | nflags = IFF_POINTOPOINT; | ||
| 1536 | 1532 | ||
| 1537 | if ((dev->flags ^ nflags) & | 1533 | if (ipv4_is_multicast(p.iph.daddr)) |
| 1538 | (IFF_POINTOPOINT | IFF_BROADCAST)) | 1534 | nflags = IFF_BROADCAST; |
| 1539 | return -EINVAL; | 1535 | else if (p.iph.daddr) |
| 1536 | nflags = IFF_POINTOPOINT; | ||
| 1537 | |||
| 1538 | if ((dev->flags ^ nflags) & | ||
| 1539 | (IFF_POINTOPOINT | IFF_BROADCAST)) | ||
| 1540 | return -EINVAL; | ||
| 1541 | } | ||
| 1540 | 1542 | ||
| 1541 | ipgre_tunnel_unlink(ign, t); | 1543 | ipgre_tunnel_unlink(ign, t); |
| 1542 | t->parms.iph.saddr = p.iph.saddr; | 1544 | t->parms.iph.saddr = p.iph.saddr; |
| 1543 | t->parms.iph.daddr = p.iph.daddr; | 1545 | t->parms.iph.daddr = p.iph.daddr; |
| 1544 | t->parms.i_key = p.i_key; | 1546 | t->parms.i_key = p.i_key; |
| 1545 | memcpy(dev->dev_addr, &p.iph.saddr, 4); | 1547 | if (dev->type != ARPHRD_ETHER) { |
| 1546 | memcpy(dev->broadcast, &p.iph.daddr, 4); | 1548 | memcpy(dev->dev_addr, &p.iph.saddr, 4); |
| 1549 | memcpy(dev->broadcast, &p.iph.daddr, 4); | ||
| 1550 | } | ||
| 1547 | ipgre_tunnel_link(ign, t); | 1551 | ipgre_tunnel_link(ign, t); |
| 1548 | netdev_state_change(dev); | 1552 | netdev_state_change(dev); |
| 1549 | } | 1553 | } |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 0c0b6e363a2..e982b5c1ee1 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -634,17 +634,16 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
| 634 | break; | 634 | break; |
| 635 | } | 635 | } |
| 636 | dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr); | 636 | dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr); |
| 637 | if (dev) { | 637 | if (dev) |
| 638 | mreq.imr_ifindex = dev->ifindex; | 638 | mreq.imr_ifindex = dev->ifindex; |
| 639 | dev_put(dev); | ||
| 640 | } | ||
| 641 | } else | 639 | } else |
| 642 | dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex); | 640 | dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex); |
| 643 | 641 | ||
| 644 | 642 | ||
| 645 | err = -EADDRNOTAVAIL; | 643 | err = -EADDRNOTAVAIL; |
| 646 | if (!dev) | 644 | if (!dev) |
| 647 | break; | 645 | break; |
| 646 | dev_put(dev); | ||
| 648 | 647 | ||
| 649 | err = -EINVAL; | 648 | err = -EINVAL; |
| 650 | if (sk->sk_bound_dev_if && | 649 | if (sk->sk_bound_dev_if && |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 08ccd344de7..ae40ed1ba56 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
| @@ -438,25 +438,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 438 | goto tx_error; | 438 | goto tx_error; |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | if (tiph->frag_off) | 441 | df |= old_iph->frag_off & htons(IP_DF); |
| 442 | |||
| 443 | if (df) { | ||
| 442 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 444 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); |
| 443 | else | ||
| 444 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | ||
| 445 | 445 | ||
| 446 | if (mtu < 68) { | 446 | if (mtu < 68) { |
| 447 | stats->collisions++; | 447 | stats->collisions++; |
| 448 | ip_rt_put(rt); | 448 | ip_rt_put(rt); |
| 449 | goto tx_error; | 449 | goto tx_error; |
| 450 | } | 450 | } |
| 451 | if (skb_dst(skb)) | ||
| 452 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
| 453 | 451 | ||
| 454 | df |= (old_iph->frag_off&htons(IP_DF)); | 452 | if (skb_dst(skb)) |
| 453 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
| 455 | 454 | ||
| 456 | if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { | 455 | if ((old_iph->frag_off & htons(IP_DF)) && |
| 457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); | 456 | mtu < ntohs(old_iph->tot_len)) { |
| 458 | ip_rt_put(rt); | 457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
| 459 | goto tx_error; | 458 | htonl(mtu)); |
| 459 | ip_rt_put(rt); | ||
| 460 | goto tx_error; | ||
| 461 | } | ||
| 460 | } | 462 | } |
| 461 | 463 | ||
| 462 | if (tunnel->err_count > 0) { | 464 | if (tunnel->err_count > 0) { |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 68afc6ecd34..fe1a64479dd 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
| @@ -750,6 +750,8 @@ static int __init nf_nat_init(void) | |||
| 750 | BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); | 750 | BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); |
| 751 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, | 751 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, |
| 752 | nfnetlink_parse_nat_setup); | 752 | nfnetlink_parse_nat_setup); |
| 753 | BUG_ON(nf_ct_nat_offset != NULL); | ||
| 754 | rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset); | ||
| 753 | return 0; | 755 | return 0; |
| 754 | 756 | ||
| 755 | cleanup_extend: | 757 | cleanup_extend: |
| @@ -764,6 +766,7 @@ static void __exit nf_nat_cleanup(void) | |||
| 764 | nf_ct_extend_unregister(&nat_extend); | 766 | nf_ct_extend_unregister(&nat_extend); |
| 765 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); | 767 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); |
| 766 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL); | 768 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL); |
| 769 | rcu_assign_pointer(nf_ct_nat_offset, NULL); | ||
| 767 | synchronize_net(); | 770 | synchronize_net(); |
| 768 | } | 771 | } |
| 769 | 772 | ||
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 09172a65d9b..f9520fa3aba 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
| @@ -73,6 +73,28 @@ adjust_tcp_sequence(u32 seq, | |||
| 73 | DUMP_OFFSET(this_way); | 73 | DUMP_OFFSET(this_way); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | /* Get the offset value, for conntrack */ | ||
| 77 | s16 nf_nat_get_offset(const struct nf_conn *ct, | ||
| 78 | enum ip_conntrack_dir dir, | ||
| 79 | u32 seq) | ||
| 80 | { | ||
| 81 | struct nf_conn_nat *nat = nfct_nat(ct); | ||
| 82 | struct nf_nat_seq *this_way; | ||
| 83 | s16 offset; | ||
| 84 | |||
| 85 | if (!nat) | ||
| 86 | return 0; | ||
| 87 | |||
| 88 | this_way = &nat->seq[dir]; | ||
| 89 | spin_lock_bh(&nf_nat_seqofs_lock); | ||
| 90 | offset = after(seq, this_way->correction_pos) | ||
| 91 | ? this_way->offset_after : this_way->offset_before; | ||
| 92 | spin_unlock_bh(&nf_nat_seqofs_lock); | ||
| 93 | |||
| 94 | return offset; | ||
| 95 | } | ||
| 96 | EXPORT_SYMBOL_GPL(nf_nat_get_offset); | ||
| 97 | |||
| 76 | /* Frobs data inside this packet, which is linear. */ | 98 | /* Frobs data inside this packet, which is linear. */ |
| 77 | static void mangle_contents(struct sk_buff *skb, | 99 | static void mangle_contents(struct sk_buff *skb, |
| 78 | unsigned int dataoff, | 100 | unsigned int dataoff, |
| @@ -189,11 +211,6 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
| 189 | adjust_tcp_sequence(ntohl(tcph->seq), | 211 | adjust_tcp_sequence(ntohl(tcph->seq), |
| 190 | (int)rep_len - (int)match_len, | 212 | (int)rep_len - (int)match_len, |
| 191 | ct, ctinfo); | 213 | ct, ctinfo); |
| 192 | /* Tell TCP window tracking about seq change */ | ||
| 193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), | ||
| 194 | ct, CTINFO2DIR(ctinfo), | ||
| 195 | (int)rep_len - (int)match_len); | ||
| 196 | |||
| 197 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); | 214 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); |
| 198 | } | 215 | } |
| 199 | return 1; | 216 | return 1; |
| @@ -415,12 +432,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, | |||
| 415 | tcph->seq = newseq; | 432 | tcph->seq = newseq; |
| 416 | tcph->ack_seq = newack; | 433 | tcph->ack_seq = newack; |
| 417 | 434 | ||
| 418 | if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) | 435 | return nf_nat_sack_adjust(skb, tcph, ct, ctinfo); |
| 419 | return 0; | ||
| 420 | |||
| 421 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff); | ||
| 422 | |||
| 423 | return 1; | ||
| 424 | } | 436 | } |
| 425 | 437 | ||
| 426 | /* Setup NAT on this expected conntrack so it follows master. */ | 438 | /* Setup NAT on this expected conntrack so it follows master. */ |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 757c9171e7c..ab996f9c0fe 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -352,13 +352,24 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
| 352 | skb->ip_summed = CHECKSUM_NONE; | 352 | skb->ip_summed = CHECKSUM_NONE; |
| 353 | 353 | ||
| 354 | skb->transport_header = skb->network_header; | 354 | skb->transport_header = skb->network_header; |
| 355 | err = memcpy_fromiovecend((void *)iph, from, 0, length); | 355 | err = -EFAULT; |
| 356 | if (err) | 356 | if (memcpy_fromiovecend((void *)iph, from, 0, length)) |
| 357 | goto error_fault; | 357 | goto error_free; |
| 358 | 358 | ||
| 359 | /* We don't modify invalid header */ | ||
| 360 | iphlen = iph->ihl * 4; | 359 | iphlen = iph->ihl * 4; |
| 361 | if (iphlen >= sizeof(*iph) && iphlen <= length) { | 360 | |
| 361 | /* | ||
| 362 | * We don't want to modify the ip header, but we do need to | ||
| 363 | * be sure that it won't cause problems later along the network | ||
| 364 | * stack. Specifically we want to make sure that iph->ihl is a | ||
| 365 | * sane value. If ihl points beyond the length of the buffer passed | ||
| 366 | * in, reject the frame as invalid | ||
| 367 | */ | ||
| 368 | err = -EINVAL; | ||
| 369 | if (iphlen > length) | ||
| 370 | goto error_free; | ||
| 371 | |||
| 372 | if (iphlen >= sizeof(*iph)) { | ||
| 362 | if (!iph->saddr) | 373 | if (!iph->saddr) |
| 363 | iph->saddr = rt->rt_src; | 374 | iph->saddr = rt->rt_src; |
| 364 | iph->check = 0; | 375 | iph->check = 0; |
| @@ -381,8 +392,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
| 381 | out: | 392 | out: |
| 382 | return 0; | 393 | return 0; |
| 383 | 394 | ||
| 384 | error_fault: | 395 | error_free: |
| 385 | err = -EFAULT; | ||
| 386 | kfree_skb(skb); | 396 | kfree_skb(skb); |
| 387 | error: | 397 | error: |
| 388 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); | 398 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index bb419925202..5b1050a5d87 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1854,7 +1854,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1854 | goto e_inval; | 1854 | goto e_inval; |
| 1855 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); | 1855 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); |
| 1856 | } else if (fib_validate_source(saddr, 0, tos, 0, | 1856 | } else if (fib_validate_source(saddr, 0, tos, 0, |
| 1857 | dev, &spec_dst, &itag) < 0) | 1857 | dev, &spec_dst, &itag, 0) < 0) |
| 1858 | goto e_inval; | 1858 | goto e_inval; |
| 1859 | 1859 | ||
| 1860 | rth = dst_alloc(&ipv4_dst_ops); | 1860 | rth = dst_alloc(&ipv4_dst_ops); |
| @@ -1967,7 +1967,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
| 1967 | 1967 | ||
| 1968 | 1968 | ||
| 1969 | err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), | 1969 | err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), |
| 1970 | in_dev->dev, &spec_dst, &itag); | 1970 | in_dev->dev, &spec_dst, &itag, skb->mark); |
| 1971 | if (err < 0) { | 1971 | if (err < 0) { |
| 1972 | ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, | 1972 | ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, |
| 1973 | saddr); | 1973 | saddr); |
| @@ -2141,7 +2141,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2141 | int result; | 2141 | int result; |
| 2142 | result = fib_validate_source(saddr, daddr, tos, | 2142 | result = fib_validate_source(saddr, daddr, tos, |
| 2143 | net->loopback_dev->ifindex, | 2143 | net->loopback_dev->ifindex, |
| 2144 | dev, &spec_dst, &itag); | 2144 | dev, &spec_dst, &itag, skb->mark); |
| 2145 | if (result < 0) | 2145 | if (result < 0) |
| 2146 | goto martian_source; | 2146 | goto martian_source; |
| 2147 | if (result) | 2147 | if (result) |
| @@ -2170,7 +2170,7 @@ brd_input: | |||
| 2170 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); | 2170 | spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); |
| 2171 | else { | 2171 | else { |
| 2172 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, | 2172 | err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, |
| 2173 | &itag); | 2173 | &itag, skb->mark); |
| 2174 | if (err < 0) | 2174 | if (err < 0) |
| 2175 | goto martian_source; | 2175 | goto martian_source; |
| 2176 | if (err) | 2176 | if (err) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 64d0af67582..98440ad8255 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk) | |||
| 326 | 326 | ||
| 327 | EXPORT_SYMBOL(tcp_enter_memory_pressure); | 327 | EXPORT_SYMBOL(tcp_enter_memory_pressure); |
| 328 | 328 | ||
| 329 | /* Convert seconds to retransmits based on initial and max timeout */ | ||
| 330 | static u8 secs_to_retrans(int seconds, int timeout, int rto_max) | ||
| 331 | { | ||
| 332 | u8 res = 0; | ||
| 333 | |||
| 334 | if (seconds > 0) { | ||
| 335 | int period = timeout; | ||
| 336 | |||
| 337 | res = 1; | ||
| 338 | while (seconds > period && res < 255) { | ||
| 339 | res++; | ||
| 340 | timeout <<= 1; | ||
| 341 | if (timeout > rto_max) | ||
| 342 | timeout = rto_max; | ||
| 343 | period += timeout; | ||
| 344 | } | ||
| 345 | } | ||
| 346 | return res; | ||
| 347 | } | ||
| 348 | |||
| 349 | /* Convert retransmits to seconds based on initial and max timeout */ | ||
| 350 | static int retrans_to_secs(u8 retrans, int timeout, int rto_max) | ||
| 351 | { | ||
| 352 | int period = 0; | ||
| 353 | |||
| 354 | if (retrans > 0) { | ||
| 355 | period = timeout; | ||
| 356 | while (--retrans) { | ||
| 357 | timeout <<= 1; | ||
| 358 | if (timeout > rto_max) | ||
| 359 | timeout = rto_max; | ||
| 360 | period += timeout; | ||
| 361 | } | ||
| 362 | } | ||
| 363 | return period; | ||
| 364 | } | ||
| 365 | |||
| 329 | /* | 366 | /* |
| 330 | * Wait for a TCP event. | 367 | * Wait for a TCP event. |
| 331 | * | 368 | * |
| @@ -1405,7 +1442,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1405 | goto found_ok_skb; | 1442 | goto found_ok_skb; |
| 1406 | if (tcp_hdr(skb)->fin) | 1443 | if (tcp_hdr(skb)->fin) |
| 1407 | goto found_fin_ok; | 1444 | goto found_fin_ok; |
| 1408 | WARN_ON(!(flags & MSG_PEEK)); | 1445 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " |
| 1446 | "copied %X seq %X\n", *seq, | ||
| 1447 | TCP_SKB_CB(skb)->seq); | ||
| 1409 | } | 1448 | } |
| 1410 | 1449 | ||
| 1411 | /* Well, if we have backlog, try to process it now yet. */ | 1450 | /* Well, if we have backlog, try to process it now yet. */ |
| @@ -2163,16 +2202,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2163 | break; | 2202 | break; |
| 2164 | 2203 | ||
| 2165 | case TCP_DEFER_ACCEPT: | 2204 | case TCP_DEFER_ACCEPT: |
| 2166 | icsk->icsk_accept_queue.rskq_defer_accept = 0; | 2205 | /* Translate value in seconds to number of retransmits */ |
| 2167 | if (val > 0) { | 2206 | icsk->icsk_accept_queue.rskq_defer_accept = |
| 2168 | /* Translate value in seconds to number of | 2207 | secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, |
| 2169 | * retransmits */ | 2208 | TCP_RTO_MAX / HZ); |
| 2170 | while (icsk->icsk_accept_queue.rskq_defer_accept < 32 && | ||
| 2171 | val > ((TCP_TIMEOUT_INIT / HZ) << | ||
| 2172 | icsk->icsk_accept_queue.rskq_defer_accept)) | ||
| 2173 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
| 2174 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
| 2175 | } | ||
| 2176 | break; | 2209 | break; |
| 2177 | 2210 | ||
| 2178 | case TCP_WINDOW_CLAMP: | 2211 | case TCP_WINDOW_CLAMP: |
| @@ -2353,8 +2386,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
| 2353 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; | 2386 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; |
| 2354 | break; | 2387 | break; |
| 2355 | case TCP_DEFER_ACCEPT: | 2388 | case TCP_DEFER_ACCEPT: |
| 2356 | val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : | 2389 | val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, |
| 2357 | ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); | 2390 | TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); |
| 2358 | break; | 2391 | break; |
| 2359 | case TCP_WINDOW_CLAMP: | 2392 | case TCP_WINDOW_CLAMP: |
| 2360 | val = tp->window_clamp; | 2393 | val = tp->window_clamp; |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 624c3c9b3c2..4c03598ed92 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -641,8 +641,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
| 641 | if (!(flg & TCP_FLAG_ACK)) | 641 | if (!(flg & TCP_FLAG_ACK)) |
| 642 | return NULL; | 642 | return NULL; |
| 643 | 643 | ||
| 644 | /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ | 644 | /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */ |
| 645 | if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && | 645 | if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && |
| 646 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { | 646 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { |
| 647 | inet_rsk(req)->acked = 1; | 647 | inet_rsk(req)->acked = 1; |
| 648 | return NULL; | 648 | return NULL; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 6ec6a8a4a22..0fa9f70e4b1 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -841,6 +841,42 @@ out: | |||
| 841 | return ret; | 841 | return ret; |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | |||
| 845 | /** | ||
| 846 | * first_packet_length - return length of first packet in receive queue | ||
| 847 | * @sk: socket | ||
| 848 | * | ||
| 849 | * Drops all bad checksum frames, until a valid one is found. | ||
| 850 | * Returns the length of found skb, or 0 if none is found. | ||
| 851 | */ | ||
| 852 | static unsigned int first_packet_length(struct sock *sk) | ||
| 853 | { | ||
| 854 | struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue; | ||
| 855 | struct sk_buff *skb; | ||
| 856 | unsigned int res; | ||
| 857 | |||
| 858 | __skb_queue_head_init(&list_kill); | ||
| 859 | |||
| 860 | spin_lock_bh(&rcvq->lock); | ||
| 861 | while ((skb = skb_peek(rcvq)) != NULL && | ||
| 862 | udp_lib_checksum_complete(skb)) { | ||
| 863 | UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, | ||
| 864 | IS_UDPLITE(sk)); | ||
| 865 | __skb_unlink(skb, rcvq); | ||
| 866 | __skb_queue_tail(&list_kill, skb); | ||
| 867 | } | ||
| 868 | res = skb ? skb->len : 0; | ||
| 869 | spin_unlock_bh(&rcvq->lock); | ||
| 870 | |||
| 871 | if (!skb_queue_empty(&list_kill)) { | ||
| 872 | lock_sock(sk); | ||
| 873 | __skb_queue_purge(&list_kill); | ||
| 874 | sk_mem_reclaim_partial(sk); | ||
| 875 | release_sock(sk); | ||
| 876 | } | ||
| 877 | return res; | ||
| 878 | } | ||
| 879 | |||
| 844 | /* | 880 | /* |
| 845 | * IOCTL requests applicable to the UDP protocol | 881 | * IOCTL requests applicable to the UDP protocol |
| 846 | */ | 882 | */ |
| @@ -857,21 +893,16 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 857 | 893 | ||
| 858 | case SIOCINQ: | 894 | case SIOCINQ: |
| 859 | { | 895 | { |
| 860 | struct sk_buff *skb; | 896 | unsigned int amount = first_packet_length(sk); |
| 861 | unsigned long amount; | ||
| 862 | 897 | ||
| 863 | amount = 0; | 898 | if (amount) |
| 864 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
| 865 | skb = skb_peek(&sk->sk_receive_queue); | ||
| 866 | if (skb != NULL) { | ||
| 867 | /* | 899 | /* |
| 868 | * We will only return the amount | 900 | * We will only return the amount |
| 869 | * of this packet since that is all | 901 | * of this packet since that is all |
| 870 | * that will be read. | 902 | * that will be read. |
| 871 | */ | 903 | */ |
| 872 | amount = skb->len - sizeof(struct udphdr); | 904 | amount -= sizeof(struct udphdr); |
| 873 | } | 905 | |
| 874 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
| 875 | return put_user(amount, (int __user *)arg); | 906 | return put_user(amount, (int __user *)arg); |
| 876 | } | 907 | } |
| 877 | 908 | ||
| @@ -968,9 +999,7 @@ try_again: | |||
| 968 | err = ulen; | 999 | err = ulen; |
| 969 | 1000 | ||
| 970 | out_free: | 1001 | out_free: |
| 971 | lock_sock(sk); | 1002 | skb_free_datagram_locked(sk, skb); |
| 972 | skb_free_datagram(sk, skb); | ||
| 973 | release_sock(sk); | ||
| 974 | out: | 1003 | out: |
| 975 | return err; | 1004 | return err; |
| 976 | 1005 | ||
| @@ -1540,29 +1569,11 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 1540 | { | 1569 | { |
| 1541 | unsigned int mask = datagram_poll(file, sock, wait); | 1570 | unsigned int mask = datagram_poll(file, sock, wait); |
| 1542 | struct sock *sk = sock->sk; | 1571 | struct sock *sk = sock->sk; |
| 1543 | int is_lite = IS_UDPLITE(sk); | ||
| 1544 | 1572 | ||
| 1545 | /* Check for false positives due to checksum errors */ | 1573 | /* Check for false positives due to checksum errors */ |
| 1546 | if ((mask & POLLRDNORM) && | 1574 | if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) && |
| 1547 | !(file->f_flags & O_NONBLOCK) && | 1575 | !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk)) |
| 1548 | !(sk->sk_shutdown & RCV_SHUTDOWN)) { | 1576 | mask &= ~(POLLIN | POLLRDNORM); |
| 1549 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; | ||
| 1550 | struct sk_buff *skb; | ||
| 1551 | |||
| 1552 | spin_lock_bh(&rcvq->lock); | ||
| 1553 | while ((skb = skb_peek(rcvq)) != NULL && | ||
| 1554 | udp_lib_checksum_complete(skb)) { | ||
| 1555 | UDP_INC_STATS_BH(sock_net(sk), | ||
| 1556 | UDP_MIB_INERRORS, is_lite); | ||
| 1557 | __skb_unlink(skb, rcvq); | ||
| 1558 | kfree_skb(skb); | ||
| 1559 | } | ||
| 1560 | spin_unlock_bh(&rcvq->lock); | ||
| 1561 | |||
| 1562 | /* nothing to see, move along */ | ||
| 1563 | if (skb == NULL) | ||
| 1564 | mask &= ~(POLLIN | POLLRDNORM); | ||
| 1565 | } | ||
| 1566 | 1577 | ||
| 1567 | return mask; | 1578 | return mask; |
| 1568 | 1579 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 14f54eb5a7f..4f7aaf6996a 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -496,13 +496,17 @@ done: | |||
| 496 | goto e_inval; | 496 | goto e_inval; |
| 497 | 497 | ||
| 498 | if (val) { | 498 | if (val) { |
| 499 | struct net_device *dev; | ||
| 500 | |||
| 499 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) | 501 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) |
| 500 | goto e_inval; | 502 | goto e_inval; |
| 501 | 503 | ||
| 502 | if (__dev_get_by_index(net, val) == NULL) { | 504 | dev = dev_get_by_index(net, val); |
| 505 | if (!dev) { | ||
| 503 | retv = -ENODEV; | 506 | retv = -ENODEV; |
| 504 | break; | 507 | break; |
| 505 | } | 508 | } |
| 509 | dev_put(dev); | ||
| 506 | } | 510 | } |
| 507 | np->mcast_oif = val; | 511 | np->mcast_oif = val; |
| 508 | retv = 0; | 512 | retv = 0; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3a60f12b34e..cf538ed5ef6 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -288,9 +288,7 @@ try_again: | |||
| 288 | err = ulen; | 288 | err = ulen; |
| 289 | 289 | ||
| 290 | out_free: | 290 | out_free: |
| 291 | lock_sock(sk); | 291 | skb_free_datagram_locked(sk, skb); |
| 292 | skb_free_datagram(sk, skb); | ||
| 293 | release_sock(sk); | ||
| 294 | out: | 292 | out: |
| 295 | return err; | 293 | return err; |
| 296 | 294 | ||
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index bd765f30dba..b09948ceec4 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
| @@ -666,26 +666,25 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 666 | 666 | ||
| 667 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 667 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 668 | 668 | ||
| 669 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
| 670 | |||
| 669 | spin_lock_bh(&sta->lock); | 671 | spin_lock_bh(&sta->lock); |
| 670 | 672 | ||
| 671 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 673 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) |
| 672 | spin_unlock_bh(&sta->lock); | 674 | goto timer_still_needed; |
| 673 | return; | ||
| 674 | } | ||
| 675 | 675 | ||
| 676 | if (mgmt->u.action.u.addba_resp.dialog_token != | 676 | if (mgmt->u.action.u.addba_resp.dialog_token != |
| 677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
| 678 | spin_unlock_bh(&sta->lock); | ||
| 679 | #ifdef CONFIG_MAC80211_HT_DEBUG | 678 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 680 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 679 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
| 681 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 680 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 682 | return; | 681 | goto timer_still_needed; |
| 683 | } | 682 | } |
| 684 | 683 | ||
| 685 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
| 686 | #ifdef CONFIG_MAC80211_HT_DEBUG | 684 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 687 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); | 685 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); |
| 688 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 686 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 687 | |||
| 689 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | 688 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) |
| 690 | == WLAN_STATUS_SUCCESS) { | 689 | == WLAN_STATUS_SUCCESS) { |
| 691 | u8 curstate = *state; | 690 | u8 curstate = *state; |
| @@ -699,5 +698,11 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 699 | } else { | 698 | } else { |
| 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 699 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
| 701 | } | 700 | } |
| 701 | |||
| 702 | goto out; | ||
| 703 | |||
| 704 | timer_still_needed: | ||
| 705 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
| 706 | out: | ||
| 702 | spin_unlock_bh(&sta->lock); | 707 | spin_unlock_bh(&sta->lock); |
| 703 | } | 708 | } |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5608f6c6841..7b5131bd6fa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -72,6 +72,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
| 72 | struct ieee80211_sub_if_data *sdata; | 72 | struct ieee80211_sub_if_data *sdata; |
| 73 | int ret; | 73 | int ret; |
| 74 | 74 | ||
| 75 | if (netif_running(dev)) | ||
| 76 | return -EBUSY; | ||
| 77 | |||
| 75 | if (!nl80211_type_check(type)) | 78 | if (!nl80211_type_check(type)) |
| 76 | return -EINVAL; | 79 | return -EINVAL; |
| 77 | 80 | ||
| @@ -81,9 +84,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
| 81 | if (ret) | 84 | if (ret) |
| 82 | return ret; | 85 | return ret; |
| 83 | 86 | ||
| 84 | if (netif_running(sdata->dev)) | ||
| 85 | return -EBUSY; | ||
| 86 | |||
| 87 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) | 87 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) |
| 88 | ieee80211_sdata_set_mesh_id(sdata, | 88 | ieee80211_sdata_set_mesh_id(sdata, |
| 89 | params->mesh_id_len, | 89 | params->mesh_id_len, |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 0891bfb0699..48ef1a282b9 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -153,7 +153,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
| 153 | if (net_ratelimit()) | 153 | if (net_ratelimit()) |
| 154 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", | 154 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", |
| 155 | mgmt->sa, initiator ? "initiator" : "recipient", tid, | 155 | mgmt->sa, initiator ? "initiator" : "recipient", tid, |
| 156 | mgmt->u.action.u.delba.reason_code); | 156 | le16_to_cpu(mgmt->u.action.u.delba.reason_code)); |
| 157 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 157 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 158 | 158 | ||
| 159 | if (initiator == WLAN_BACK_INITIATOR) | 159 | if (initiator == WLAN_BACK_INITIATOR) |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 920ec8792f4..f1362f32c17 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -73,6 +73,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 73 | struct ieee80211_mgmt *mgmt; | 73 | struct ieee80211_mgmt *mgmt; |
| 74 | u8 *pos; | 74 | u8 *pos; |
| 75 | struct ieee80211_supported_band *sband; | 75 | struct ieee80211_supported_band *sband; |
| 76 | struct cfg80211_bss *bss; | ||
| 76 | u32 bss_change; | 77 | u32 bss_change; |
| 77 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 78 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
| 78 | 79 | ||
| @@ -177,8 +178,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
| 177 | mod_timer(&ifibss->timer, | 178 | mod_timer(&ifibss->timer, |
| 178 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); | 179 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); |
| 179 | 180 | ||
| 180 | cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, | 181 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, |
| 181 | mgmt, skb->len, 0, GFP_KERNEL); | 182 | mgmt, skb->len, 0, GFP_KERNEL); |
| 183 | cfg80211_put_bss(bss); | ||
| 182 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); | 184 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); |
| 183 | } | 185 | } |
| 184 | 186 | ||
| @@ -538,13 +540,12 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
| 538 | WLAN_CAPABILITY_PRIVACY, | 540 | WLAN_CAPABILITY_PRIVACY, |
| 539 | capability); | 541 | capability); |
| 540 | 542 | ||
| 543 | if (bss) { | ||
| 541 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 544 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 542 | if (bss) | ||
| 543 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " | 545 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " |
| 544 | "%pM\n", bss->cbss.bssid, ifibss->bssid); | 546 | "%pM\n", bss->cbss.bssid, ifibss->bssid); |
| 545 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 547 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
| 546 | 548 | ||
| 547 | if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) { | ||
| 548 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" | 549 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" |
| 549 | " based on configured SSID\n", | 550 | " based on configured SSID\n", |
| 550 | sdata->dev->name, bss->cbss.bssid); | 551 | sdata->dev->name, bss->cbss.bssid); |
| @@ -552,8 +553,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
| 552 | ieee80211_sta_join_ibss(sdata, bss); | 553 | ieee80211_sta_join_ibss(sdata, bss); |
| 553 | ieee80211_rx_bss_put(local, bss); | 554 | ieee80211_rx_bss_put(local, bss); |
| 554 | return; | 555 | return; |
| 555 | } else if (bss) | 556 | } |
| 556 | ieee80211_rx_bss_put(local, bss); | ||
| 557 | 557 | ||
| 558 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 558 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 559 | printk(KERN_DEBUG " did not try to join ibss\n"); | 559 | printk(KERN_DEBUG " did not try to join ibss\n"); |
| @@ -829,7 +829,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) | |||
| 829 | if (!sdata->u.ibss.ssid_len) | 829 | if (!sdata->u.ibss.ssid_len) |
| 830 | continue; | 830 | continue; |
| 831 | sdata->u.ibss.last_scan_completed = jiffies; | 831 | sdata->u.ibss.last_scan_completed = jiffies; |
| 832 | ieee80211_sta_find_ibss(sdata); | 832 | mod_timer(&sdata->u.ibss.timer, 0); |
| 833 | } | 833 | } |
| 834 | mutex_unlock(&local->iflist_mtx); | 834 | mutex_unlock(&local->iflist_mtx); |
| 835 | } | 835 | } |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index e12a786e26b..29b82e98eff 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
| @@ -259,7 +259,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
| 259 | * @hwmp_ie: hwmp information element (PREP or PREQ) | 259 | * @hwmp_ie: hwmp information element (PREP or PREQ) |
| 260 | * | 260 | * |
| 261 | * This function updates the path routing information to the originator and the | 261 | * This function updates the path routing information to the originator and the |
| 262 | * transmitter of a HWMP PREQ or PREP fram. | 262 | * transmitter of a HWMP PREQ or PREP frame. |
| 263 | * | 263 | * |
| 264 | * Returns: metric to frame originator or 0 if the frame should not be further | 264 | * Returns: metric to frame originator or 0 if the frame should not be further |
| 265 | * processed | 265 | * processed |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 8d26e9bf896..dc5049d58c5 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1457,8 +1457,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 1457 | if (status_code != WLAN_STATUS_SUCCESS) { | 1457 | if (status_code != WLAN_STATUS_SUCCESS) { |
| 1458 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", | 1458 | printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", |
| 1459 | sdata->dev->name, status_code); | 1459 | sdata->dev->name, status_code); |
| 1460 | list_del(&wk->list); | 1460 | wk->state = IEEE80211_MGD_STATE_IDLE; |
| 1461 | kfree(wk); | ||
| 1462 | return RX_MGMT_CFG80211_ASSOC; | 1461 | return RX_MGMT_CFG80211_ASSOC; |
| 1463 | } | 1462 | } |
| 1464 | 1463 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c01588f9d45..7170bf4565a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2164,11 +2164,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
| 2164 | 2164 | ||
| 2165 | skb = rx.skb; | 2165 | skb = rx.skb; |
| 2166 | 2166 | ||
| 2167 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 2167 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { |
| 2168 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
| 2169 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | ||
| 2170 | if (prepares) | ||
| 2171 | prev = rx.sdata; | ||
| 2172 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
| 2168 | if (!netif_running(sdata->dev)) | 2173 | if (!netif_running(sdata->dev)) |
| 2169 | continue; | 2174 | continue; |
| 2170 | 2175 | ||
| 2171 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | 2176 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
| 2177 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
| 2172 | continue; | 2178 | continue; |
| 2173 | 2179 | ||
| 2174 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2180 | rx.flags |= IEEE80211_RX_RA_MATCH; |
| @@ -2447,6 +2453,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 2447 | struct ieee80211_supported_band *sband; | 2453 | struct ieee80211_supported_band *sband; |
| 2448 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2454 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
| 2449 | 2455 | ||
| 2456 | WARN_ON_ONCE(softirq_count() == 0); | ||
| 2457 | |||
| 2450 | if (WARN_ON(status->band < 0 || | 2458 | if (WARN_ON(status->band < 0 || |
| 2451 | status->band >= IEEE80211_NUM_BANDS)) | 2459 | status->band >= IEEE80211_NUM_BANDS)) |
| 2452 | goto drop; | 2460 | goto drop; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index eec001491e6..594f2318c3d 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -361,6 +361,7 @@ int sta_info_insert(struct sta_info *sta) | |||
| 361 | u.ap); | 361 | u.ap); |
| 362 | 362 | ||
| 363 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); | 363 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); |
| 364 | sdata = sta->sdata; | ||
| 364 | } | 365 | } |
| 365 | 366 | ||
| 366 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 367 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
| @@ -496,6 +497,7 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
| 496 | 497 | ||
| 497 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, | 498 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, |
| 498 | &(*sta)->sta); | 499 | &(*sta)->sta); |
| 500 | sdata = (*sta)->sdata; | ||
| 499 | } | 501 | } |
| 500 | 502 | ||
| 501 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 503 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index fd402829661..eaa4118de98 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1445,7 +1445,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
| 1445 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1445 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) |
| 1446 | continue; | 1446 | continue; |
| 1447 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, | 1447 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, |
| 1448 | hdr->addr2)) { | 1448 | hdr->addr2) == 0) { |
| 1449 | dev_hold(tmp_sdata->dev); | 1449 | dev_hold(tmp_sdata->dev); |
| 1450 | dev_put(sdata->dev); | 1450 | dev_put(sdata->dev); |
| 1451 | sdata = tmp_sdata; | 1451 | sdata = tmp_sdata; |
| @@ -1704,7 +1704,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1704 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1704 | if (!is_multicast_ether_addr(hdr.addr1)) { |
| 1705 | rcu_read_lock(); | 1705 | rcu_read_lock(); |
| 1706 | sta = sta_info_get(local, hdr.addr1); | 1706 | sta = sta_info_get(local, hdr.addr1); |
| 1707 | if (sta) | 1707 | /* XXX: in the future, use sdata to look up the sta */ |
| 1708 | if (sta && sta->sdata == sdata) | ||
| 1708 | sta_flags = get_sta_flags(sta); | 1709 | sta_flags = get_sta_flags(sta); |
| 1709 | rcu_read_unlock(); | 1710 | rcu_read_unlock(); |
| 1710 | } | 1711 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index dd656432136..aeb65b3d229 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -339,7 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
| 339 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 339 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 340 | 340 | ||
| 341 | if (WARN_ON(!info->control.vif)) { | 341 | if (WARN_ON(!info->control.vif)) { |
| 342 | kfree(skb); | 342 | kfree_skb(skb); |
| 343 | return; | 343 | return; |
| 344 | } | 344 | } |
| 345 | 345 | ||
| @@ -367,7 +367,7 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
| 367 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 367 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 368 | 368 | ||
| 369 | if (WARN_ON(!info->control.vif)) { | 369 | if (WARN_ON(!info->control.vif)) { |
| 370 | kfree(skb); | 370 | kfree_skb(skb); |
| 371 | continue; | 371 | continue; |
| 372 | } | 372 | } |
| 373 | 373 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ca6e68dcd8a..b9168c1864c 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -1351,6 +1351,11 @@ err_stat: | |||
| 1351 | return ret; | 1351 | return ret; |
| 1352 | } | 1352 | } |
| 1353 | 1353 | ||
| 1354 | s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, | ||
| 1355 | enum ip_conntrack_dir dir, | ||
| 1356 | u32 seq); | ||
| 1357 | EXPORT_SYMBOL_GPL(nf_ct_nat_offset); | ||
| 1358 | |||
| 1354 | int nf_conntrack_init(struct net *net) | 1359 | int nf_conntrack_init(struct net *net) |
| 1355 | { | 1360 | { |
| 1356 | int ret; | 1361 | int ret; |
| @@ -1368,6 +1373,9 @@ int nf_conntrack_init(struct net *net) | |||
| 1368 | /* For use by REJECT target */ | 1373 | /* For use by REJECT target */ |
| 1369 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); | 1374 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); |
| 1370 | rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); | 1375 | rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); |
| 1376 | |||
| 1377 | /* Howto get NAT offsets */ | ||
| 1378 | rcu_assign_pointer(nf_ct_nat_offset, NULL); | ||
| 1371 | } | 1379 | } |
| 1372 | return 0; | 1380 | return 0; |
| 1373 | 1381 | ||
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 97a82ba7537..ba2b7693728 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
| @@ -492,6 +492,21 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, | |||
| 492 | } | 492 | } |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | #ifdef CONFIG_NF_NAT_NEEDED | ||
| 496 | static inline s16 nat_offset(const struct nf_conn *ct, | ||
| 497 | enum ip_conntrack_dir dir, | ||
| 498 | u32 seq) | ||
| 499 | { | ||
| 500 | typeof(nf_ct_nat_offset) get_offset = rcu_dereference(nf_ct_nat_offset); | ||
| 501 | |||
| 502 | return get_offset != NULL ? get_offset(ct, dir, seq) : 0; | ||
| 503 | } | ||
| 504 | #define NAT_OFFSET(pf, ct, dir, seq) \ | ||
| 505 | (pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0) | ||
| 506 | #else | ||
| 507 | #define NAT_OFFSET(pf, ct, dir, seq) 0 | ||
| 508 | #endif | ||
| 509 | |||
| 495 | static bool tcp_in_window(const struct nf_conn *ct, | 510 | static bool tcp_in_window(const struct nf_conn *ct, |
| 496 | struct ip_ct_tcp *state, | 511 | struct ip_ct_tcp *state, |
| 497 | enum ip_conntrack_dir dir, | 512 | enum ip_conntrack_dir dir, |
| @@ -506,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
| 506 | struct ip_ct_tcp_state *receiver = &state->seen[!dir]; | 521 | struct ip_ct_tcp_state *receiver = &state->seen[!dir]; |
| 507 | const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; | 522 | const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; |
| 508 | __u32 seq, ack, sack, end, win, swin; | 523 | __u32 seq, ack, sack, end, win, swin; |
| 524 | s16 receiver_offset; | ||
| 509 | bool res; | 525 | bool res; |
| 510 | 526 | ||
| 511 | /* | 527 | /* |
| @@ -519,11 +535,16 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
| 519 | if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) | 535 | if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) |
| 520 | tcp_sack(skb, dataoff, tcph, &sack); | 536 | tcp_sack(skb, dataoff, tcph, &sack); |
| 521 | 537 | ||
| 538 | /* Take into account NAT sequence number mangling */ | ||
| 539 | receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1); | ||
| 540 | ack -= receiver_offset; | ||
| 541 | sack -= receiver_offset; | ||
| 542 | |||
| 522 | pr_debug("tcp_in_window: START\n"); | 543 | pr_debug("tcp_in_window: START\n"); |
| 523 | pr_debug("tcp_in_window: "); | 544 | pr_debug("tcp_in_window: "); |
| 524 | nf_ct_dump_tuple(tuple); | 545 | nf_ct_dump_tuple(tuple); |
| 525 | pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n", | 546 | pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", |
| 526 | seq, ack, sack, win, end); | 547 | seq, ack, receiver_offset, sack, receiver_offset, win, end); |
| 527 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " | 548 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " |
| 528 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", | 549 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", |
| 529 | sender->td_end, sender->td_maxend, sender->td_maxwin, | 550 | sender->td_end, sender->td_maxend, sender->td_maxwin, |
| @@ -613,8 +634,8 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
| 613 | 634 | ||
| 614 | pr_debug("tcp_in_window: "); | 635 | pr_debug("tcp_in_window: "); |
| 615 | nf_ct_dump_tuple(tuple); | 636 | nf_ct_dump_tuple(tuple); |
| 616 | pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n", | 637 | pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", |
| 617 | seq, ack, sack, win, end); | 638 | seq, ack, receiver_offset, sack, receiver_offset, win, end); |
| 618 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " | 639 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " |
| 619 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", | 640 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", |
| 620 | sender->td_end, sender->td_maxend, sender->td_maxwin, | 641 | sender->td_end, sender->td_maxend, sender->td_maxwin, |
| @@ -700,7 +721,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
| 700 | before(seq, sender->td_maxend + 1) ? | 721 | before(seq, sender->td_maxend + 1) ? |
| 701 | after(end, sender->td_end - receiver->td_maxwin - 1) ? | 722 | after(end, sender->td_end - receiver->td_maxwin - 1) ? |
| 702 | before(sack, receiver->td_end + 1) ? | 723 | before(sack, receiver->td_end + 1) ? |
| 703 | after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG" | 724 | after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" |
| 704 | : "ACK is under the lower bound (possible overly delayed ACK)" | 725 | : "ACK is under the lower bound (possible overly delayed ACK)" |
| 705 | : "ACK is over the upper bound (ACKed data not seen yet)" | 726 | : "ACK is over the upper bound (ACKed data not seen yet)" |
| 706 | : "SEQ is under the lower bound (already ACKed data retransmitted)" | 727 | : "SEQ is under the lower bound (already ACKed data retransmitted)" |
| @@ -715,39 +736,6 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
| 715 | return res; | 736 | return res; |
| 716 | } | 737 | } |
| 717 | 738 | ||
| 718 | #ifdef CONFIG_NF_NAT_NEEDED | ||
| 719 | /* Update sender->td_end after NAT successfully mangled the packet */ | ||
| 720 | /* Caller must linearize skb at tcp header. */ | ||
| 721 | void nf_conntrack_tcp_update(const struct sk_buff *skb, | ||
| 722 | unsigned int dataoff, | ||
| 723 | struct nf_conn *ct, int dir, | ||
| 724 | s16 offset) | ||
| 725 | { | ||
| 726 | const struct tcphdr *tcph = (const void *)skb->data + dataoff; | ||
| 727 | const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir]; | ||
| 728 | const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir]; | ||
| 729 | __u32 end; | ||
| 730 | |||
| 731 | end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph); | ||
| 732 | |||
| 733 | spin_lock_bh(&ct->lock); | ||
| 734 | /* | ||
| 735 | * We have to worry for the ack in the reply packet only... | ||
| 736 | */ | ||
| 737 | if (ct->proto.tcp.seen[dir].td_end + offset == end) | ||
| 738 | ct->proto.tcp.seen[dir].td_end = end; | ||
| 739 | ct->proto.tcp.last_end = end; | ||
| 740 | spin_unlock_bh(&ct->lock); | ||
| 741 | pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i " | ||
| 742 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", | ||
| 743 | sender->td_end, sender->td_maxend, sender->td_maxwin, | ||
| 744 | sender->td_scale, | ||
| 745 | receiver->td_end, receiver->td_maxend, receiver->td_maxwin, | ||
| 746 | receiver->td_scale); | ||
| 747 | } | ||
| 748 | EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update); | ||
| 749 | #endif | ||
| 750 | |||
| 751 | #define TH_FIN 0x01 | 739 | #define TH_FIN 0x01 |
| 752 | #define TH_SYN 0x02 | 740 | #define TH_SYN 0x02 |
| 753 | #define TH_RST 0x04 | 741 | #define TH_RST 0x04 |
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 68098095439..38f03f75a63 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c | |||
| @@ -103,7 +103,7 @@ static int count_them(struct xt_connlimit_data *data, | |||
| 103 | const struct nf_conntrack_tuple *tuple, | 103 | const struct nf_conntrack_tuple *tuple, |
| 104 | const union nf_inet_addr *addr, | 104 | const union nf_inet_addr *addr, |
| 105 | const union nf_inet_addr *mask, | 105 | const union nf_inet_addr *mask, |
| 106 | const struct xt_match *match) | 106 | u_int8_t family) |
| 107 | { | 107 | { |
| 108 | const struct nf_conntrack_tuple_hash *found; | 108 | const struct nf_conntrack_tuple_hash *found; |
| 109 | struct xt_connlimit_conn *conn; | 109 | struct xt_connlimit_conn *conn; |
| @@ -113,8 +113,7 @@ static int count_them(struct xt_connlimit_data *data, | |||
| 113 | bool addit = true; | 113 | bool addit = true; |
| 114 | int matches = 0; | 114 | int matches = 0; |
| 115 | 115 | ||
| 116 | 116 | if (family == NFPROTO_IPV6) | |
| 117 | if (match->family == NFPROTO_IPV6) | ||
| 118 | hash = &data->iphash[connlimit_iphash6(addr, mask)]; | 117 | hash = &data->iphash[connlimit_iphash6(addr, mask)]; |
| 119 | else | 118 | else |
| 120 | hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; | 119 | hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; |
| @@ -157,8 +156,7 @@ static int count_them(struct xt_connlimit_data *data, | |||
| 157 | continue; | 156 | continue; |
| 158 | } | 157 | } |
| 159 | 158 | ||
| 160 | if (same_source_net(addr, mask, &conn->tuple.src.u3, | 159 | if (same_source_net(addr, mask, &conn->tuple.src.u3, family)) |
| 161 | match->family)) | ||
| 162 | /* same source network -> be counted! */ | 160 | /* same source network -> be counted! */ |
| 163 | ++matches; | 161 | ++matches; |
| 164 | nf_ct_put(found_ct); | 162 | nf_ct_put(found_ct); |
| @@ -207,7 +205,7 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
| 207 | 205 | ||
| 208 | spin_lock_bh(&info->data->lock); | 206 | spin_lock_bh(&info->data->lock); |
| 209 | connections = count_them(info->data, tuple_ptr, &addr, | 207 | connections = count_them(info->data, tuple_ptr, &addr, |
| 210 | &info->mask, par->match); | 208 | &info->mask, par->family); |
| 211 | spin_unlock_bh(&info->data->lock); | 209 | spin_unlock_bh(&info->data->lock); |
| 212 | 210 | ||
| 213 | if (connections < 0) { | 211 | if (connections < 0) { |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d7ecca0a0c0..f2d116a5cb3 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -982,10 +982,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 982 | goto out_put; | 982 | goto out_put; |
| 983 | 983 | ||
| 984 | size_max = po->tx_ring.frame_size | 984 | size_max = po->tx_ring.frame_size |
| 985 | - sizeof(struct skb_shared_info) | 985 | - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); |
| 986 | - po->tp_hdrlen | ||
| 987 | - LL_ALLOCATED_SPACE(dev) | ||
| 988 | - sizeof(struct sockaddr_ll); | ||
| 989 | 986 | ||
| 990 | if (size_max > dev->mtu + reserve) | 987 | if (size_max > dev->mtu + reserve) |
| 991 | size_max = dev->mtu + reserve; | 988 | size_max = dev->mtu + reserve; |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 9478d9b3d97..f3e21989b88 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
| @@ -578,18 +578,18 @@ static int rose_clear_routes(void) | |||
| 578 | 578 | ||
| 579 | /* | 579 | /* |
| 580 | * Check that the device given is a valid AX.25 interface that is "up". | 580 | * Check that the device given is a valid AX.25 interface that is "up". |
| 581 | * called whith RTNL | ||
| 581 | */ | 582 | */ |
| 582 | static struct net_device *rose_ax25_dev_get(char *devname) | 583 | static struct net_device *rose_ax25_dev_find(char *devname) |
| 583 | { | 584 | { |
| 584 | struct net_device *dev; | 585 | struct net_device *dev; |
| 585 | 586 | ||
| 586 | if ((dev = dev_get_by_name(&init_net, devname)) == NULL) | 587 | if ((dev = __dev_get_by_name(&init_net, devname)) == NULL) |
| 587 | return NULL; | 588 | return NULL; |
| 588 | 589 | ||
| 589 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) | 590 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) |
| 590 | return dev; | 591 | return dev; |
| 591 | 592 | ||
| 592 | dev_put(dev); | ||
| 593 | return NULL; | 593 | return NULL; |
| 594 | } | 594 | } |
| 595 | 595 | ||
| @@ -720,27 +720,23 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg) | |||
| 720 | case SIOCADDRT: | 720 | case SIOCADDRT: |
| 721 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) | 721 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) |
| 722 | return -EFAULT; | 722 | return -EFAULT; |
| 723 | if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) | 723 | if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL) |
| 724 | return -EINVAL; | 724 | return -EINVAL; |
| 725 | if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */ | 725 | if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */ |
| 726 | dev_put(dev); | ||
| 727 | return -EINVAL; | 726 | return -EINVAL; |
| 728 | } | ||
| 729 | if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ | 727 | if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ |
| 730 | return -EINVAL; | 728 | return -EINVAL; |
| 731 | if (rose_route.ndigis > AX25_MAX_DIGIS) | 729 | if (rose_route.ndigis > AX25_MAX_DIGIS) |
| 732 | return -EINVAL; | 730 | return -EINVAL; |
| 733 | err = rose_add_node(&rose_route, dev); | 731 | err = rose_add_node(&rose_route, dev); |
| 734 | dev_put(dev); | ||
| 735 | return err; | 732 | return err; |
| 736 | 733 | ||
| 737 | case SIOCDELRT: | 734 | case SIOCDELRT: |
| 738 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) | 735 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) |
| 739 | return -EFAULT; | 736 | return -EFAULT; |
| 740 | if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) | 737 | if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL) |
| 741 | return -EINVAL; | 738 | return -EINVAL; |
| 742 | err = rose_del_node(&rose_route, dev); | 739 | err = rose_del_node(&rose_route, dev); |
| 743 | dev_put(dev); | ||
| 744 | return err; | 740 | return err; |
| 745 | 741 | ||
| 746 | case SIOCRSCLRRT: | 742 | case SIOCRSCLRRT: |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 96c0ed115e2..6b0359a500e 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -34,7 +34,7 @@ static struct tcf_hashinfo pedit_hash_info = { | |||
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { | 36 | static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { |
| 37 | [TCA_PEDIT_PARMS] = { .len = sizeof(struct tcf_pedit) }, | 37 | [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, | 40 | static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 6a536949cdc..7cf6c0fbc7a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
| @@ -350,7 +350,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, | |||
| 350 | tcm = NLMSG_DATA(nlh); | 350 | tcm = NLMSG_DATA(nlh); |
| 351 | tcm->tcm_family = AF_UNSPEC; | 351 | tcm->tcm_family = AF_UNSPEC; |
| 352 | tcm->tcm__pad1 = 0; | 352 | tcm->tcm__pad1 = 0; |
| 353 | tcm->tcm__pad1 = 0; | 353 | tcm->tcm__pad2 = 0; |
| 354 | tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; | 354 | tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; |
| 355 | tcm->tcm_parent = tp->classid; | 355 | tcm->tcm_parent = tp->classid; |
| 356 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); | 356 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index ccc5e83cae5..1c246a4f491 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -111,7 +111,7 @@ static void svc_release_skb(struct svc_rqst *rqstp) | |||
| 111 | rqstp->rq_xprt_ctxt = NULL; | 111 | rqstp->rq_xprt_ctxt = NULL; |
| 112 | 112 | ||
| 113 | dprintk("svc: service %p, releasing skb %p\n", rqstp, skb); | 113 | dprintk("svc: service %p, releasing skb %p\n", rqstp, skb); |
| 114 | skb_free_datagram(svsk->sk_sk, skb); | 114 | skb_free_datagram_locked(svsk->sk_sk, skb); |
| 115 | } | 115 | } |
| 116 | } | 116 | } |
| 117 | 117 | ||
| @@ -578,7 +578,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
| 578 | "svc: received unknown control message %d/%d; " | 578 | "svc: received unknown control message %d/%d; " |
| 579 | "dropping RPC reply datagram\n", | 579 | "dropping RPC reply datagram\n", |
| 580 | cmh->cmsg_level, cmh->cmsg_type); | 580 | cmh->cmsg_level, cmh->cmsg_type); |
| 581 | skb_free_datagram(svsk->sk_sk, skb); | 581 | skb_free_datagram_locked(svsk->sk_sk, skb); |
| 582 | return 0; | 582 | return 0; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| @@ -588,18 +588,18 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
| 588 | if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { | 588 | if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) { |
| 589 | local_bh_enable(); | 589 | local_bh_enable(); |
| 590 | /* checksum error */ | 590 | /* checksum error */ |
| 591 | skb_free_datagram(svsk->sk_sk, skb); | 591 | skb_free_datagram_locked(svsk->sk_sk, skb); |
| 592 | return 0; | 592 | return 0; |
| 593 | } | 593 | } |
| 594 | local_bh_enable(); | 594 | local_bh_enable(); |
| 595 | skb_free_datagram(svsk->sk_sk, skb); | 595 | skb_free_datagram_locked(svsk->sk_sk, skb); |
| 596 | } else { | 596 | } else { |
| 597 | /* we can use it in-place */ | 597 | /* we can use it in-place */ |
| 598 | rqstp->rq_arg.head[0].iov_base = skb->data + | 598 | rqstp->rq_arg.head[0].iov_base = skb->data + |
| 599 | sizeof(struct udphdr); | 599 | sizeof(struct udphdr); |
| 600 | rqstp->rq_arg.head[0].iov_len = len; | 600 | rqstp->rq_arg.head[0].iov_len = len; |
| 601 | if (skb_checksum_complete(skb)) { | 601 | if (skb_checksum_complete(skb)) { |
| 602 | skb_free_datagram(svsk->sk_sk, skb); | 602 | skb_free_datagram_locked(svsk->sk_sk, skb); |
| 603 | return 0; | 603 | return 0; |
| 604 | } | 604 | } |
| 605 | rqstp->rq_xprt_ctxt = skb; | 605 | rqstp->rq_xprt_ctxt = skb; |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51ab497115e..fc820cd7545 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1074,6 +1074,8 @@ restart: | |||
| 1074 | err = -ECONNREFUSED; | 1074 | err = -ECONNREFUSED; |
| 1075 | if (other->sk_state != TCP_LISTEN) | 1075 | if (other->sk_state != TCP_LISTEN) |
| 1076 | goto out_unlock; | 1076 | goto out_unlock; |
| 1077 | if (other->sk_shutdown & RCV_SHUTDOWN) | ||
| 1078 | goto out_unlock; | ||
| 1077 | 1079 | ||
| 1078 | if (unix_recvq_full(other)) { | 1080 | if (unix_recvq_full(other)) { |
| 1079 | err = -EAGAIN; | 1081 | err = -EAGAIN; |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 2a33d8bc886..68b321997d4 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -358,6 +358,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | |||
| 358 | struct wireless_dev *wdev); | 358 | struct wireless_dev *wdev); |
| 359 | 359 | ||
| 360 | void cfg80211_conn_work(struct work_struct *work); | 360 | void cfg80211_conn_work(struct work_struct *work); |
| 361 | void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); | ||
| 361 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); | 362 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); |
| 362 | 363 | ||
| 363 | /* internal helpers */ | 364 | /* internal helpers */ |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 79d2eec54ce..0a6b7a0eca6 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -62,6 +62,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
| 62 | u8 *ie = mgmt->u.assoc_resp.variable; | 62 | u8 *ie = mgmt->u.assoc_resp.variable; |
| 63 | int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); | 63 | int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); |
| 64 | struct cfg80211_internal_bss *bss = NULL; | 64 | struct cfg80211_internal_bss *bss = NULL; |
| 65 | bool need_connect_result = true; | ||
| 65 | 66 | ||
| 66 | wdev_lock(wdev); | 67 | wdev_lock(wdev); |
| 67 | 68 | ||
| @@ -94,6 +95,14 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | WARN_ON(!bss); | 97 | WARN_ON(!bss); |
| 98 | } else if (wdev->conn) { | ||
| 99 | cfg80211_sme_failed_assoc(wdev); | ||
| 100 | need_connect_result = false; | ||
| 101 | /* | ||
| 102 | * do not call connect_result() now because the | ||
| 103 | * sme will schedule work that does it later. | ||
| 104 | */ | ||
| 105 | goto out; | ||
| 97 | } | 106 | } |
| 98 | 107 | ||
| 99 | if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { | 108 | if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index eddab097435..ca3c92a0a14 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -4029,7 +4029,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) | |||
| 4029 | rdev = cfg80211_get_dev_from_info(info); | 4029 | rdev = cfg80211_get_dev_from_info(info); |
| 4030 | if (IS_ERR(rdev)) { | 4030 | if (IS_ERR(rdev)) { |
| 4031 | err = PTR_ERR(rdev); | 4031 | err = PTR_ERR(rdev); |
| 4032 | goto out; | 4032 | goto out_rtnl; |
| 4033 | } | 4033 | } |
| 4034 | 4034 | ||
| 4035 | net = get_net_ns_by_pid(pid); | 4035 | net = get_net_ns_by_pid(pid); |
| @@ -4049,6 +4049,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) | |||
| 4049 | put_net(net); | 4049 | put_net(net); |
| 4050 | out: | 4050 | out: |
| 4051 | cfg80211_unlock_rdev(rdev); | 4051 | cfg80211_unlock_rdev(rdev); |
| 4052 | out_rtnl: | ||
| 4052 | rtnl_unlock(); | 4053 | rtnl_unlock(); |
| 4053 | return err; | 4054 | return err; |
| 4054 | } | 4055 | } |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 93c3ed32920..9f0b2800a9d 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
| @@ -26,6 +26,7 @@ struct cfg80211_conn { | |||
| 26 | CFG80211_CONN_AUTHENTICATING, | 26 | CFG80211_CONN_AUTHENTICATING, |
| 27 | CFG80211_CONN_ASSOCIATE_NEXT, | 27 | CFG80211_CONN_ASSOCIATE_NEXT, |
| 28 | CFG80211_CONN_ASSOCIATING, | 28 | CFG80211_CONN_ASSOCIATING, |
| 29 | CFG80211_CONN_DEAUTH_ASSOC_FAIL, | ||
| 29 | } state; | 30 | } state; |
| 30 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; | 31 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; |
| 31 | u8 *ie; | 32 | u8 *ie; |
| @@ -148,6 +149,12 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
| 148 | NULL, 0, | 149 | NULL, 0, |
| 149 | WLAN_REASON_DEAUTH_LEAVING); | 150 | WLAN_REASON_DEAUTH_LEAVING); |
| 150 | return err; | 151 | return err; |
| 152 | case CFG80211_CONN_DEAUTH_ASSOC_FAIL: | ||
| 153 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | ||
| 154 | NULL, 0, | ||
| 155 | WLAN_REASON_DEAUTH_LEAVING); | ||
| 156 | /* return an error so that we call __cfg80211_connect_result() */ | ||
| 157 | return -EINVAL; | ||
| 151 | default: | 158 | default: |
| 152 | return 0; | 159 | return 0; |
| 153 | } | 160 | } |
| @@ -158,6 +165,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
| 158 | struct cfg80211_registered_device *rdev = | 165 | struct cfg80211_registered_device *rdev = |
| 159 | container_of(work, struct cfg80211_registered_device, conn_work); | 166 | container_of(work, struct cfg80211_registered_device, conn_work); |
| 160 | struct wireless_dev *wdev; | 167 | struct wireless_dev *wdev; |
| 168 | u8 bssid_buf[ETH_ALEN], *bssid = NULL; | ||
| 161 | 169 | ||
| 162 | rtnl_lock(); | 170 | rtnl_lock(); |
| 163 | cfg80211_lock_rdev(rdev); | 171 | cfg80211_lock_rdev(rdev); |
| @@ -173,10 +181,13 @@ void cfg80211_conn_work(struct work_struct *work) | |||
| 173 | wdev_unlock(wdev); | 181 | wdev_unlock(wdev); |
| 174 | continue; | 182 | continue; |
| 175 | } | 183 | } |
| 184 | if (wdev->conn->params.bssid) { | ||
| 185 | memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); | ||
| 186 | bssid = bssid_buf; | ||
| 187 | } | ||
| 176 | if (cfg80211_conn_do_work(wdev)) | 188 | if (cfg80211_conn_do_work(wdev)) |
| 177 | __cfg80211_connect_result( | 189 | __cfg80211_connect_result( |
| 178 | wdev->netdev, | 190 | wdev->netdev, bssid, |
| 179 | wdev->conn->params.bssid, | ||
| 180 | NULL, 0, NULL, 0, | 191 | NULL, 0, NULL, 0, |
| 181 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 192 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
| 182 | false, NULL); | 193 | false, NULL); |
| @@ -337,6 +348,15 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev) | |||
| 337 | return true; | 348 | return true; |
| 338 | } | 349 | } |
| 339 | 350 | ||
| 351 | void cfg80211_sme_failed_assoc(struct wireless_dev *wdev) | ||
| 352 | { | ||
| 353 | struct wiphy *wiphy = wdev->wiphy; | ||
| 354 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
| 355 | |||
| 356 | wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL; | ||
| 357 | schedule_work(&rdev->conn_work); | ||
| 358 | } | ||
| 359 | |||
| 340 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 360 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
| 341 | const u8 *req_ie, size_t req_ie_len, | 361 | const u8 *req_ie, size_t req_ie_len, |
| 342 | const u8 *resp_ie, size_t resp_ie_len, | 362 | const u8 *resp_ie, size_t resp_ie_len, |
