diff options
| author | David S. Miller <davem@davemloft.net> | 2009-12-03 15:51:21 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-12-03 15:51:21 -0500 |
| commit | a6c872afb2536f47285e6643f4629dec7520041d (patch) | |
| tree | 4b54e69fc6594f9afc1277520a350db04e578e77 /net | |
| parent | 9fe02668fe48a1d546196bc1392330ff28d9bd57 (diff) | |
| parent | 22763c5cf3690a681551162c15d34d935308c8d7 (diff) | |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'net')
53 files changed, 379 insertions, 291 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 8836575f9d79..a29c5ab5815c 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -281,8 +281,11 @@ out_uninit_applicant: | |||
| 281 | if (ngrp) | 281 | if (ngrp) |
| 282 | vlan_gvrp_uninit_applicant(real_dev); | 282 | vlan_gvrp_uninit_applicant(real_dev); |
| 283 | out_free_group: | 283 | out_free_group: |
| 284 | if (ngrp) | 284 | if (ngrp) { |
| 285 | vlan_group_free(ngrp); | 285 | hlist_del_rcu(&ngrp->hlist); |
| 286 | /* Free the group, after all cpu's are done. */ | ||
| 287 | call_rcu(&ngrp->rcu, vlan_rcu_free); | ||
| 288 | } | ||
| 286 | return err; | 289 | return err; |
| 287 | } | 290 | } |
| 288 | 291 | ||
diff --git a/net/9p/client.c b/net/9p/client.c index 5bf5f227dbe0..8af95b2dddd6 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/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index a9750984f772..b7c4224f4e7d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -211,6 +211,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
| 211 | conn->type = type; | 211 | conn->type = type; |
| 212 | conn->mode = HCI_CM_ACTIVE; | 212 | conn->mode = HCI_CM_ACTIVE; |
| 213 | conn->state = BT_OPEN; | 213 | conn->state = BT_OPEN; |
| 214 | conn->auth_type = HCI_AT_GENERAL_BONDING; | ||
| 214 | 215 | ||
| 215 | conn->power_save = 1; | 216 | conn->power_save = 1; |
| 216 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 217 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 77e9fb130adb..947f8bbb4bb3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -2205,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
| 2205 | { | 2205 | { |
| 2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
| 2207 | struct l2cap_conf_req *req = data; | 2207 | struct l2cap_conf_req *req = data; |
| 2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM }; | 2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
| 2209 | void *ptr = req->data; | 2209 | void *ptr = req->data; |
| 2210 | 2210 | ||
| 2211 | BT_DBG("sk %p", sk); | 2211 | BT_DBG("sk %p", sk); |
| @@ -2394,6 +2394,10 @@ done: | |||
| 2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; | 2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; |
| 2395 | 2395 | ||
| 2396 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 2396 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
| 2397 | |||
| 2398 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
| 2399 | sizeof(rfc), (unsigned long) &rfc); | ||
| 2400 | |||
| 2397 | break; | 2401 | break; |
| 2398 | 2402 | ||
| 2399 | case L2CAP_MODE_STREAMING: | 2403 | case L2CAP_MODE_STREAMING: |
| @@ -2401,6 +2405,10 @@ done: | |||
| 2401 | pi->max_pdu_size = rfc.max_pdu_size; | 2405 | pi->max_pdu_size = rfc.max_pdu_size; |
| 2402 | 2406 | ||
| 2403 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 2407 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
| 2408 | |||
| 2409 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
| 2410 | sizeof(rfc), (unsigned long) &rfc); | ||
| 2411 | |||
| 2404 | break; | 2412 | break; |
| 2405 | 2413 | ||
| 2406 | default: | 2414 | default: |
| @@ -2410,9 +2418,6 @@ done: | |||
| 2410 | rfc.mode = pi->mode; | 2418 | rfc.mode = pi->mode; |
| 2411 | } | 2419 | } |
| 2412 | 2420 | ||
| 2413 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
| 2414 | sizeof(rfc), (unsigned long) &rfc); | ||
| 2415 | |||
| 2416 | if (result == L2CAP_CONF_SUCCESS) | 2421 | if (result == L2CAP_CONF_SUCCESS) |
| 2417 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 2422 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; |
| 2418 | } | 2423 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b1b3b0fbf41c..4a9f52732655 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 597da4f8f888..e8d58f33fe09 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 1c6cf3a1a4f6..4ade3011bb3c 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/dev.c b/net/core/dev.c index b8f74cfb1bfd..fe10551d3671 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -942,14 +942,15 @@ rollback: | |||
| 942 | ret = notifier_to_errno(ret); | 942 | ret = notifier_to_errno(ret); |
| 943 | 943 | ||
| 944 | if (ret) { | 944 | if (ret) { |
| 945 | if (err) { | 945 | /* err >= 0 after dev_alloc_name() or stores the first errno */ |
| 946 | printk(KERN_ERR | 946 | if (err >= 0) { |
| 947 | "%s: name change rollback failed: %d.\n", | ||
| 948 | dev->name, ret); | ||
| 949 | } else { | ||
| 950 | err = ret; | 947 | err = ret; |
| 951 | memcpy(dev->name, oldname, IFNAMSIZ); | 948 | memcpy(dev->name, oldname, IFNAMSIZ); |
| 952 | goto rollback; | 949 | goto rollback; |
| 950 | } else { | ||
| 951 | printk(KERN_ERR | ||
| 952 | "%s: name change rollback failed: %d.\n", | ||
| 953 | dev->name, ret); | ||
| 953 | } | 954 | } |
| 954 | } | 955 | } |
| 955 | 956 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 86acdba0a97d..6e79e96cb4f2 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; |
| @@ -362,6 +363,7 @@ struct pktgen_dev { | |||
| 362 | * device name (not when the inject is | 363 | * device name (not when the inject is |
| 363 | * started as it used to do.) | 364 | * started as it used to do.) |
| 364 | */ | 365 | */ |
| 366 | char odevname[32]; | ||
| 365 | struct flow_state *flows; | 367 | struct flow_state *flows; |
| 366 | unsigned cflows; /* Concurrent flows (config) */ | 368 | unsigned cflows; /* Concurrent flows (config) */ |
| 367 | unsigned lflow; /* Flow length (config) */ | 369 | unsigned lflow; /* Flow length (config) */ |
| @@ -425,7 +427,7 @@ static const char version[] = | |||
| 425 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); | 427 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); |
| 426 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); | 428 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); |
| 427 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 429 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
| 428 | const char *ifname); | 430 | const char *ifname, bool exact); |
| 429 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); | 431 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); |
| 430 | static void pktgen_run_all_threads(void); | 432 | static void pktgen_run_all_threads(void); |
| 431 | static void pktgen_reset_all_threads(void); | 433 | static void pktgen_reset_all_threads(void); |
| @@ -527,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
| 527 | seq_printf(seq, | 529 | seq_printf(seq, |
| 528 | " frags: %d delay: %llu clone_skb: %d ifname: %s\n", | 530 | " frags: %d delay: %llu clone_skb: %d ifname: %s\n", |
| 529 | pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, | 531 | pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, |
| 530 | pkt_dev->clone_skb, pkt_dev->odev->name); | 532 | pkt_dev->clone_skb, pkt_dev->odevname); |
| 531 | 533 | ||
| 532 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, | 534 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, |
| 533 | pkt_dev->lflow); | 535 | pkt_dev->lflow); |
| @@ -1687,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v) | |||
| 1687 | if_lock(t); | 1689 | if_lock(t); |
| 1688 | list_for_each_entry(pkt_dev, &t->if_list, list) | 1690 | list_for_each_entry(pkt_dev, &t->if_list, list) |
| 1689 | if (pkt_dev->running) | 1691 | if (pkt_dev->running) |
| 1690 | seq_printf(seq, "%s ", pkt_dev->odev->name); | 1692 | seq_printf(seq, "%s ", pkt_dev->odevname); |
| 1691 | 1693 | ||
| 1692 | seq_printf(seq, "\nStopped: "); | 1694 | seq_printf(seq, "\nStopped: "); |
| 1693 | 1695 | ||
| 1694 | list_for_each_entry(pkt_dev, &t->if_list, list) | 1696 | list_for_each_entry(pkt_dev, &t->if_list, list) |
| 1695 | if (!pkt_dev->running) | 1697 | if (!pkt_dev->running) |
| 1696 | seq_printf(seq, "%s ", pkt_dev->odev->name); | 1698 | seq_printf(seq, "%s ", pkt_dev->odevname); |
| 1697 | 1699 | ||
| 1698 | if (t->result[0]) | 1700 | if (t->result[0]) |
| 1699 | seq_printf(seq, "\nResult: %s\n", t->result); | 1701 | seq_printf(seq, "\nResult: %s\n", t->result); |
| @@ -1816,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) | |||
| 1816 | { | 1818 | { |
| 1817 | struct pktgen_thread *t; | 1819 | struct pktgen_thread *t; |
| 1818 | struct pktgen_dev *pkt_dev = NULL; | 1820 | struct pktgen_dev *pkt_dev = NULL; |
| 1821 | bool exact = (remove == FIND); | ||
| 1819 | 1822 | ||
| 1820 | list_for_each_entry(t, &pktgen_threads, th_list) { | 1823 | list_for_each_entry(t, &pktgen_threads, th_list) { |
| 1821 | pkt_dev = pktgen_find_dev(t, ifname); | 1824 | pkt_dev = pktgen_find_dev(t, ifname, exact); |
| 1822 | if (pkt_dev) { | 1825 | if (pkt_dev) { |
| 1823 | if (remove) { | 1826 | if (remove) { |
| 1824 | if_lock(t); | 1827 | if_lock(t); |
| @@ -1993,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
| 1993 | "queue_map_min (zero-based) (%d) exceeds valid range " | 1996 | "queue_map_min (zero-based) (%d) exceeds valid range " |
| 1994 | "[0 - %d] for (%d) queues on %s, resetting\n", | 1997 | "[0 - %d] for (%d) queues on %s, resetting\n", |
| 1995 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, | 1998 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, |
| 1996 | pkt_dev->odev->name); | 1999 | pkt_dev->odevname); |
| 1997 | pkt_dev->queue_map_min = ntxq - 1; | 2000 | pkt_dev->queue_map_min = ntxq - 1; |
| 1998 | } | 2001 | } |
| 1999 | if (pkt_dev->queue_map_max >= ntxq) { | 2002 | if (pkt_dev->queue_map_max >= ntxq) { |
| @@ -2001,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
| 2001 | "queue_map_max (zero-based) (%d) exceeds valid range " | 2004 | "queue_map_max (zero-based) (%d) exceeds valid range " |
| 2002 | "[0 - %d] for (%d) queues on %s, resetting\n", | 2005 | "[0 - %d] for (%d) queues on %s, resetting\n", |
| 2003 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, | 2006 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, |
| 2004 | pkt_dev->odev->name); | 2007 | pkt_dev->odevname); |
| 2005 | pkt_dev->queue_map_max = ntxq - 1; | 2008 | pkt_dev->queue_map_max = ntxq - 1; |
| 2006 | } | 2009 | } |
| 2007 | 2010 | ||
| @@ -2630,6 +2633,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
| 2630 | iph->protocol = IPPROTO_UDP; /* UDP */ | 2633 | iph->protocol = IPPROTO_UDP; /* UDP */ |
| 2631 | iph->saddr = pkt_dev->cur_saddr; | 2634 | iph->saddr = pkt_dev->cur_saddr; |
| 2632 | iph->daddr = pkt_dev->cur_daddr; | 2635 | iph->daddr = pkt_dev->cur_daddr; |
| 2636 | iph->id = htons(pkt_dev->ip_id); | ||
| 2637 | pkt_dev->ip_id++; | ||
| 2633 | iph->frag_off = 0; | 2638 | iph->frag_off = 0; |
| 2634 | iplen = 20 + 8 + datalen; | 2639 | iplen = 20 + 8 + datalen; |
| 2635 | iph->tot_len = htons(iplen); | 2640 | iph->tot_len = htons(iplen); |
| @@ -2641,24 +2646,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
| 2641 | skb->dev = odev; | 2646 | skb->dev = odev; |
| 2642 | skb->pkt_type = PACKET_HOST; | 2647 | skb->pkt_type = PACKET_HOST; |
| 2643 | 2648 | ||
| 2644 | if (pkt_dev->nfrags <= 0) | 2649 | if (pkt_dev->nfrags <= 0) { |
| 2645 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); | 2650 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); |
| 2646 | else { | 2651 | memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr)); |
| 2652 | } else { | ||
| 2647 | int frags = pkt_dev->nfrags; | 2653 | int frags = pkt_dev->nfrags; |
| 2648 | int i; | 2654 | int i, len; |
| 2649 | 2655 | ||
| 2650 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); | 2656 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); |
| 2651 | 2657 | ||
| 2652 | if (frags > MAX_SKB_FRAGS) | 2658 | if (frags > MAX_SKB_FRAGS) |
| 2653 | frags = MAX_SKB_FRAGS; | 2659 | frags = MAX_SKB_FRAGS; |
| 2654 | if (datalen > frags * PAGE_SIZE) { | 2660 | if (datalen > frags * PAGE_SIZE) { |
| 2655 | skb_put(skb, datalen - frags * PAGE_SIZE); | 2661 | len = datalen - frags * PAGE_SIZE; |
| 2662 | memset(skb_put(skb, len), 0, len); | ||
| 2656 | datalen = frags * PAGE_SIZE; | 2663 | datalen = frags * PAGE_SIZE; |
| 2657 | } | 2664 | } |
| 2658 | 2665 | ||
| 2659 | i = 0; | 2666 | i = 0; |
| 2660 | while (datalen > 0) { | 2667 | while (datalen > 0) { |
| 2661 | struct page *page = alloc_pages(GFP_KERNEL, 0); | 2668 | struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); |
| 2662 | skb_shinfo(skb)->frags[i].page = page; | 2669 | skb_shinfo(skb)->frags[i].page = page; |
| 2663 | skb_shinfo(skb)->frags[i].page_offset = 0; | 2670 | skb_shinfo(skb)->frags[i].page_offset = 0; |
| 2664 | skb_shinfo(skb)->frags[i].size = | 2671 | skb_shinfo(skb)->frags[i].size = |
| @@ -3257,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) | |||
| 3257 | 3264 | ||
| 3258 | if (!pkt_dev->running) { | 3265 | if (!pkt_dev->running) { |
| 3259 | printk(KERN_WARNING "pktgen: interface: %s is already " | 3266 | printk(KERN_WARNING "pktgen: interface: %s is already " |
| 3260 | "stopped\n", pkt_dev->odev->name); | 3267 | "stopped\n", pkt_dev->odevname); |
| 3261 | return -EINVAL; | 3268 | return -EINVAL; |
| 3262 | } | 3269 | } |
| 3263 | 3270 | ||
| @@ -3459,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
| 3459 | default: /* Drivers are not supposed to return other values! */ | 3466 | default: /* Drivers are not supposed to return other values! */ |
| 3460 | if (net_ratelimit()) | 3467 | if (net_ratelimit()) |
| 3461 | pr_info("pktgen: %s xmit error: %d\n", | 3468 | pr_info("pktgen: %s xmit error: %d\n", |
| 3462 | odev->name, ret); | 3469 | pkt_dev->odevname, ret); |
| 3463 | pkt_dev->errors++; | 3470 | pkt_dev->errors++; |
| 3464 | /* fallthru */ | 3471 | /* fallthru */ |
| 3465 | case NETDEV_TX_LOCKED: | 3472 | case NETDEV_TX_LOCKED: |
| @@ -3561,13 +3568,18 @@ static int pktgen_thread_worker(void *arg) | |||
| 3561 | } | 3568 | } |
| 3562 | 3569 | ||
| 3563 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 3570 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
| 3564 | const char *ifname) | 3571 | const char *ifname, bool exact) |
| 3565 | { | 3572 | { |
| 3566 | struct pktgen_dev *p, *pkt_dev = NULL; | 3573 | struct pktgen_dev *p, *pkt_dev = NULL; |
| 3567 | if_lock(t); | 3574 | size_t len = strlen(ifname); |
| 3568 | 3575 | ||
| 3576 | if_lock(t); | ||
| 3569 | list_for_each_entry(p, &t->if_list, list) | 3577 | list_for_each_entry(p, &t->if_list, list) |
| 3570 | if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) { | 3578 | if (strncmp(p->odevname, ifname, len) == 0) { |
| 3579 | if (p->odevname[len]) { | ||
| 3580 | if (exact || p->odevname[len] != '@') | ||
| 3581 | continue; | ||
| 3582 | } | ||
| 3571 | pkt_dev = p; | 3583 | pkt_dev = p; |
| 3572 | break; | 3584 | break; |
| 3573 | } | 3585 | } |
| @@ -3623,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
| 3623 | if (!pkt_dev) | 3635 | if (!pkt_dev) |
| 3624 | return -ENOMEM; | 3636 | return -ENOMEM; |
| 3625 | 3637 | ||
| 3638 | strcpy(pkt_dev->odevname, ifname); | ||
| 3626 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); | 3639 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); |
| 3627 | if (pkt_dev->flows == NULL) { | 3640 | if (pkt_dev->flows == NULL) { |
| 3628 | kfree(pkt_dev); | 3641 | kfree(pkt_dev); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 80a96166df39..ec85681a7dd8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
| 2701 | 2701 | ||
| 2702 | NAPI_GRO_CB(skb)->free = 1; | 2702 | NAPI_GRO_CB(skb)->free = 1; |
| 2703 | goto done; | 2703 | goto done; |
| 2704 | } | 2704 | } else if (skb_gro_len(p) != pinfo->gso_size) |
| 2705 | return -E2BIG; | ||
| 2705 | 2706 | ||
| 2706 | headroom = skb_headroom(p); | 2707 | headroom = skb_headroom(p); |
| 2707 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | 2708 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); |
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 26b0ab1e9f56..2036568beea9 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 e2f950592566..aa00398be80e 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/ip_fragment.c b/net/ipv4/ip_fragment.c index 575f9bd51ccd..d3fe10be7219 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -563,7 +563,7 @@ out_oversize: | |||
| 563 | printk(KERN_INFO "Oversized IP packet from %pI4.\n", | 563 | printk(KERN_INFO "Oversized IP packet from %pI4.\n", |
| 564 | &qp->saddr); | 564 | &qp->saddr); |
| 565 | out_fail: | 565 | out_fail: |
| 566 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS); | 566 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
| 567 | return err; | 567 | return err; |
| 568 | } | 568 | } |
| 569 | 569 | ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 41ada9904d31..143333852624 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/ipip.c b/net/ipv4/ipip.c index 08ccd344de7a..ae40ed1ba560 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/ipmr.c b/net/ipv4/ipmr.c index 630a56df7b47..99508d66a642 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
| 483 | return -EINVAL; | 483 | return -EINVAL; |
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 486 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) { |
| 487 | dev_put(dev); | ||
| 487 | return -EADDRNOTAVAIL; | 488 | return -EADDRNOTAVAIL; |
| 489 | } | ||
| 488 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; | 490 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
| 489 | ip_rt_multicast_event(in_dev); | 491 | ip_rt_multicast_event(in_dev); |
| 490 | 492 | ||
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 68afc6ecd343..fe1a64479dd0 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 09172a65d9b6..f9520fa3aba9 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 757c9171e7c2..ab996f9c0fe0 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 bb4199252026..5b1050a5d874 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 90b2e0649bfb..f1813bc71088 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1183,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) | |||
| 1183 | #if TCP_DEBUG | 1183 | #if TCP_DEBUG |
| 1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); | 1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); |
| 1185 | 1185 | ||
| 1186 | WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); | 1186 | WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq), |
| 1187 | KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", | ||
| 1188 | tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt); | ||
| 1187 | #endif | 1189 | #endif |
| 1188 | 1190 | ||
| 1189 | if (inet_csk_ack_scheduled(sk)) { | 1191 | if (inet_csk_ack_scheduled(sk)) { |
| @@ -1430,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1430 | /* Now that we have two receive queues this | 1432 | /* Now that we have two receive queues this |
| 1431 | * shouldn't happen. | 1433 | * shouldn't happen. |
| 1432 | */ | 1434 | */ |
| 1433 | if (before(*seq, TCP_SKB_CB(skb)->seq)) { | 1435 | if (WARN(before(*seq, TCP_SKB_CB(skb)->seq), |
| 1434 | printk(KERN_INFO "recvmsg bug: copied %X " | 1436 | KERN_INFO "recvmsg bug: copied %X " |
| 1435 | "seq %X\n", *seq, TCP_SKB_CB(skb)->seq); | 1437 | "seq %X rcvnxt %X fl %X\n", *seq, |
| 1438 | TCP_SKB_CB(skb)->seq, tp->rcv_nxt, | ||
| 1439 | flags)) | ||
| 1436 | break; | 1440 | break; |
| 1437 | } | 1441 | |
| 1438 | offset = *seq - TCP_SKB_CB(skb)->seq; | 1442 | offset = *seq - TCP_SKB_CB(skb)->seq; |
| 1439 | if (tcp_hdr(skb)->syn) | 1443 | if (tcp_hdr(skb)->syn) |
| 1440 | offset--; | 1444 | offset--; |
| @@ -1442,9 +1446,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1442 | goto found_ok_skb; | 1446 | goto found_ok_skb; |
| 1443 | if (tcp_hdr(skb)->fin) | 1447 | if (tcp_hdr(skb)->fin) |
| 1444 | goto found_fin_ok; | 1448 | goto found_fin_ok; |
| 1445 | if (WARN_ON(!(flags & MSG_PEEK))) | 1449 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " |
| 1446 | printk(KERN_INFO "recvmsg bug 2: copied %X " | 1450 | "copied %X seq %X rcvnxt %X fl %X\n", |
| 1447 | "seq %X\n", *seq, TCP_SKB_CB(skb)->seq); | 1451 | *seq, TCP_SKB_CB(skb)->seq, |
| 1452 | tp->rcv_nxt, flags); | ||
| 1448 | } | 1453 | } |
| 1449 | 1454 | ||
| 1450 | /* Well, if we have backlog, try to process it now yet. */ | 1455 | /* Well, if we have backlog, try to process it now yet. */ |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d0d436d6216c..0fa9f70e4b19 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -999,9 +999,7 @@ try_again: | |||
| 999 | err = ulen; | 999 | err = ulen; |
| 1000 | 1000 | ||
| 1001 | out_free: | 1001 | out_free: |
| 1002 | lock_sock(sk); | 1002 | skb_free_datagram_locked(sk, skb); |
| 1003 | skb_free_datagram(sk, skb); | ||
| 1004 | release_sock(sk); | ||
| 1005 | out: | 1003 | out: |
| 1006 | return err; | 1004 | return err; |
| 1007 | 1005 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3a60f12b34ed..cf538ed5ef6a 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-rx.c b/net/mac80211/agg-rx.c index bc064d7933ff..ce8e0e772bab 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
| @@ -85,10 +85,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
| 85 | struct ieee80211_local *local = sdata->local; | 85 | struct ieee80211_local *local = sdata->local; |
| 86 | struct sta_info *sta; | 86 | struct sta_info *sta; |
| 87 | 87 | ||
| 88 | /* stop HW Rx aggregation. ampdu_action existence | ||
| 89 | * already verified in session init so we add the BUG_ON */ | ||
| 90 | BUG_ON(!local->ops->ampdu_action); | ||
| 91 | |||
| 92 | rcu_read_lock(); | 88 | rcu_read_lock(); |
| 93 | 89 | ||
| 94 | sta = sta_info_get(local, ra); | 90 | sta = sta_info_get(local, ra); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index bd765f30dba2..89e238b001de 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
| @@ -123,13 +123,18 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 | |||
| 123 | ieee80211_tx_skb(sdata, skb, 0); | 123 | ieee80211_tx_skb(sdata, skb, 0); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 126 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
| 127 | enum ieee80211_back_parties initiator) | 127 | enum ieee80211_back_parties initiator) |
| 128 | { | 128 | { |
| 129 | struct ieee80211_local *local = sta->local; | 129 | struct ieee80211_local *local = sta->local; |
| 130 | int ret; | 130 | int ret; |
| 131 | u8 *state; | 131 | u8 *state; |
| 132 | 132 | ||
| 133 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 134 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
| 135 | sta->sta.addr, tid); | ||
| 136 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
| 137 | |||
| 133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 138 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 134 | 139 | ||
| 135 | if (*state == HT_AGG_STATE_OPERATIONAL) | 140 | if (*state == HT_AGG_STATE_OPERATIONAL) |
| @@ -143,7 +148,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
| 143 | 148 | ||
| 144 | /* HW shall not deny going back to legacy */ | 149 | /* HW shall not deny going back to legacy */ |
| 145 | if (WARN_ON(ret)) { | 150 | if (WARN_ON(ret)) { |
| 146 | *state = HT_AGG_STATE_OPERATIONAL; | ||
| 147 | /* | 151 | /* |
| 148 | * We may have pending packets get stuck in this case... | 152 | * We may have pending packets get stuck in this case... |
| 149 | * Not bothering with a workaround for now. | 153 | * Not bothering with a workaround for now. |
| @@ -173,12 +177,14 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
| 173 | 177 | ||
| 174 | /* check if the TID waits for addBA response */ | 178 | /* check if the TID waits for addBA response */ |
| 175 | spin_lock_bh(&sta->lock); | 179 | spin_lock_bh(&sta->lock); |
| 176 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 180 | if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != |
| 181 | HT_ADDBA_REQUESTED_MSK) { | ||
| 177 | spin_unlock_bh(&sta->lock); | 182 | spin_unlock_bh(&sta->lock); |
| 178 | *state = HT_AGG_STATE_IDLE; | 183 | *state = HT_AGG_STATE_IDLE; |
| 179 | #ifdef CONFIG_MAC80211_HT_DEBUG | 184 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 180 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 185 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
| 181 | "expecting addBA response there", tid); | 186 | "(or no longer) expecting addBA response there", |
| 187 | tid); | ||
| 182 | #endif | 188 | #endif |
| 183 | return; | 189 | return; |
| 184 | } | 190 | } |
| @@ -523,11 +529,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
| 523 | goto unlock; | 529 | goto unlock; |
| 524 | } | 530 | } |
| 525 | 531 | ||
| 526 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 527 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
| 528 | sta->sta.addr, tid); | ||
| 529 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
| 530 | |||
| 531 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); | 532 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); |
| 532 | 533 | ||
| 533 | unlock: | 534 | unlock: |
| @@ -543,7 +544,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
| 543 | struct sta_info *sta; | 544 | struct sta_info *sta; |
| 544 | int ret = 0; | 545 | int ret = 0; |
| 545 | 546 | ||
| 546 | if (WARN_ON(!local->ops->ampdu_action)) | 547 | if (!local->ops->ampdu_action) |
| 547 | return -EINVAL; | 548 | return -EINVAL; |
| 548 | 549 | ||
| 549 | if (tid >= STA_TID_NUM) | 550 | if (tid >= STA_TID_NUM) |
| @@ -668,24 +669,23 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 668 | 669 | ||
| 669 | spin_lock_bh(&sta->lock); | 670 | spin_lock_bh(&sta->lock); |
| 670 | 671 | ||
| 671 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 672 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) |
| 672 | spin_unlock_bh(&sta->lock); | 673 | goto out; |
| 673 | return; | ||
| 674 | } | ||
| 675 | 674 | ||
| 676 | if (mgmt->u.action.u.addba_resp.dialog_token != | 675 | if (mgmt->u.action.u.addba_resp.dialog_token != |
| 677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 676 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
| 678 | spin_unlock_bh(&sta->lock); | ||
| 679 | #ifdef CONFIG_MAC80211_HT_DEBUG | 677 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 680 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 678 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
| 681 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 679 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 682 | return; | 680 | goto out; |
| 683 | } | 681 | } |
| 684 | 682 | ||
| 685 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 683 | del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
| 684 | |||
| 686 | #ifdef CONFIG_MAC80211_HT_DEBUG | 685 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 687 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); | 686 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); |
| 688 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 687 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 688 | |||
| 689 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | 689 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) |
| 690 | == WLAN_STATUS_SUCCESS) { | 690 | == WLAN_STATUS_SUCCESS) { |
| 691 | u8 curstate = *state; | 691 | u8 curstate = *state; |
| @@ -699,5 +699,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 699 | } else { | 699 | } else { |
| 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
| 701 | } | 701 | } |
| 702 | |||
| 703 | out: | ||
| 702 | spin_unlock_bh(&sta->lock); | 704 | spin_unlock_bh(&sta->lock); |
| 703 | } | 705 | } |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5608f6c68413..7b5131bd6fa1 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 0891bfb06996..cdc58e61d921 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
| 141 | struct sta_info *sta, | 141 | struct sta_info *sta, |
| 142 | struct ieee80211_mgmt *mgmt, size_t len) | 142 | struct ieee80211_mgmt *mgmt, size_t len) |
| 143 | { | 143 | { |
| 144 | struct ieee80211_local *local = sdata->local; | ||
| 145 | u16 tid, params; | 144 | u16 tid, params; |
| 146 | u16 initiator; | 145 | u16 initiator; |
| 147 | 146 | ||
| @@ -153,7 +152,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
| 153 | if (net_ratelimit()) | 152 | if (net_ratelimit()) |
| 154 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", | 153 | printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n", |
| 155 | mgmt->sa, initiator ? "initiator" : "recipient", tid, | 154 | mgmt->sa, initiator ? "initiator" : "recipient", tid, |
| 156 | mgmt->u.action.u.delba.reason_code); | 155 | le16_to_cpu(mgmt->u.action.u.delba.reason_code)); |
| 157 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 156 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 158 | 157 | ||
| 159 | if (initiator == WLAN_BACK_INITIATOR) | 158 | if (initiator == WLAN_BACK_INITIATOR) |
| @@ -161,10 +160,9 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
| 161 | WLAN_BACK_INITIATOR, 0); | 160 | WLAN_BACK_INITIATOR, 0); |
| 162 | else { /* WLAN_BACK_RECIPIENT */ | 161 | else { /* WLAN_BACK_RECIPIENT */ |
| 163 | spin_lock_bh(&sta->lock); | 162 | spin_lock_bh(&sta->lock); |
| 164 | sta->ampdu_mlme.tid_state_tx[tid] = | 163 | if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK) |
| 165 | HT_AGG_STATE_OPERATIONAL; | 164 | ___ieee80211_stop_tx_ba_session(sta, tid, |
| 165 | WLAN_BACK_RECIPIENT); | ||
| 166 | spin_unlock_bh(&sta->lock); | 166 | spin_unlock_bh(&sta->lock); |
| 167 | ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid, | ||
| 168 | WLAN_BACK_RECIPIENT); | ||
| 169 | } | 167 | } |
| 170 | } | 168 | } |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 6eaf69823439..f1362f32c17d 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"); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 588005c84a6d..10d316e455de 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -662,6 +662,14 @@ struct ieee80211_local { | |||
| 662 | bool suspended; | 662 | bool suspended; |
| 663 | 663 | ||
| 664 | /* | 664 | /* |
| 665 | * Resuming is true while suspended, but when we're reprogramming the | ||
| 666 | * hardware -- at that time it's allowed to use ieee80211_queue_work() | ||
| 667 | * again even though some other parts of the stack are still suspended | ||
| 668 | * and we still drop received frames to avoid waking the stack. | ||
| 669 | */ | ||
| 670 | bool resuming; | ||
| 671 | |||
| 672 | /* | ||
| 665 | * quiescing is true during the suspend process _only_ to | 673 | * quiescing is true during the suspend process _only_ to |
| 666 | * ease timer cancelling etc. | 674 | * ease timer cancelling etc. |
| 667 | */ | 675 | */ |
| @@ -1083,6 +1091,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
| 1083 | 1091 | ||
| 1084 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1092 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
| 1085 | enum ieee80211_back_parties initiator); | 1093 | enum ieee80211_back_parties initiator); |
| 1094 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | ||
| 1095 | enum ieee80211_back_parties initiator); | ||
| 1086 | 1096 | ||
| 1087 | /* Spectrum management */ | 1097 | /* Spectrum management */ |
| 1088 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 1098 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index e12a786e26b8..29b82e98effa 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 8d26e9bf8964..dc5049d58c51 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/tx.c b/net/mac80211/tx.c index db4bda681ec9..eaa4118de988 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; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aeb65b3d2295..e6c08da8da26 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | |||
| 520 | */ | 520 | */ |
| 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) |
| 522 | { | 522 | { |
| 523 | if (WARN(local->suspended, "queueing ieee80211 work while " | 523 | if (WARN(local->suspended && !local->resuming, |
| 524 | "going to suspend\n")) | 524 | "queueing ieee80211 work while going to suspend\n")) |
| 525 | return false; | 525 | return false; |
| 526 | 526 | ||
| 527 | return true; | 527 | return true; |
| 528 | } | 528 | } |
| @@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1025 | struct sta_info *sta; | 1025 | struct sta_info *sta; |
| 1026 | unsigned long flags; | 1026 | unsigned long flags; |
| 1027 | int res; | 1027 | int res; |
| 1028 | bool from_suspend = local->suspended; | ||
| 1029 | 1028 | ||
| 1030 | /* | 1029 | if (local->suspended) |
| 1031 | * We're going to start the hardware, at that point | 1030 | local->resuming = true; |
| 1032 | * we are no longer suspended and can RX frames. | ||
| 1033 | */ | ||
| 1034 | local->suspended = false; | ||
| 1035 | 1031 | ||
| 1036 | /* restart hardware */ | 1032 | /* restart hardware */ |
| 1037 | if (local->open_count) { | 1033 | if (local->open_count) { |
| @@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1129 | * If this is for hw restart things are still running. | 1125 | * If this is for hw restart things are still running. |
| 1130 | * We may want to change that later, however. | 1126 | * We may want to change that later, however. |
| 1131 | */ | 1127 | */ |
| 1132 | if (!from_suspend) | 1128 | if (!local->suspended) |
| 1133 | return 0; | 1129 | return 0; |
| 1134 | 1130 | ||
| 1135 | #ifdef CONFIG_PM | 1131 | #ifdef CONFIG_PM |
| 1132 | /* first set suspended false, then resuming */ | ||
| 1136 | local->suspended = false; | 1133 | local->suspended = false; |
| 1134 | mb(); | ||
| 1135 | local->resuming = false; | ||
| 1137 | 1136 | ||
| 1138 | list_for_each_entry(sdata, &local->interfaces, list) { | 1137 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 1139 | switch(sdata->vif.type) { | 1138 | switch(sdata->vif.type) { |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ca6e68dcd8a8..b9168c1864ca 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 97a82ba75376..ba2b76937283 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/nf_log.c b/net/netfilter/nf_log.c index c93494fef8ef..d65d3481919c 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
| @@ -128,9 +128,8 @@ EXPORT_SYMBOL(nf_log_packet); | |||
| 128 | 128 | ||
| 129 | #ifdef CONFIG_PROC_FS | 129 | #ifdef CONFIG_PROC_FS |
| 130 | static void *seq_start(struct seq_file *seq, loff_t *pos) | 130 | static void *seq_start(struct seq_file *seq, loff_t *pos) |
| 131 | __acquires(RCU) | ||
| 132 | { | 131 | { |
| 133 | rcu_read_lock(); | 132 | mutex_lock(&nf_log_mutex); |
| 134 | 133 | ||
| 135 | if (*pos >= ARRAY_SIZE(nf_loggers)) | 134 | if (*pos >= ARRAY_SIZE(nf_loggers)) |
| 136 | return NULL; | 135 | return NULL; |
| @@ -149,9 +148,8 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
| 149 | } | 148 | } |
| 150 | 149 | ||
| 151 | static void seq_stop(struct seq_file *s, void *v) | 150 | static void seq_stop(struct seq_file *s, void *v) |
| 152 | __releases(RCU) | ||
| 153 | { | 151 | { |
| 154 | rcu_read_unlock(); | 152 | mutex_unlock(&nf_log_mutex); |
| 155 | } | 153 | } |
| 156 | 154 | ||
| 157 | static int seq_show(struct seq_file *s, void *v) | 155 | static int seq_show(struct seq_file *s, void *v) |
| @@ -161,7 +159,7 @@ static int seq_show(struct seq_file *s, void *v) | |||
| 161 | struct nf_logger *t; | 159 | struct nf_logger *t; |
| 162 | int ret; | 160 | int ret; |
| 163 | 161 | ||
| 164 | logger = rcu_dereference(nf_loggers[*pos]); | 162 | logger = nf_loggers[*pos]; |
| 165 | 163 | ||
| 166 | if (!logger) | 164 | if (!logger) |
| 167 | ret = seq_printf(s, "%2lld NONE (", *pos); | 165 | ret = seq_printf(s, "%2lld NONE (", *pos); |
| @@ -171,22 +169,16 @@ static int seq_show(struct seq_file *s, void *v) | |||
| 171 | if (ret < 0) | 169 | if (ret < 0) |
| 172 | return ret; | 170 | return ret; |
| 173 | 171 | ||
| 174 | mutex_lock(&nf_log_mutex); | ||
| 175 | list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { | 172 | list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { |
| 176 | ret = seq_printf(s, "%s", t->name); | 173 | ret = seq_printf(s, "%s", t->name); |
| 177 | if (ret < 0) { | 174 | if (ret < 0) |
| 178 | mutex_unlock(&nf_log_mutex); | ||
| 179 | return ret; | 175 | return ret; |
| 180 | } | ||
| 181 | if (&t->list[*pos] != nf_loggers_l[*pos].prev) { | 176 | if (&t->list[*pos] != nf_loggers_l[*pos].prev) { |
| 182 | ret = seq_printf(s, ","); | 177 | ret = seq_printf(s, ","); |
| 183 | if (ret < 0) { | 178 | if (ret < 0) |
| 184 | mutex_unlock(&nf_log_mutex); | ||
| 185 | return ret; | 179 | return ret; |
| 186 | } | ||
| 187 | } | 180 | } |
| 188 | } | 181 | } |
| 189 | mutex_unlock(&nf_log_mutex); | ||
| 190 | 182 | ||
| 191 | return seq_printf(s, ")\n"); | 183 | return seq_printf(s, ")\n"); |
| 192 | } | 184 | } |
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 680980954395..38f03f75a636 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/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 2e8089ecd0af..2773be6a71dd 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c | |||
| @@ -112,7 +112,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par) | |||
| 112 | 112 | ||
| 113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
| 114 | if (priv == NULL) | 114 | if (priv == NULL) |
| 115 | return -ENOMEM; | 115 | return false; |
| 116 | 116 | ||
| 117 | /* For SMP, we only want to use one set of state. */ | 117 | /* For SMP, we only want to use one set of state. */ |
| 118 | r->master = priv; | 118 | r->master = priv; |
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 63e190504656..4d1a41bbd5d7 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c | |||
| @@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb, | |||
| 118 | { | 118 | { |
| 119 | struct xt_osf_user_finger *f; | 119 | struct xt_osf_user_finger *f; |
| 120 | struct xt_osf_finger *sf; | 120 | struct xt_osf_finger *sf; |
| 121 | int err = ENOENT; | 121 | int err = -ENOENT; |
| 122 | 122 | ||
| 123 | if (!osf_attrs[OSF_ATTR_FINGER]) | 123 | if (!osf_attrs[OSF_ATTR_FINGER]) |
| 124 | return -EINVAL; | 124 | return -EINVAL; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d7ecca0a0c07..f2d116a5cb35 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/rfkill/core.c b/net/rfkill/core.c index ba2efb960c60..a001f7c1f711 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
| @@ -1189,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, | |||
| 1189 | #endif | 1189 | #endif |
| 1190 | 1190 | ||
| 1191 | static const struct file_operations rfkill_fops = { | 1191 | static const struct file_operations rfkill_fops = { |
| 1192 | .owner = THIS_MODULE, | ||
| 1192 | .open = rfkill_fop_open, | 1193 | .open = rfkill_fop_open, |
| 1193 | .read = rfkill_fop_read, | 1194 | .read = rfkill_fop_read, |
| 1194 | .write = rfkill_fop_write, | 1195 | .write = rfkill_fop_write, |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 9478d9b3d977..f3e21989b88c 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/sctp/associola.c b/net/sctp/associola.c index 8450960df24f..7eed77a39d0d 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -1485,15 +1485,13 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) | |||
| 1485 | * local endpoint and the remote peer. | 1485 | * local endpoint and the remote peer. |
| 1486 | */ | 1486 | */ |
| 1487 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, | 1487 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, |
| 1488 | gfp_t gfp) | 1488 | sctp_scope_t scope, gfp_t gfp) |
| 1489 | { | 1489 | { |
| 1490 | sctp_scope_t scope; | ||
| 1491 | int flags; | 1490 | int flags; |
| 1492 | 1491 | ||
| 1493 | /* Use scoping rules to determine the subset of addresses from | 1492 | /* Use scoping rules to determine the subset of addresses from |
| 1494 | * the endpoint. | 1493 | * the endpoint. |
| 1495 | */ | 1494 | */ |
| 1496 | scope = sctp_scope(&asoc->peer.active_path->ipaddr); | ||
| 1497 | flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; | 1495 | flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; |
| 1498 | if (asoc->peer.ipv4_address) | 1496 | if (asoc->peer.ipv4_address) |
| 1499 | flags |= SCTP_ADDR4_PEERSUPP; | 1497 | flags |= SCTP_ADDR4_PEERSUPP; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index c9f20e28521b..23e5e97aa617 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -423,16 +423,6 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
| 423 | if ((reason == SCTP_RTXR_FAST_RTX && | 423 | if ((reason == SCTP_RTXR_FAST_RTX && |
| 424 | (chunk->fast_retransmit == SCTP_NEED_FRTX)) || | 424 | (chunk->fast_retransmit == SCTP_NEED_FRTX)) || |
| 425 | (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { | 425 | (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { |
| 426 | /* If this chunk was sent less then 1 rto ago, do not | ||
| 427 | * retransmit this chunk, but give the peer time | ||
| 428 | * to acknowlege it. Do this only when | ||
| 429 | * retransmitting due to T3 timeout. | ||
| 430 | */ | ||
| 431 | if (reason == SCTP_RTXR_T3_RTX && | ||
| 432 | time_before(jiffies, chunk->sent_at + | ||
| 433 | transport->last_rto)) | ||
| 434 | continue; | ||
| 435 | |||
| 436 | /* RFC 2960 6.2.1 Processing a Received SACK | 426 | /* RFC 2960 6.2.1 Processing a Received SACK |
| 437 | * | 427 | * |
| 438 | * C) Any time a DATA chunk is marked for | 428 | * C) Any time a DATA chunk is marked for |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 8674d4919556..efa516b47e81 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -480,7 +480,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
| 480 | * that indicates that we have an outstanding HB. | 480 | * that indicates that we have an outstanding HB. |
| 481 | */ | 481 | */ |
| 482 | if (!is_hb || transport->hb_sent) { | 482 | if (!is_hb || transport->hb_sent) { |
| 483 | transport->last_rto = transport->rto; | ||
| 484 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); | 483 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); |
| 485 | } | 484 | } |
| 486 | } | 485 | } |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c8fae1983dd1..d4df45022ffa 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
| 384 | if (!new_asoc) | 384 | if (!new_asoc) |
| 385 | goto nomem; | 385 | goto nomem; |
| 386 | 386 | ||
| 387 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, | ||
| 388 | sctp_scope(sctp_source(chunk)), | ||
| 389 | GFP_ATOMIC) < 0) | ||
| 390 | goto nomem_init; | ||
| 391 | |||
| 387 | /* The call, sctp_process_init(), can fail on memory allocation. */ | 392 | /* The call, sctp_process_init(), can fail on memory allocation. */ |
| 388 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 393 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, |
| 389 | sctp_source(chunk), | 394 | sctp_source(chunk), |
| @@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
| 401 | len = ntohs(err_chunk->chunk_hdr->length) - | 406 | len = ntohs(err_chunk->chunk_hdr->length) - |
| 402 | sizeof(sctp_chunkhdr_t); | 407 | sizeof(sctp_chunkhdr_t); |
| 403 | 408 | ||
| 404 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | ||
| 405 | goto nomem_init; | ||
| 406 | |||
| 407 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 409 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
| 408 | if (!repl) | 410 | if (!repl) |
| 409 | goto nomem_init; | 411 | goto nomem_init; |
| @@ -1452,6 +1454,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
| 1452 | if (!new_asoc) | 1454 | if (!new_asoc) |
| 1453 | goto nomem; | 1455 | goto nomem; |
| 1454 | 1456 | ||
| 1457 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, | ||
| 1458 | sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0) | ||
| 1459 | goto nomem; | ||
| 1460 | |||
| 1455 | /* In the outbound INIT ACK the endpoint MUST copy its current | 1461 | /* In the outbound INIT ACK the endpoint MUST copy its current |
| 1456 | * Verification Tag and Peers Verification tag into a reserved | 1462 | * Verification Tag and Peers Verification tag into a reserved |
| 1457 | * place (local tie-tag and per tie-tag) within the state cookie. | 1463 | * place (local tie-tag and per tie-tag) within the state cookie. |
| @@ -1488,9 +1494,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
| 1488 | sizeof(sctp_chunkhdr_t); | 1494 | sizeof(sctp_chunkhdr_t); |
| 1489 | } | 1495 | } |
| 1490 | 1496 | ||
| 1491 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | ||
| 1492 | goto nomem; | ||
| 1493 | |||
| 1494 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 1497 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
| 1495 | if (!repl) | 1498 | if (!repl) |
| 1496 | goto nomem; | 1499 | goto nomem; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c8d05758661d..3a95fcb17a9e 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -1080,6 +1080,13 @@ static int __sctp_connect(struct sock* sk, | |||
| 1080 | err = -ENOMEM; | 1080 | err = -ENOMEM; |
| 1081 | goto out_free; | 1081 | goto out_free; |
| 1082 | } | 1082 | } |
| 1083 | |||
| 1084 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, | ||
| 1085 | GFP_KERNEL); | ||
| 1086 | if (err < 0) { | ||
| 1087 | goto out_free; | ||
| 1088 | } | ||
| 1089 | |||
| 1083 | } | 1090 | } |
| 1084 | 1091 | ||
| 1085 | /* Prime the peer's transport structures. */ | 1092 | /* Prime the peer's transport structures. */ |
| @@ -1095,11 +1102,6 @@ static int __sctp_connect(struct sock* sk, | |||
| 1095 | walk_size += af->sockaddr_len; | 1102 | walk_size += af->sockaddr_len; |
| 1096 | } | 1103 | } |
| 1097 | 1104 | ||
| 1098 | err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); | ||
| 1099 | if (err < 0) { | ||
| 1100 | goto out_free; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | /* In case the user of sctp_connectx() wants an association | 1105 | /* In case the user of sctp_connectx() wants an association |
| 1104 | * id back, assign one now. | 1106 | * id back, assign one now. |
| 1105 | */ | 1107 | */ |
| @@ -1274,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, | |||
| 1274 | } | 1276 | } |
| 1275 | 1277 | ||
| 1276 | /* | 1278 | /* |
| 1277 | * New (hopefully final) interface for the API. The option buffer is used | 1279 | * New (hopefully final) interface for the API. |
| 1278 | * both for the returned association id and the addresses. | 1280 | * We use the sctp_getaddrs_old structure so that use-space library |
| 1281 | * can avoid any unnecessary allocations. The only defferent part | ||
| 1282 | * is that we store the actual length of the address buffer into the | ||
| 1283 | * addrs_num structure member. That way we can re-use the existing | ||
| 1284 | * code. | ||
| 1279 | */ | 1285 | */ |
| 1280 | SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, | 1286 | SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, |
| 1281 | char __user *optval, | 1287 | char __user *optval, |
| 1282 | int __user *optlen) | 1288 | int __user *optlen) |
| 1283 | { | 1289 | { |
| 1290 | struct sctp_getaddrs_old param; | ||
| 1284 | sctp_assoc_t assoc_id = 0; | 1291 | sctp_assoc_t assoc_id = 0; |
| 1285 | int err = 0; | 1292 | int err = 0; |
| 1286 | 1293 | ||
| 1287 | if (len < sizeof(assoc_id)) | 1294 | if (len < sizeof(param)) |
| 1288 | return -EINVAL; | 1295 | return -EINVAL; |
| 1289 | 1296 | ||
| 1297 | if (copy_from_user(¶m, optval, sizeof(param))) | ||
| 1298 | return -EFAULT; | ||
| 1299 | |||
| 1290 | err = __sctp_setsockopt_connectx(sk, | 1300 | err = __sctp_setsockopt_connectx(sk, |
| 1291 | (struct sockaddr __user *)(optval + sizeof(assoc_id)), | 1301 | (struct sockaddr __user *)param.addrs, |
| 1292 | len - sizeof(assoc_id), &assoc_id); | 1302 | param.addr_num, &assoc_id); |
| 1293 | 1303 | ||
| 1294 | if (err == 0 || err == -EINPROGRESS) { | 1304 | if (err == 0 || err == -EINPROGRESS) { |
| 1295 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) | 1305 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) |
| @@ -1689,6 +1699,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1689 | goto out_unlock; | 1699 | goto out_unlock; |
| 1690 | } | 1700 | } |
| 1691 | asoc = new_asoc; | 1701 | asoc = new_asoc; |
| 1702 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL); | ||
| 1703 | if (err < 0) { | ||
| 1704 | err = -ENOMEM; | ||
| 1705 | goto out_free; | ||
| 1706 | } | ||
| 1692 | 1707 | ||
| 1693 | /* If the SCTP_INIT ancillary data is specified, set all | 1708 | /* If the SCTP_INIT ancillary data is specified, set all |
| 1694 | * the association init values accordingly. | 1709 | * the association init values accordingly. |
| @@ -1718,11 +1733,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1718 | err = -ENOMEM; | 1733 | err = -ENOMEM; |
| 1719 | goto out_free; | 1734 | goto out_free; |
| 1720 | } | 1735 | } |
| 1721 | err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); | ||
| 1722 | if (err < 0) { | ||
| 1723 | err = -ENOMEM; | ||
| 1724 | goto out_free; | ||
| 1725 | } | ||
| 1726 | } | 1736 | } |
| 1727 | 1737 | ||
| 1728 | /* ASSERT: we have a valid association at this point. */ | 1738 | /* ASSERT: we have a valid association at this point. */ |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index c256e4839316..37a1184d789f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -74,7 +74,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
| 74 | * given destination transport address, set RTO to the protocol | 74 | * given destination transport address, set RTO to the protocol |
| 75 | * parameter 'RTO.Initial'. | 75 | * parameter 'RTO.Initial'. |
| 76 | */ | 76 | */ |
| 77 | peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial); | 77 | peer->rto = msecs_to_jiffies(sctp_rto_initial); |
| 78 | peer->rtt = 0; | 78 | peer->rtt = 0; |
| 79 | peer->rttvar = 0; | 79 | peer->rttvar = 0; |
| 80 | peer->srtt = 0; | 80 | peer->srtt = 0; |
| @@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
| 308 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 308 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
| 309 | * association's active path for getsockname(). | 309 | * association's active path for getsockname(). |
| 310 | */ | 310 | */ |
| 311 | if (asoc && (transport == asoc->peer.active_path)) | 311 | if (asoc && (!asoc->peer.primary_path || |
| 312 | (transport == asoc->peer.active_path))) | ||
| 312 | opt->pf->af->to_sk_saddr(&transport->saddr, | 313 | opt->pf->af->to_sk_saddr(&transport->saddr, |
| 313 | asoc->base.sk); | 314 | asoc->base.sk); |
| 314 | } else | 315 | } else |
| @@ -385,7 +386,6 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
| 385 | tp->rto = tp->asoc->rto_max; | 386 | tp->rto = tp->asoc->rto_max; |
| 386 | 387 | ||
| 387 | tp->rtt = rtt; | 388 | tp->rtt = rtt; |
| 388 | tp->last_rto = tp->rto; | ||
| 389 | 389 | ||
| 390 | /* Reset rto_pending so that a new RTT measurement is started when a | 390 | /* Reset rto_pending so that a new RTT measurement is started when a |
| 391 | * new data chunk is sent. | 391 | * new data chunk is sent. |
| @@ -601,7 +601,7 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
| 601 | */ | 601 | */ |
| 602 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); | 602 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
| 603 | t->ssthresh = asoc->peer.i.a_rwnd; | 603 | t->ssthresh = asoc->peer.i.a_rwnd; |
| 604 | t->last_rto = t->rto = asoc->rto_initial; | 604 | t->rto = asoc->rto_initial; |
| 605 | t->rtt = 0; | 605 | t->rtt = 0; |
| 606 | t->srtt = 0; | 606 | t->srtt = 0; |
| 607 | t->rttvar = 0; | 607 | t->rttvar = 0; |
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 22e8fd89477f..c7450c8f0a7c 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c | |||
| @@ -306,24 +306,25 @@ EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr); | |||
| 306 | * @sap: buffer into which to plant socket address | 306 | * @sap: buffer into which to plant socket address |
| 307 | * @salen: size of buffer | 307 | * @salen: size of buffer |
| 308 | * | 308 | * |
| 309 | * @uaddr does not have to be '\0'-terminated, but strict_strtoul() and | ||
| 310 | * rpc_pton() require proper string termination to be successful. | ||
| 311 | * | ||
| 309 | * Returns the size of the socket address if successful; otherwise | 312 | * Returns the size of the socket address if successful; otherwise |
| 310 | * zero is returned. | 313 | * zero is returned. |
| 311 | */ | 314 | */ |
| 312 | size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | 315 | size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, |
| 313 | struct sockaddr *sap, const size_t salen) | 316 | struct sockaddr *sap, const size_t salen) |
| 314 | { | 317 | { |
| 315 | char *c, buf[RPCBIND_MAXUADDRLEN]; | 318 | char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')]; |
| 316 | unsigned long portlo, porthi; | 319 | unsigned long portlo, porthi; |
| 317 | unsigned short port; | 320 | unsigned short port; |
| 318 | 321 | ||
| 319 | if (uaddr_len > sizeof(buf)) | 322 | if (uaddr_len > RPCBIND_MAXUADDRLEN) |
| 320 | return 0; | 323 | return 0; |
| 321 | 324 | ||
| 322 | memcpy(buf, uaddr, uaddr_len); | 325 | memcpy(buf, uaddr, uaddr_len); |
| 323 | 326 | ||
| 324 | buf[uaddr_len] = '\n'; | 327 | buf[uaddr_len] = '\0'; |
| 325 | buf[uaddr_len + 1] = '\0'; | ||
| 326 | |||
| 327 | c = strrchr(buf, '.'); | 328 | c = strrchr(buf, '.'); |
| 328 | if (unlikely(c == NULL)) | 329 | if (unlikely(c == NULL)) |
| 329 | return 0; | 330 | return 0; |
| @@ -332,9 +333,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | |||
| 332 | if (unlikely(portlo > 255)) | 333 | if (unlikely(portlo > 255)) |
| 333 | return 0; | 334 | return 0; |
| 334 | 335 | ||
| 335 | c[0] = '\n'; | 336 | *c = '\0'; |
| 336 | c[1] = '\0'; | ||
| 337 | |||
| 338 | c = strrchr(buf, '.'); | 337 | c = strrchr(buf, '.'); |
| 339 | if (unlikely(c == NULL)) | 338 | if (unlikely(c == NULL)) |
| 340 | return 0; | 339 | return 0; |
| @@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | |||
| 345 | 344 | ||
| 346 | port = (unsigned short)((porthi << 8) | portlo); | 345 | port = (unsigned short)((porthi << 8) | portlo); |
| 347 | 346 | ||
| 348 | c[0] = '\0'; | 347 | *c = '\0'; |
| 349 | |||
| 350 | if (rpc_pton(buf, strlen(buf), sap, salen) == 0) | 348 | if (rpc_pton(buf, strlen(buf), sap, salen) == 0) |
| 351 | return 0; | 349 | return 0; |
| 352 | 350 | ||
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index ccc5e83cae5d..1c246a4f491e 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/wireless/core.h b/net/wireless/core.h index 2a33d8bc886b..68b321997d4c 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 79d2eec54cec..0a6b7a0eca6b 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/sme.c b/net/wireless/sme.c index 93c3ed329204..9f0b2800a9d7 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, |
