diff options
author | James Morris <jmorris@macbook.(none)> | 2009-12-03 01:33:40 -0500 |
---|---|---|
committer | James Morris <jmorris@macbook.(none)> | 2009-12-03 01:33:40 -0500 |
commit | c84d6efd363a3948eb32ec40d46bab6338580454 (patch) | |
tree | 3ba7ac46e6626fe8ac843834588609eb6ccee5c6 /net | |
parent | 7539cf4b92be4aecc573ea962135f246a7a33401 (diff) | |
parent | 22763c5cf3690a681551162c15d34d935308c8d7 (diff) |
Merge branch 'master' into next
Diffstat (limited to 'net')
119 files changed, 759 insertions, 601 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/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index 343146e1bceb..a91504850195 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c | |||
@@ -169,6 +169,7 @@ static size_t vlan_get_size(const struct net_device *dev) | |||
169 | struct vlan_dev_info *vlan = vlan_dev_info(dev); | 169 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
170 | 170 | ||
171 | return nla_total_size(2) + /* IFLA_VLAN_ID */ | 171 | return nla_total_size(2) + /* IFLA_VLAN_ID */ |
172 | sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */ | ||
172 | vlan_qos_map_size(vlan->nr_ingress_mappings) + | 173 | vlan_qos_map_size(vlan->nr_ingress_mappings) + |
173 | vlan_qos_map_size(vlan->nr_egress_mappings); | 174 | vlan_qos_map_size(vlan->nr_egress_mappings); |
174 | } | 175 | } |
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/9p/trans_virtio.c b/net/9p/trans_virtio.c index b2e07f0dd298..ea1e3daabefe 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <net/9p/transport.h> | 43 | #include <net/9p/transport.h> |
44 | #include <linux/scatterlist.h> | 44 | #include <linux/scatterlist.h> |
45 | #include <linux/virtio.h> | 45 | #include <linux/virtio.h> |
46 | #include <linux/virtio_ids.h> | ||
47 | #include <linux/virtio_9p.h> | 46 | #include <linux/virtio_9p.h> |
48 | 47 | ||
49 | #define VIRTQUEUE_NUM 128 | 48 | #define VIRTQUEUE_NUM 128 |
diff --git a/net/atm/common.c b/net/atm/common.c index 8c4d843eb17f..950bd16d2383 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -679,7 +679,7 @@ static int check_qos(const struct atm_qos *qos) | |||
679 | } | 679 | } |
680 | 680 | ||
681 | int vcc_setsockopt(struct socket *sock, int level, int optname, | 681 | int vcc_setsockopt(struct socket *sock, int level, int optname, |
682 | char __user *optval, int optlen) | 682 | char __user *optval, unsigned int optlen) |
683 | { | 683 | { |
684 | struct atm_vcc *vcc; | 684 | struct atm_vcc *vcc; |
685 | unsigned long value; | 685 | unsigned long value; |
diff --git a/net/atm/common.h b/net/atm/common.h index 92e2981f479f..f48a76b6cdf4 100644 --- a/net/atm/common.h +++ b/net/atm/common.h | |||
@@ -21,7 +21,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait); | |||
21 | int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); | 21 | int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); |
22 | int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); | 22 | int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); |
23 | int vcc_setsockopt(struct socket *sock, int level, int optname, | 23 | int vcc_setsockopt(struct socket *sock, int level, int optname, |
24 | char __user *optval, int optlen); | 24 | char __user *optval, unsigned int optlen); |
25 | int vcc_getsockopt(struct socket *sock, int level, int optname, | 25 | int vcc_getsockopt(struct socket *sock, int level, int optname, |
26 | char __user *optval, int __user *optlen); | 26 | char __user *optval, int __user *optlen); |
27 | 27 | ||
diff --git a/net/atm/pvc.c b/net/atm/pvc.c index e1d22d9430dd..d4c024504f99 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c | |||
@@ -59,7 +59,7 @@ static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr, | |||
59 | } | 59 | } |
60 | 60 | ||
61 | static int pvc_setsockopt(struct socket *sock, int level, int optname, | 61 | static int pvc_setsockopt(struct socket *sock, int level, int optname, |
62 | char __user *optval, int optlen) | 62 | char __user *optval, unsigned int optlen) |
63 | { | 63 | { |
64 | struct sock *sk = sock->sk; | 64 | struct sock *sk = sock->sk; |
65 | int error; | 65 | int error; |
diff --git a/net/atm/svc.c b/net/atm/svc.c index 7b831b526d0b..f90d143c4b25 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c | |||
@@ -446,7 +446,7 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos) | |||
446 | 446 | ||
447 | 447 | ||
448 | static int svc_setsockopt(struct socket *sock, int level, int optname, | 448 | static int svc_setsockopt(struct socket *sock, int level, int optname, |
449 | char __user *optval, int optlen) | 449 | char __user *optval, unsigned int optlen) |
450 | { | 450 | { |
451 | struct sock *sk = sock->sk; | 451 | struct sock *sk = sock->sk; |
452 | struct atm_vcc *vcc = ATM_SD(sock); | 452 | struct atm_vcc *vcc = ATM_SD(sock); |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fbcac76fdc0d..f45460730371 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -534,7 +534,7 @@ ax25_cb *ax25_create_cb(void) | |||
534 | */ | 534 | */ |
535 | 535 | ||
536 | static int ax25_setsockopt(struct socket *sock, int level, int optname, | 536 | static int ax25_setsockopt(struct socket *sock, int level, int optname, |
537 | char __user *optval, int optlen) | 537 | char __user *optval, unsigned int optlen) |
538 | { | 538 | { |
539 | struct sock *sk = sock->sk; | 539 | struct sock *sk = sock->sk; |
540 | ax25_cb *ax25; | 540 | ax25_cb *ax25; |
@@ -641,15 +641,10 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, | |||
641 | 641 | ||
642 | case SO_BINDTODEVICE: | 642 | case SO_BINDTODEVICE: |
643 | if (optlen > IFNAMSIZ) | 643 | if (optlen > IFNAMSIZ) |
644 | optlen=IFNAMSIZ; | 644 | optlen = IFNAMSIZ; |
645 | if (copy_from_user(devname, optval, optlen)) { | ||
646 | res = -EFAULT; | ||
647 | break; | ||
648 | } | ||
649 | 645 | ||
650 | dev = dev_get_by_name(&init_net, devname); | 646 | if (copy_from_user(devname, optval, optlen)) { |
651 | if (dev == NULL) { | 647 | res = -EFAULT; |
652 | res = -ENODEV; | ||
653 | break; | 648 | break; |
654 | } | 649 | } |
655 | 650 | ||
@@ -657,12 +652,18 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, | |||
657 | (sock->state != SS_UNCONNECTED || | 652 | (sock->state != SS_UNCONNECTED || |
658 | sk->sk_state == TCP_LISTEN)) { | 653 | sk->sk_state == TCP_LISTEN)) { |
659 | res = -EADDRNOTAVAIL; | 654 | res = -EADDRNOTAVAIL; |
660 | dev_put(dev); | 655 | break; |
656 | } | ||
657 | |||
658 | dev = dev_get_by_name(&init_net, devname); | ||
659 | if (!dev) { | ||
660 | res = -ENODEV; | ||
661 | break; | 661 | break; |
662 | } | 662 | } |
663 | 663 | ||
664 | ax25->ax25_dev = ax25_dev_ax25dev(dev); | 664 | ax25->ax25_dev = ax25_dev_ax25dev(dev); |
665 | ax25_fillin_cb(ax25, ax25->ax25_dev); | 665 | ax25_fillin_cb(ax25, ax25->ax25_dev); |
666 | dev_put(dev); | ||
666 | break; | 667 | break; |
667 | 668 | ||
668 | default: | 669 | default: |
@@ -900,7 +901,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) | |||
900 | 901 | ||
901 | sock_init_data(NULL, sk); | 902 | sock_init_data(NULL, sk); |
902 | 903 | ||
903 | sk->sk_destruct = ax25_free_sock; | ||
904 | sk->sk_type = osk->sk_type; | 904 | sk->sk_type = osk->sk_type; |
905 | sk->sk_priority = osk->sk_priority; | 905 | sk->sk_priority = osk->sk_priority; |
906 | sk->sk_protocol = osk->sk_protocol; | 906 | sk->sk_protocol = osk->sk_protocol; |
@@ -938,6 +938,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) | |||
938 | } | 938 | } |
939 | 939 | ||
940 | sk->sk_protinfo = ax25; | 940 | sk->sk_protinfo = ax25; |
941 | sk->sk_destruct = ax25_free_sock; | ||
941 | ax25->sk = sk; | 942 | ax25->sk = sk; |
942 | 943 | ||
943 | return sk; | 944 | return sk; |
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/hci_sock.c b/net/bluetooth/hci_sock.c index 4f9621f759a0..75302a986067 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -466,7 +466,7 @@ drop: | |||
466 | goto done; | 466 | goto done; |
467 | } | 467 | } |
468 | 468 | ||
469 | static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len) | 469 | static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len) |
470 | { | 470 | { |
471 | struct hci_ufilter uf = { .opcode = 0 }; | 471 | struct hci_ufilter uf = { .opcode = 0 }; |
472 | struct sock *sk = sock->sk; | 472 | struct sock *sk = sock->sk; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 7f939ce29801..2bc6f6a8de68 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -92,6 +92,8 @@ static void add_conn(struct work_struct *work) | |||
92 | 92 | ||
93 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); | 93 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); |
94 | 94 | ||
95 | dev_set_drvdata(&conn->dev, conn); | ||
96 | |||
95 | if (device_add(&conn->dev) < 0) { | 97 | if (device_add(&conn->dev) < 0) { |
96 | BT_ERR("Failed to register connection device"); | 98 | BT_ERR("Failed to register connection device"); |
97 | return; | 99 | return; |
@@ -144,8 +146,6 @@ void hci_conn_init_sysfs(struct hci_conn *conn) | |||
144 | conn->dev.class = bt_class; | 146 | conn->dev.class = bt_class; |
145 | conn->dev.parent = &hdev->dev; | 147 | conn->dev.parent = &hdev->dev; |
146 | 148 | ||
147 | dev_set_drvdata(&conn->dev, conn); | ||
148 | |||
149 | device_initialize(&conn->dev); | 149 | device_initialize(&conn->dev); |
150 | 150 | ||
151 | INIT_WORK(&conn->work_add, add_conn); | 151 | INIT_WORK(&conn->work_add, add_conn); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index b03012564647..947f8bbb4bb3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -555,12 +555,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
555 | 555 | ||
556 | conn->feat_mask = 0; | 556 | conn->feat_mask = 0; |
557 | 557 | ||
558 | setup_timer(&conn->info_timer, l2cap_info_timeout, | ||
559 | (unsigned long) conn); | ||
560 | |||
561 | spin_lock_init(&conn->lock); | 558 | spin_lock_init(&conn->lock); |
562 | rwlock_init(&conn->chan_list.lock); | 559 | rwlock_init(&conn->chan_list.lock); |
563 | 560 | ||
561 | setup_timer(&conn->info_timer, l2cap_info_timeout, | ||
562 | (unsigned long) conn); | ||
563 | |||
564 | conn->disc_reason = 0x13; | 564 | conn->disc_reason = 0x13; |
565 | 565 | ||
566 | return conn; | 566 | return conn; |
@@ -783,6 +783,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
783 | /* Default config options */ | 783 | /* Default config options */ |
784 | pi->conf_len = 0; | 784 | pi->conf_len = 0; |
785 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 785 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
786 | skb_queue_head_init(TX_QUEUE(sk)); | ||
787 | skb_queue_head_init(SREJ_QUEUE(sk)); | ||
788 | INIT_LIST_HEAD(SREJ_LIST(sk)); | ||
786 | } | 789 | } |
787 | 790 | ||
788 | static struct proto l2cap_proto = { | 791 | static struct proto l2cap_proto = { |
@@ -1698,7 +1701,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1698 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); | 1701 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); |
1699 | } | 1702 | } |
1700 | 1703 | ||
1701 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) | 1704 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) |
1702 | { | 1705 | { |
1703 | struct sock *sk = sock->sk; | 1706 | struct sock *sk = sock->sk; |
1704 | struct l2cap_options opts; | 1707 | struct l2cap_options opts; |
@@ -1755,7 +1758,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
1755 | return err; | 1758 | return err; |
1756 | } | 1759 | } |
1757 | 1760 | ||
1758 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 1761 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
1759 | { | 1762 | { |
1760 | struct sock *sk = sock->sk; | 1763 | struct sock *sk = sock->sk; |
1761 | struct bt_security sec; | 1764 | struct bt_security sec; |
@@ -2202,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
2202 | { | 2205 | { |
2203 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
2204 | struct l2cap_conf_req *req = data; | 2207 | struct l2cap_conf_req *req = data; |
2205 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM }; | 2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
2206 | void *ptr = req->data; | 2209 | void *ptr = req->data; |
2207 | 2210 | ||
2208 | BT_DBG("sk %p", sk); | 2211 | BT_DBG("sk %p", sk); |
@@ -2391,6 +2394,10 @@ done: | |||
2391 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; | 2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; |
2392 | 2395 | ||
2393 | 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 | |||
2394 | break; | 2401 | break; |
2395 | 2402 | ||
2396 | case L2CAP_MODE_STREAMING: | 2403 | case L2CAP_MODE_STREAMING: |
@@ -2398,6 +2405,10 @@ done: | |||
2398 | pi->max_pdu_size = rfc.max_pdu_size; | 2405 | pi->max_pdu_size = rfc.max_pdu_size; |
2399 | 2406 | ||
2400 | 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 | |||
2401 | break; | 2412 | break; |
2402 | 2413 | ||
2403 | default: | 2414 | default: |
@@ -2407,9 +2418,6 @@ done: | |||
2407 | rfc.mode = pi->mode; | 2418 | rfc.mode = pi->mode; |
2408 | } | 2419 | } |
2409 | 2420 | ||
2410 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2411 | sizeof(rfc), (unsigned long) &rfc); | ||
2412 | |||
2413 | if (result == L2CAP_CONF_SUCCESS) | 2421 | if (result == L2CAP_CONF_SUCCESS) |
2414 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 2422 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; |
2415 | } | 2423 | } |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 0b85e8116859..8a20aaf1f231 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -730,7 +730,7 @@ out: | |||
730 | return copied ? : err; | 730 | return copied ? : err; |
731 | } | 731 | } |
732 | 732 | ||
733 | static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) | 733 | static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) |
734 | { | 734 | { |
735 | struct sock *sk = sock->sk; | 735 | struct sock *sk = sock->sk; |
736 | int err = 0; | 736 | int err = 0; |
@@ -766,7 +766,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u | |||
766 | return err; | 766 | return err; |
767 | } | 767 | } |
768 | 768 | ||
769 | static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 769 | static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
770 | { | 770 | { |
771 | struct sock *sk = sock->sk; | 771 | struct sock *sk = sock->sk; |
772 | struct bt_security sec; | 772 | struct bt_security sec; |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 13c27f17192c..77f4153bdb5e 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -644,7 +644,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
644 | return err; | 644 | return err; |
645 | } | 645 | } |
646 | 646 | ||
647 | static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 647 | static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
648 | { | 648 | { |
649 | struct sock *sk = sock->sk; | 649 | struct sock *sk = sock->sk; |
650 | int err = 0; | 650 | int err = 0; |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 142ebac14176..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 | ||
@@ -432,6 +436,7 @@ err2: | |||
432 | br_fdb_delete_by_port(br, p, 1); | 436 | br_fdb_delete_by_port(br, p, 1); |
433 | err1: | 437 | err1: |
434 | kobject_put(&p->kobj); | 438 | kobject_put(&p->kobj); |
439 | p = NULL; /* kobject_put frees */ | ||
435 | err0: | 440 | err0: |
436 | dev_set_promiscuity(dev, -1); | 441 | dev_set_promiscuity(dev, -1); |
437 | put_back: | 442 | put_back: |
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/can/raw.c b/net/can/raw.c index db3152df7d2b..b5e897922d32 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -411,7 +411,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr, | |||
411 | } | 411 | } |
412 | 412 | ||
413 | static int raw_setsockopt(struct socket *sock, int level, int optname, | 413 | static int raw_setsockopt(struct socket *sock, int level, int optname, |
414 | char __user *optval, int optlen) | 414 | char __user *optval, unsigned int optlen) |
415 | { | 415 | { |
416 | struct sock *sk = sock->sk; | 416 | struct sock *sk = sock->sk; |
417 | struct raw_sock *ro = raw_sk(sk); | 417 | struct raw_sock *ro = raw_sk(sk); |
diff --git a/net/compat.c b/net/compat.c index 12728b17a226..a407c3addbae 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -331,7 +331,7 @@ struct compat_sock_fprog { | |||
331 | }; | 331 | }; |
332 | 332 | ||
333 | static int do_set_attach_filter(struct socket *sock, int level, int optname, | 333 | static int do_set_attach_filter(struct socket *sock, int level, int optname, |
334 | char __user *optval, int optlen) | 334 | char __user *optval, unsigned int optlen) |
335 | { | 335 | { |
336 | struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval; | 336 | struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval; |
337 | struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog)); | 337 | struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog)); |
@@ -351,7 +351,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname, | |||
351 | } | 351 | } |
352 | 352 | ||
353 | static int do_set_sock_timeout(struct socket *sock, int level, | 353 | static int do_set_sock_timeout(struct socket *sock, int level, |
354 | int optname, char __user *optval, int optlen) | 354 | int optname, char __user *optval, unsigned int optlen) |
355 | { | 355 | { |
356 | struct compat_timeval __user *up = (struct compat_timeval __user *) optval; | 356 | struct compat_timeval __user *up = (struct compat_timeval __user *) optval; |
357 | struct timeval ktime; | 357 | struct timeval ktime; |
@@ -373,7 +373,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, | |||
373 | } | 373 | } |
374 | 374 | ||
375 | static int compat_sock_setsockopt(struct socket *sock, int level, int optname, | 375 | static int compat_sock_setsockopt(struct socket *sock, int level, int optname, |
376 | char __user *optval, int optlen) | 376 | char __user *optval, unsigned int optlen) |
377 | { | 377 | { |
378 | if (optname == SO_ATTACH_FILTER) | 378 | if (optname == SO_ATTACH_FILTER) |
379 | return do_set_attach_filter(sock, level, optname, | 379 | return do_set_attach_filter(sock, level, optname, |
@@ -385,7 +385,7 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname, | |||
385 | } | 385 | } |
386 | 386 | ||
387 | asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, | 387 | asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, |
388 | char __user *optval, int optlen) | 388 | char __user *optval, unsigned int optlen) |
389 | { | 389 | { |
390 | int err; | 390 | int err; |
391 | struct socket *sock; | 391 | struct socket *sock; |
@@ -558,8 +558,8 @@ struct compat_group_filter { | |||
558 | 558 | ||
559 | 559 | ||
560 | int compat_mc_setsockopt(struct sock *sock, int level, int optname, | 560 | int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
561 | char __user *optval, int optlen, | 561 | char __user *optval, unsigned int optlen, |
562 | int (*setsockopt)(struct sock *,int,int,char __user *,int)) | 562 | int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int)) |
563 | { | 563 | { |
564 | char __user *koptval = optval; | 564 | char __user *koptval = optval; |
565 | int koptlen = optlen; | 565 | int koptlen = optlen; |
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 560c8c9c03ab..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 | ||
@@ -2288,6 +2289,9 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2288 | int ret = NET_RX_DROP; | 2289 | int ret = NET_RX_DROP; |
2289 | __be16 type; | 2290 | __be16 type; |
2290 | 2291 | ||
2292 | if (!skb->tstamp.tv64) | ||
2293 | net_timestamp(skb); | ||
2294 | |||
2291 | if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) | 2295 | if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) |
2292 | return NET_RX_SUCCESS; | 2296 | return NET_RX_SUCCESS; |
2293 | 2297 | ||
@@ -2295,9 +2299,6 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2295 | if (netpoll_receive_skb(skb)) | 2299 | if (netpoll_receive_skb(skb)) |
2296 | return NET_RX_DROP; | 2300 | return NET_RX_DROP; |
2297 | 2301 | ||
2298 | if (!skb->tstamp.tv64) | ||
2299 | net_timestamp(skb); | ||
2300 | |||
2301 | if (!skb->iif) | 2302 | if (!skb->iif) |
2302 | skb->iif = skb->dev->ifindex; | 2303 | skb->iif = skb->dev->ifindex; |
2303 | 2304 | ||
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 7d4c57523b09..427ded841224 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <net/sock.h> | 16 | #include <net/sock.h> |
17 | #include <linux/rtnetlink.h> | 17 | #include <linux/rtnetlink.h> |
18 | #include <linux/wireless.h> | 18 | #include <linux/wireless.h> |
19 | #include <net/iw_handler.h> | 19 | #include <net/wext.h> |
20 | 20 | ||
21 | #include "net-sysfs.h" | 21 | #include "net-sysfs.h" |
22 | 22 | ||
@@ -363,18 +363,16 @@ static ssize_t wireless_show(struct device *d, char *buf, | |||
363 | char *)) | 363 | char *)) |
364 | { | 364 | { |
365 | struct net_device *dev = to_net_dev(d); | 365 | struct net_device *dev = to_net_dev(d); |
366 | const struct iw_statistics *iw = NULL; | 366 | const struct iw_statistics *iw; |
367 | ssize_t ret = -EINVAL; | 367 | ssize_t ret = -EINVAL; |
368 | 368 | ||
369 | read_lock(&dev_base_lock); | 369 | rtnl_lock(); |
370 | if (dev_isalive(dev)) { | 370 | if (dev_isalive(dev)) { |
371 | if (dev->wireless_handlers && | 371 | iw = get_wireless_stats(dev); |
372 | dev->wireless_handlers->get_wireless_stats) | 372 | if (iw) |
373 | iw = dev->wireless_handlers->get_wireless_stats(dev); | ||
374 | if (iw != NULL) | ||
375 | ret = (*format)(iw, buf); | 373 | ret = (*format)(iw, buf); |
376 | } | 374 | } |
377 | read_unlock(&dev_base_lock); | 375 | rtnl_unlock(); |
378 | 376 | ||
379 | return ret; | 377 | return ret; |
380 | } | 378 | } |
@@ -505,7 +503,7 @@ int netdev_register_kobject(struct net_device *net) | |||
505 | *groups++ = &netstat_group; | 503 | *groups++ = &netstat_group; |
506 | 504 | ||
507 | #ifdef CONFIG_WIRELESS_EXT_SYSFS | 505 | #ifdef CONFIG_WIRELESS_EXT_SYSFS |
508 | if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats) | 506 | if (net->wireless_handlers || net->ieee80211_ptr) |
509 | *groups++ = &wireless_group; | 507 | *groups++ = &wireless_group; |
510 | #endif | 508 | #endif |
511 | #endif /* CONFIG_SYSFS */ | 509 | #endif /* CONFIG_SYSFS */ |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 4d11c28ca8ca..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); |
@@ -964,7 +966,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
964 | if (value == 0x7FFFFFFF) | 966 | if (value == 0x7FFFFFFF) |
965 | pkt_dev->delay = ULLONG_MAX; | 967 | pkt_dev->delay = ULLONG_MAX; |
966 | else | 968 | else |
967 | pkt_dev->delay = (u64)value * NSEC_PER_USEC; | 969 | pkt_dev->delay = (u64)value; |
968 | 970 | ||
969 | sprintf(pg_result, "OK: delay=%llu", | 971 | sprintf(pg_result, "OK: delay=%llu", |
970 | (unsigned long long) pkt_dev->delay); | 972 | (unsigned long long) pkt_dev->delay); |
@@ -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 | ||
@@ -2105,15 +2108,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2105 | static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) | 2108 | static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) |
2106 | { | 2109 | { |
2107 | ktime_t start_time, end_time; | 2110 | ktime_t start_time, end_time; |
2108 | s32 remaining; | 2111 | s64 remaining; |
2109 | struct hrtimer_sleeper t; | 2112 | struct hrtimer_sleeper t; |
2110 | 2113 | ||
2111 | hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | 2114 | hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); |
2112 | hrtimer_set_expires(&t.timer, spin_until); | 2115 | hrtimer_set_expires(&t.timer, spin_until); |
2113 | 2116 | ||
2114 | remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer)); | 2117 | remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer)); |
2115 | if (remaining <= 0) | 2118 | if (remaining <= 0) { |
2119 | pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay); | ||
2116 | return; | 2120 | return; |
2121 | } | ||
2117 | 2122 | ||
2118 | start_time = ktime_now(); | 2123 | start_time = ktime_now(); |
2119 | if (remaining < 100) | 2124 | if (remaining < 100) |
@@ -2210,7 +2215,7 @@ static void set_cur_queue_map(struct pktgen_dev *pkt_dev) | |||
2210 | if (pkt_dev->flags & F_QUEUE_MAP_CPU) | 2215 | if (pkt_dev->flags & F_QUEUE_MAP_CPU) |
2211 | pkt_dev->cur_queue_map = smp_processor_id(); | 2216 | pkt_dev->cur_queue_map = smp_processor_id(); |
2212 | 2217 | ||
2213 | else if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) { | 2218 | else if (pkt_dev->queue_map_min <= pkt_dev->queue_map_max) { |
2214 | __u16 t; | 2219 | __u16 t; |
2215 | if (pkt_dev->flags & F_QUEUE_MAP_RND) { | 2220 | if (pkt_dev->flags & F_QUEUE_MAP_RND) { |
2216 | t = random32() % | 2221 | t = random32() % |
@@ -2628,6 +2633,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2628 | iph->protocol = IPPROTO_UDP; /* UDP */ | 2633 | iph->protocol = IPPROTO_UDP; /* UDP */ |
2629 | iph->saddr = pkt_dev->cur_saddr; | 2634 | iph->saddr = pkt_dev->cur_saddr; |
2630 | 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++; | ||
2631 | iph->frag_off = 0; | 2638 | iph->frag_off = 0; |
2632 | iplen = 20 + 8 + datalen; | 2639 | iplen = 20 + 8 + datalen; |
2633 | iph->tot_len = htons(iplen); | 2640 | iph->tot_len = htons(iplen); |
@@ -2639,24 +2646,26 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2639 | skb->dev = odev; | 2646 | skb->dev = odev; |
2640 | skb->pkt_type = PACKET_HOST; | 2647 | skb->pkt_type = PACKET_HOST; |
2641 | 2648 | ||
2642 | if (pkt_dev->nfrags <= 0) | 2649 | if (pkt_dev->nfrags <= 0) { |
2643 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); | 2650 | pgh = (struct pktgen_hdr *)skb_put(skb, datalen); |
2644 | else { | 2651 | memset(pgh + 1, 0, datalen - sizeof(struct pktgen_hdr)); |
2652 | } else { | ||
2645 | int frags = pkt_dev->nfrags; | 2653 | int frags = pkt_dev->nfrags; |
2646 | int i; | 2654 | int i, len; |
2647 | 2655 | ||
2648 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); | 2656 | pgh = (struct pktgen_hdr *)(((char *)(udph)) + 8); |
2649 | 2657 | ||
2650 | if (frags > MAX_SKB_FRAGS) | 2658 | if (frags > MAX_SKB_FRAGS) |
2651 | frags = MAX_SKB_FRAGS; | 2659 | frags = MAX_SKB_FRAGS; |
2652 | if (datalen > frags * PAGE_SIZE) { | 2660 | if (datalen > frags * PAGE_SIZE) { |
2653 | skb_put(skb, datalen - frags * PAGE_SIZE); | 2661 | len = datalen - frags * PAGE_SIZE; |
2662 | memset(skb_put(skb, len), 0, len); | ||
2654 | datalen = frags * PAGE_SIZE; | 2663 | datalen = frags * PAGE_SIZE; |
2655 | } | 2664 | } |
2656 | 2665 | ||
2657 | i = 0; | 2666 | i = 0; |
2658 | while (datalen > 0) { | 2667 | while (datalen > 0) { |
2659 | struct page *page = alloc_pages(GFP_KERNEL, 0); | 2668 | struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); |
2660 | skb_shinfo(skb)->frags[i].page = page; | 2669 | skb_shinfo(skb)->frags[i].page = page; |
2661 | skb_shinfo(skb)->frags[i].page_offset = 0; | 2670 | skb_shinfo(skb)->frags[i].page_offset = 0; |
2662 | skb_shinfo(skb)->frags[i].size = | 2671 | skb_shinfo(skb)->frags[i].size = |
@@ -3255,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) | |||
3255 | 3264 | ||
3256 | if (!pkt_dev->running) { | 3265 | if (!pkt_dev->running) { |
3257 | printk(KERN_WARNING "pktgen: interface: %s is already " | 3266 | printk(KERN_WARNING "pktgen: interface: %s is already " |
3258 | "stopped\n", pkt_dev->odev->name); | 3267 | "stopped\n", pkt_dev->odevname); |
3259 | return -EINVAL; | 3268 | return -EINVAL; |
3260 | } | 3269 | } |
3261 | 3270 | ||
@@ -3457,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
3457 | default: /* Drivers are not supposed to return other values! */ | 3466 | default: /* Drivers are not supposed to return other values! */ |
3458 | if (net_ratelimit()) | 3467 | if (net_ratelimit()) |
3459 | pr_info("pktgen: %s xmit error: %d\n", | 3468 | pr_info("pktgen: %s xmit error: %d\n", |
3460 | odev->name, ret); | 3469 | pkt_dev->odevname, ret); |
3461 | pkt_dev->errors++; | 3470 | pkt_dev->errors++; |
3462 | /* fallthru */ | 3471 | /* fallthru */ |
3463 | case NETDEV_TX_LOCKED: | 3472 | case NETDEV_TX_LOCKED: |
@@ -3559,13 +3568,18 @@ static int pktgen_thread_worker(void *arg) | |||
3559 | } | 3568 | } |
3560 | 3569 | ||
3561 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 3570 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
3562 | const char *ifname) | 3571 | const char *ifname, bool exact) |
3563 | { | 3572 | { |
3564 | struct pktgen_dev *p, *pkt_dev = NULL; | 3573 | struct pktgen_dev *p, *pkt_dev = NULL; |
3565 | if_lock(t); | 3574 | size_t len = strlen(ifname); |
3566 | 3575 | ||
3576 | if_lock(t); | ||
3567 | list_for_each_entry(p, &t->if_list, list) | 3577 | list_for_each_entry(p, &t->if_list, list) |
3568 | 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 | } | ||
3569 | pkt_dev = p; | 3583 | pkt_dev = p; |
3570 | break; | 3584 | break; |
3571 | } | 3585 | } |
@@ -3621,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3621 | if (!pkt_dev) | 3635 | if (!pkt_dev) |
3622 | return -ENOMEM; | 3636 | return -ENOMEM; |
3623 | 3637 | ||
3638 | strcpy(pkt_dev->odevname, ifname); | ||
3624 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); | 3639 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); |
3625 | if (pkt_dev->flows == NULL) { | 3640 | if (pkt_dev->flows == NULL) { |
3626 | 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/core/sock.c b/net/core/sock.c index 524712a7b154..7626b6aacd68 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -446,7 +446,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) | |||
446 | */ | 446 | */ |
447 | 447 | ||
448 | int sock_setsockopt(struct socket *sock, int level, int optname, | 448 | int sock_setsockopt(struct socket *sock, int level, int optname, |
449 | char __user *optval, int optlen) | 449 | char __user *optval, unsigned int optlen) |
450 | { | 450 | { |
451 | struct sock *sk = sock->sk; | 451 | struct sock *sk = sock->sk; |
452 | int val; | 452 | int val; |
@@ -1228,17 +1228,22 @@ void __init sk_init(void) | |||
1228 | void sock_wfree(struct sk_buff *skb) | 1228 | void sock_wfree(struct sk_buff *skb) |
1229 | { | 1229 | { |
1230 | struct sock *sk = skb->sk; | 1230 | struct sock *sk = skb->sk; |
1231 | int res; | 1231 | unsigned int len = skb->truesize; |
1232 | 1232 | ||
1233 | /* In case it might be waiting for more memory. */ | 1233 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) { |
1234 | res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); | 1234 | /* |
1235 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) | 1235 | * Keep a reference on sk_wmem_alloc, this will be released |
1236 | * after sk_write_space() call | ||
1237 | */ | ||
1238 | atomic_sub(len - 1, &sk->sk_wmem_alloc); | ||
1236 | sk->sk_write_space(sk); | 1239 | sk->sk_write_space(sk); |
1240 | len = 1; | ||
1241 | } | ||
1237 | /* | 1242 | /* |
1238 | * if sk_wmem_alloc reached 0, we are last user and should | 1243 | * if sk_wmem_alloc reaches 0, we must finish what sk_free() |
1239 | * free this sock, as sk_free() call could not do it. | 1244 | * could not do because of in-flight packets |
1240 | */ | 1245 | */ |
1241 | if (res == 0) | 1246 | if (atomic_sub_and_test(len, &sk->sk_wmem_alloc)) |
1242 | __sk_free(sk); | 1247 | __sk_free(sk); |
1243 | } | 1248 | } |
1244 | EXPORT_SYMBOL(sock_wfree); | 1249 | EXPORT_SYMBOL(sock_wfree); |
@@ -1697,7 +1702,7 @@ int sock_no_shutdown(struct socket *sock, int how) | |||
1697 | EXPORT_SYMBOL(sock_no_shutdown); | 1702 | EXPORT_SYMBOL(sock_no_shutdown); |
1698 | 1703 | ||
1699 | int sock_no_setsockopt(struct socket *sock, int level, int optname, | 1704 | int sock_no_setsockopt(struct socket *sock, int level, int optname, |
1700 | char __user *optval, int optlen) | 1705 | char __user *optval, unsigned int optlen) |
1701 | { | 1706 | { |
1702 | return -EOPNOTSUPP; | 1707 | return -EOPNOTSUPP; |
1703 | } | 1708 | } |
@@ -2018,7 +2023,7 @@ EXPORT_SYMBOL(sock_common_recvmsg); | |||
2018 | * Set socket options on an inet socket. | 2023 | * Set socket options on an inet socket. |
2019 | */ | 2024 | */ |
2020 | int sock_common_setsockopt(struct socket *sock, int level, int optname, | 2025 | int sock_common_setsockopt(struct socket *sock, int level, int optname, |
2021 | char __user *optval, int optlen) | 2026 | char __user *optval, unsigned int optlen) |
2022 | { | 2027 | { |
2023 | struct sock *sk = sock->sk; | 2028 | struct sock *sk = sock->sk; |
2024 | 2029 | ||
@@ -2028,7 +2033,7 @@ EXPORT_SYMBOL(sock_common_setsockopt); | |||
2028 | 2033 | ||
2029 | #ifdef CONFIG_COMPAT | 2034 | #ifdef CONFIG_COMPAT |
2030 | int compat_sock_common_setsockopt(struct socket *sock, int level, int optname, | 2035 | int compat_sock_common_setsockopt(struct socket *sock, int level, int optname, |
2031 | char __user *optval, int optlen) | 2036 | char __user *optval, unsigned int optlen) |
2032 | { | 2037 | { |
2033 | struct sock *sk = sock->sk; | 2038 | struct sock *sk = sock->sk; |
2034 | 2039 | ||
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index e0879bfb7dd5..ac1205df6c86 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -194,7 +194,7 @@ static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, | |||
194 | nlmsg_end(dcbnl_skb, nlh); | 194 | nlmsg_end(dcbnl_skb, nlh); |
195 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 195 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
196 | if (ret) | 196 | if (ret) |
197 | goto err; | 197 | return -EINVAL; |
198 | 198 | ||
199 | return 0; | 199 | return 0; |
200 | nlmsg_failure: | 200 | nlmsg_failure: |
@@ -275,7 +275,7 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, | |||
275 | 275 | ||
276 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 276 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
277 | if (ret) | 277 | if (ret) |
278 | goto err; | 278 | goto err_out; |
279 | 279 | ||
280 | return 0; | 280 | return 0; |
281 | nlmsg_failure: | 281 | nlmsg_failure: |
@@ -316,12 +316,11 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, | |||
316 | 316 | ||
317 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 317 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
318 | if (ret) | 318 | if (ret) |
319 | goto err; | 319 | goto err_out; |
320 | 320 | ||
321 | return 0; | 321 | return 0; |
322 | 322 | ||
323 | nlmsg_failure: | 323 | nlmsg_failure: |
324 | err: | ||
325 | kfree_skb(dcbnl_skb); | 324 | kfree_skb(dcbnl_skb); |
326 | err_out: | 325 | err_out: |
327 | return -EINVAL; | 326 | return -EINVAL; |
@@ -383,7 +382,7 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, | |||
383 | 382 | ||
384 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 383 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
385 | if (ret) | 384 | if (ret) |
386 | goto err; | 385 | goto err_out; |
387 | 386 | ||
388 | return 0; | 387 | return 0; |
389 | nlmsg_failure: | 388 | nlmsg_failure: |
@@ -460,7 +459,7 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, | |||
460 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 459 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
461 | if (ret) { | 460 | if (ret) { |
462 | ret = -EINVAL; | 461 | ret = -EINVAL; |
463 | goto err; | 462 | goto err_out; |
464 | } | 463 | } |
465 | 464 | ||
466 | return 0; | 465 | return 0; |
@@ -799,7 +798,7 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, | |||
799 | 798 | ||
800 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 799 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
801 | if (ret) | 800 | if (ret) |
802 | goto err; | 801 | goto err_out; |
803 | 802 | ||
804 | return 0; | 803 | return 0; |
805 | 804 | ||
@@ -1063,7 +1062,7 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, | |||
1063 | 1062 | ||
1064 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); | 1063 | ret = rtnl_unicast(dcbnl_skb, &init_net, pid); |
1065 | if (ret) | 1064 | if (ret) |
1066 | goto err; | 1065 | goto err_out; |
1067 | 1066 | ||
1068 | return 0; | 1067 | return 0; |
1069 | 1068 | ||
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index d6bc47363b1c..5ef32c2f0d6a 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -290,14 +290,14 @@ extern int dccp_disconnect(struct sock *sk, int flags); | |||
290 | extern int dccp_getsockopt(struct sock *sk, int level, int optname, | 290 | extern int dccp_getsockopt(struct sock *sk, int level, int optname, |
291 | char __user *optval, int __user *optlen); | 291 | char __user *optval, int __user *optlen); |
292 | extern int dccp_setsockopt(struct sock *sk, int level, int optname, | 292 | extern int dccp_setsockopt(struct sock *sk, int level, int optname, |
293 | char __user *optval, int optlen); | 293 | char __user *optval, unsigned int optlen); |
294 | #ifdef CONFIG_COMPAT | 294 | #ifdef CONFIG_COMPAT |
295 | extern int compat_dccp_getsockopt(struct sock *sk, | 295 | extern int compat_dccp_getsockopt(struct sock *sk, |
296 | int level, int optname, | 296 | int level, int optname, |
297 | char __user *optval, int __user *optlen); | 297 | char __user *optval, int __user *optlen); |
298 | extern int compat_dccp_setsockopt(struct sock *sk, | 298 | extern int compat_dccp_setsockopt(struct sock *sk, |
299 | int level, int optname, | 299 | int level, int optname, |
300 | char __user *optval, int optlen); | 300 | char __user *optval, unsigned int optlen); |
301 | #endif | 301 | #endif |
302 | extern int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg); | 302 | extern int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg); |
303 | extern int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, | 303 | extern int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index bc4467082a00..a156319fd0ac 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -393,7 +393,7 @@ out: | |||
393 | EXPORT_SYMBOL_GPL(dccp_ioctl); | 393 | EXPORT_SYMBOL_GPL(dccp_ioctl); |
394 | 394 | ||
395 | static int dccp_setsockopt_service(struct sock *sk, const __be32 service, | 395 | static int dccp_setsockopt_service(struct sock *sk, const __be32 service, |
396 | char __user *optval, int optlen) | 396 | char __user *optval, unsigned int optlen) |
397 | { | 397 | { |
398 | struct dccp_sock *dp = dccp_sk(sk); | 398 | struct dccp_sock *dp = dccp_sk(sk); |
399 | struct dccp_service_list *sl = NULL; | 399 | struct dccp_service_list *sl = NULL; |
@@ -464,7 +464,7 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx) | |||
464 | } | 464 | } |
465 | 465 | ||
466 | static int dccp_setsockopt_ccid(struct sock *sk, int type, | 466 | static int dccp_setsockopt_ccid(struct sock *sk, int type, |
467 | char __user *optval, int optlen) | 467 | char __user *optval, unsigned int optlen) |
468 | { | 468 | { |
469 | u8 *val; | 469 | u8 *val; |
470 | int rc = 0; | 470 | int rc = 0; |
@@ -494,7 +494,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type, | |||
494 | } | 494 | } |
495 | 495 | ||
496 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | 496 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, |
497 | char __user *optval, int optlen) | 497 | char __user *optval, unsigned int optlen) |
498 | { | 498 | { |
499 | struct dccp_sock *dp = dccp_sk(sk); | 499 | struct dccp_sock *dp = dccp_sk(sk); |
500 | int val, err = 0; | 500 | int val, err = 0; |
@@ -546,7 +546,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
546 | } | 546 | } |
547 | 547 | ||
548 | int dccp_setsockopt(struct sock *sk, int level, int optname, | 548 | int dccp_setsockopt(struct sock *sk, int level, int optname, |
549 | char __user *optval, int optlen) | 549 | char __user *optval, unsigned int optlen) |
550 | { | 550 | { |
551 | if (level != SOL_DCCP) | 551 | if (level != SOL_DCCP) |
552 | return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level, | 552 | return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level, |
@@ -559,7 +559,7 @@ EXPORT_SYMBOL_GPL(dccp_setsockopt); | |||
559 | 559 | ||
560 | #ifdef CONFIG_COMPAT | 560 | #ifdef CONFIG_COMPAT |
561 | int compat_dccp_setsockopt(struct sock *sk, int level, int optname, | 561 | int compat_dccp_setsockopt(struct sock *sk, int level, int optname, |
562 | char __user *optval, int optlen) | 562 | char __user *optval, unsigned int optlen) |
563 | { | 563 | { |
564 | if (level != SOL_DCCP) | 564 | if (level != SOL_DCCP) |
565 | return inet_csk_compat_setsockopt(sk, level, optname, | 565 | return inet_csk_compat_setsockopt(sk, level, optname, |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 77d40289653c..7a58c87baf17 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -157,7 +157,7 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; | |||
157 | static struct hlist_head dn_wild_sk; | 157 | static struct hlist_head dn_wild_sk; |
158 | static atomic_t decnet_memory_allocated; | 158 | static atomic_t decnet_memory_allocated; |
159 | 159 | ||
160 | static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags); | 160 | static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags); |
161 | static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); | 161 | static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); |
162 | 162 | ||
163 | static struct hlist_head *dn_find_list(struct sock *sk) | 163 | static struct hlist_head *dn_find_list(struct sock *sk) |
@@ -1325,7 +1325,7 @@ out: | |||
1325 | return err; | 1325 | return err; |
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 1328 | static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
1329 | { | 1329 | { |
1330 | struct sock *sk = sock->sk; | 1330 | struct sock *sk = sock->sk; |
1331 | int err; | 1331 | int err; |
@@ -1337,7 +1337,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use | |||
1337 | return err; | 1337 | return err; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags) | 1340 | static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags) |
1341 | { | 1341 | { |
1342 | struct sock *sk = sock->sk; | 1342 | struct sock *sk = sock->sk; |
1343 | struct dn_scp *scp = DN_SK(sk); | 1343 | struct dn_scp *scp = DN_SK(sk); |
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/ieee802154/dgram.c b/net/ieee802154/dgram.c index 51593a48f2dd..a413b1bf4465 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
@@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname, | |||
414 | } | 414 | } |
415 | 415 | ||
416 | static int dgram_setsockopt(struct sock *sk, int level, int optname, | 416 | static int dgram_setsockopt(struct sock *sk, int level, int optname, |
417 | char __user *optval, int optlen) | 417 | char __user *optval, unsigned int optlen) |
418 | { | 418 | { |
419 | struct dgram_sock *ro = dgram_sk(sk); | 419 | struct dgram_sock *ro = dgram_sk(sk); |
420 | int val; | 420 | int val; |
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 13198859982e..30e74eee07d6 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c | |||
@@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname, | |||
244 | } | 244 | } |
245 | 245 | ||
246 | static int raw_setsockopt(struct sock *sk, int level, int optname, | 246 | static int raw_setsockopt(struct sock *sk, int level, int optname, |
247 | char __user *optval, int optlen) | 247 | char __user *optval, unsigned int optlen) |
248 | { | 248 | { |
249 | return -EOPNOTSUPP; | 249 | return -EOPNOTSUPP; |
250 | } | 250 | } |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 58c4b0f7c4aa..57737b8d1711 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1119,6 +1119,7 @@ int inet_sk_rebuild_header(struct sock *sk) | |||
1119 | { | 1119 | { |
1120 | struct flowi fl = { | 1120 | struct flowi fl = { |
1121 | .oif = sk->sk_bound_dev_if, | 1121 | .oif = sk->sk_bound_dev_if, |
1122 | .mark = sk->sk_mark, | ||
1122 | .nl_u = { | 1123 | .nl_u = { |
1123 | .ip4_u = { | 1124 | .ip4_u = { |
1124 | .daddr = daddr, | 1125 | .daddr = daddr, |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index e92f1fd28aa5..5df2f6a0b0f0 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1077,12 +1077,16 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1077 | ip_mc_up(in_dev); | 1077 | ip_mc_up(in_dev); |
1078 | /* fall through */ | 1078 | /* fall through */ |
1079 | case NETDEV_CHANGEADDR: | 1079 | case NETDEV_CHANGEADDR: |
1080 | if (IN_DEV_ARP_NOTIFY(in_dev)) | 1080 | /* Send gratuitous ARP to notify of link change */ |
1081 | arp_send(ARPOP_REQUEST, ETH_P_ARP, | 1081 | if (IN_DEV_ARP_NOTIFY(in_dev)) { |
1082 | in_dev->ifa_list->ifa_address, | 1082 | struct in_ifaddr *ifa = in_dev->ifa_list; |
1083 | dev, | 1083 | |
1084 | in_dev->ifa_list->ifa_address, | 1084 | if (ifa) |
1085 | NULL, dev->dev_addr, NULL); | 1085 | arp_send(ARPOP_REQUEST, ETH_P_ARP, |
1086 | ifa->ifa_address, dev, | ||
1087 | ifa->ifa_address, NULL, | ||
1088 | dev->dev_addr, NULL); | ||
1089 | } | ||
1086 | break; | 1090 | break; |
1087 | case NETDEV_DOWN: | 1091 | case NETDEV_DOWN: |
1088 | ip_mc_down(in_dev); | 1092 | ip_mc_down(in_dev); |
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/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 22cd19ee44e5..537731b3bcb3 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -446,6 +446,28 @@ extern int sysctl_tcp_synack_retries; | |||
446 | 446 | ||
447 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); | 447 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); |
448 | 448 | ||
449 | /* Decide when to expire the request and when to resend SYN-ACK */ | ||
450 | static inline void syn_ack_recalc(struct request_sock *req, const int thresh, | ||
451 | const int max_retries, | ||
452 | const u8 rskq_defer_accept, | ||
453 | int *expire, int *resend) | ||
454 | { | ||
455 | if (!rskq_defer_accept) { | ||
456 | *expire = req->retrans >= thresh; | ||
457 | *resend = 1; | ||
458 | return; | ||
459 | } | ||
460 | *expire = req->retrans >= thresh && | ||
461 | (!inet_rsk(req)->acked || req->retrans >= max_retries); | ||
462 | /* | ||
463 | * Do not resend while waiting for data after ACK, | ||
464 | * start to resend on end of deferring period to give | ||
465 | * last chance for data or ACK to create established socket. | ||
466 | */ | ||
467 | *resend = !inet_rsk(req)->acked || | ||
468 | req->retrans >= rskq_defer_accept - 1; | ||
469 | } | ||
470 | |||
449 | void inet_csk_reqsk_queue_prune(struct sock *parent, | 471 | void inet_csk_reqsk_queue_prune(struct sock *parent, |
450 | const unsigned long interval, | 472 | const unsigned long interval, |
451 | const unsigned long timeout, | 473 | const unsigned long timeout, |
@@ -501,9 +523,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
501 | reqp=&lopt->syn_table[i]; | 523 | reqp=&lopt->syn_table[i]; |
502 | while ((req = *reqp) != NULL) { | 524 | while ((req = *reqp) != NULL) { |
503 | if (time_after_eq(now, req->expires)) { | 525 | if (time_after_eq(now, req->expires)) { |
504 | if ((req->retrans < thresh || | 526 | int expire = 0, resend = 0; |
505 | (inet_rsk(req)->acked && req->retrans < max_retries)) | 527 | |
506 | && !req->rsk_ops->rtx_syn_ack(parent, req)) { | 528 | syn_ack_recalc(req, thresh, max_retries, |
529 | queue->rskq_defer_accept, | ||
530 | &expire, &resend); | ||
531 | if (!expire && | ||
532 | (!resend || | ||
533 | !req->rsk_ops->rtx_syn_ack(parent, req) || | ||
534 | inet_rsk(req)->acked)) { | ||
507 | unsigned long timeo; | 535 | unsigned long timeo; |
508 | 536 | ||
509 | if (req->retrans++ == 0) | 537 | if (req->retrans++ == 0) |
@@ -714,7 +742,7 @@ int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname, | |||
714 | EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt); | 742 | EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt); |
715 | 743 | ||
716 | int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, | 744 | int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, |
717 | char __user *optval, int optlen) | 745 | char __user *optval, unsigned int optlen) |
718 | { | 746 | { |
719 | const struct inet_connection_sock *icsk = inet_csk(sk); | 747 | const struct inet_connection_sock *icsk = inet_csk(sk); |
720 | 748 | ||
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/ip_output.c b/net/ipv4/ip_output.c index 9fe5d7b81580..f9895180f481 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -335,6 +335,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | |||
335 | 335 | ||
336 | { | 336 | { |
337 | struct flowi fl = { .oif = sk->sk_bound_dev_if, | 337 | struct flowi fl = { .oif = sk->sk_bound_dev_if, |
338 | .mark = sk->sk_mark, | ||
338 | .nl_u = { .ip4_u = | 339 | .nl_u = { .ip4_u = |
339 | { .daddr = daddr, | 340 | { .daddr = daddr, |
340 | .saddr = inet->saddr, | 341 | .saddr = inet->saddr, |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5a0693576e82..e982b5c1ee17 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -440,7 +440,7 @@ out: | |||
440 | */ | 440 | */ |
441 | 441 | ||
442 | static int do_ip_setsockopt(struct sock *sk, int level, | 442 | static int do_ip_setsockopt(struct sock *sk, int level, |
443 | int optname, char __user *optval, int optlen) | 443 | int optname, char __user *optval, unsigned int optlen) |
444 | { | 444 | { |
445 | struct inet_sock *inet = inet_sk(sk); | 445 | struct inet_sock *inet = inet_sk(sk); |
446 | int val = 0, err; | 446 | int val = 0, err; |
@@ -634,17 +634,16 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
634 | break; | 634 | break; |
635 | } | 635 | } |
636 | dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr); | 636 | dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr); |
637 | if (dev) { | 637 | if (dev) |
638 | mreq.imr_ifindex = dev->ifindex; | 638 | mreq.imr_ifindex = dev->ifindex; |
639 | dev_put(dev); | ||
640 | } | ||
641 | } else | 639 | } else |
642 | dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex); | 640 | dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex); |
643 | 641 | ||
644 | 642 | ||
645 | err = -EADDRNOTAVAIL; | 643 | err = -EADDRNOTAVAIL; |
646 | if (!dev) | 644 | if (!dev) |
647 | break; | 645 | break; |
646 | dev_put(dev); | ||
648 | 647 | ||
649 | err = -EINVAL; | 648 | err = -EINVAL; |
650 | if (sk->sk_bound_dev_if && | 649 | if (sk->sk_bound_dev_if && |
@@ -950,7 +949,7 @@ e_inval: | |||
950 | } | 949 | } |
951 | 950 | ||
952 | int ip_setsockopt(struct sock *sk, int level, | 951 | int ip_setsockopt(struct sock *sk, int level, |
953 | int optname, char __user *optval, int optlen) | 952 | int optname, char __user *optval, unsigned int optlen) |
954 | { | 953 | { |
955 | int err; | 954 | int err; |
956 | 955 | ||
@@ -975,7 +974,7 @@ EXPORT_SYMBOL(ip_setsockopt); | |||
975 | 974 | ||
976 | #ifdef CONFIG_COMPAT | 975 | #ifdef CONFIG_COMPAT |
977 | int compat_ip_setsockopt(struct sock *sk, int level, int optname, | 976 | int compat_ip_setsockopt(struct sock *sk, int level, int optname, |
978 | char __user *optval, int optlen) | 977 | char __user *optval, unsigned int optlen) |
979 | { | 978 | { |
980 | int err; | 979 | int err; |
981 | 980 | ||
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 c43ec2d51ce2..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 | ||
@@ -931,7 +933,7 @@ static void mrtsock_destruct(struct sock *sk) | |||
931 | * MOSPF/PIM router set up we can clean this up. | 933 | * MOSPF/PIM router set up we can clean this up. |
932 | */ | 934 | */ |
933 | 935 | ||
934 | int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen) | 936 | int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen) |
935 | { | 937 | { |
936 | int ret; | 938 | int ret; |
937 | struct vifctl vif; | 939 | struct vifctl vif; |
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 ebb1e5848bc6..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); |
@@ -741,7 +751,7 @@ out: return ret; | |||
741 | } | 751 | } |
742 | 752 | ||
743 | static int do_raw_setsockopt(struct sock *sk, int level, int optname, | 753 | static int do_raw_setsockopt(struct sock *sk, int level, int optname, |
744 | char __user *optval, int optlen) | 754 | char __user *optval, unsigned int optlen) |
745 | { | 755 | { |
746 | if (optname == ICMP_FILTER) { | 756 | if (optname == ICMP_FILTER) { |
747 | if (inet_sk(sk)->num != IPPROTO_ICMP) | 757 | if (inet_sk(sk)->num != IPPROTO_ICMP) |
@@ -753,7 +763,7 @@ static int do_raw_setsockopt(struct sock *sk, int level, int optname, | |||
753 | } | 763 | } |
754 | 764 | ||
755 | static int raw_setsockopt(struct sock *sk, int level, int optname, | 765 | static int raw_setsockopt(struct sock *sk, int level, int optname, |
756 | char __user *optval, int optlen) | 766 | char __user *optval, unsigned int optlen) |
757 | { | 767 | { |
758 | if (level != SOL_RAW) | 768 | if (level != SOL_RAW) |
759 | return ip_setsockopt(sk, level, optname, optval, optlen); | 769 | return ip_setsockopt(sk, level, optname, optval, optlen); |
@@ -762,7 +772,7 @@ static int raw_setsockopt(struct sock *sk, int level, int optname, | |||
762 | 772 | ||
763 | #ifdef CONFIG_COMPAT | 773 | #ifdef CONFIG_COMPAT |
764 | static int compat_raw_setsockopt(struct sock *sk, int level, int optname, | 774 | static int compat_raw_setsockopt(struct sock *sk, int level, int optname, |
765 | char __user *optval, int optlen) | 775 | char __user *optval, unsigned int optlen) |
766 | { | 776 | { |
767 | if (level != SOL_RAW) | 777 | if (level != SOL_RAW) |
768 | return compat_ip_setsockopt(sk, level, optname, optval, optlen); | 778 | return compat_ip_setsockopt(sk, level, optname, optval, optlen); |
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 21387ebabf00..f1813bc71088 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk) | |||
326 | 326 | ||
327 | EXPORT_SYMBOL(tcp_enter_memory_pressure); | 327 | EXPORT_SYMBOL(tcp_enter_memory_pressure); |
328 | 328 | ||
329 | /* Convert seconds to retransmits based on initial and max timeout */ | ||
330 | static u8 secs_to_retrans(int seconds, int timeout, int rto_max) | ||
331 | { | ||
332 | u8 res = 0; | ||
333 | |||
334 | if (seconds > 0) { | ||
335 | int period = timeout; | ||
336 | |||
337 | res = 1; | ||
338 | while (seconds > period && res < 255) { | ||
339 | res++; | ||
340 | timeout <<= 1; | ||
341 | if (timeout > rto_max) | ||
342 | timeout = rto_max; | ||
343 | period += timeout; | ||
344 | } | ||
345 | } | ||
346 | return res; | ||
347 | } | ||
348 | |||
349 | /* Convert retransmits to seconds based on initial and max timeout */ | ||
350 | static int retrans_to_secs(u8 retrans, int timeout, int rto_max) | ||
351 | { | ||
352 | int period = 0; | ||
353 | |||
354 | if (retrans > 0) { | ||
355 | period = timeout; | ||
356 | while (--retrans) { | ||
357 | timeout <<= 1; | ||
358 | if (timeout > rto_max) | ||
359 | timeout = rto_max; | ||
360 | period += timeout; | ||
361 | } | ||
362 | } | ||
363 | return period; | ||
364 | } | ||
365 | |||
329 | /* | 366 | /* |
330 | * Wait for a TCP event. | 367 | * Wait for a TCP event. |
331 | * | 368 | * |
@@ -580,7 +617,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, | |||
580 | 617 | ||
581 | lock_sock(sk); | 618 | lock_sock(sk); |
582 | 619 | ||
583 | timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK); | 620 | timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); |
584 | while (tss.len) { | 621 | while (tss.len) { |
585 | ret = __tcp_splice_read(sk, &tss); | 622 | ret = __tcp_splice_read(sk, &tss); |
586 | if (ret < 0) | 623 | if (ret < 0) |
@@ -1146,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) | |||
1146 | #if TCP_DEBUG | 1183 | #if TCP_DEBUG |
1147 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); | 1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); |
1148 | 1185 | ||
1149 | 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); | ||
1150 | #endif | 1189 | #endif |
1151 | 1190 | ||
1152 | if (inet_csk_ack_scheduled(sk)) { | 1191 | if (inet_csk_ack_scheduled(sk)) { |
@@ -1393,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1393 | /* Now that we have two receive queues this | 1432 | /* Now that we have two receive queues this |
1394 | * shouldn't happen. | 1433 | * shouldn't happen. |
1395 | */ | 1434 | */ |
1396 | if (before(*seq, TCP_SKB_CB(skb)->seq)) { | 1435 | if (WARN(before(*seq, TCP_SKB_CB(skb)->seq), |
1397 | printk(KERN_INFO "recvmsg bug: copied %X " | 1436 | KERN_INFO "recvmsg bug: copied %X " |
1398 | "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)) | ||
1399 | break; | 1440 | break; |
1400 | } | 1441 | |
1401 | offset = *seq - TCP_SKB_CB(skb)->seq; | 1442 | offset = *seq - TCP_SKB_CB(skb)->seq; |
1402 | if (tcp_hdr(skb)->syn) | 1443 | if (tcp_hdr(skb)->syn) |
1403 | offset--; | 1444 | offset--; |
@@ -1405,7 +1446,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1405 | goto found_ok_skb; | 1446 | goto found_ok_skb; |
1406 | if (tcp_hdr(skb)->fin) | 1447 | if (tcp_hdr(skb)->fin) |
1407 | goto found_fin_ok; | 1448 | goto found_fin_ok; |
1408 | WARN_ON(!(flags & MSG_PEEK)); | 1449 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " |
1450 | "copied %X seq %X rcvnxt %X fl %X\n", | ||
1451 | *seq, TCP_SKB_CB(skb)->seq, | ||
1452 | tp->rcv_nxt, flags); | ||
1409 | } | 1453 | } |
1410 | 1454 | ||
1411 | /* Well, if we have backlog, try to process it now yet. */ | 1455 | /* Well, if we have backlog, try to process it now yet. */ |
@@ -2032,7 +2076,7 @@ int tcp_disconnect(struct sock *sk, int flags) | |||
2032 | * Socket option code for TCP. | 2076 | * Socket option code for TCP. |
2033 | */ | 2077 | */ |
2034 | static int do_tcp_setsockopt(struct sock *sk, int level, | 2078 | static int do_tcp_setsockopt(struct sock *sk, int level, |
2035 | int optname, char __user *optval, int optlen) | 2079 | int optname, char __user *optval, unsigned int optlen) |
2036 | { | 2080 | { |
2037 | struct tcp_sock *tp = tcp_sk(sk); | 2081 | struct tcp_sock *tp = tcp_sk(sk); |
2038 | struct inet_connection_sock *icsk = inet_csk(sk); | 2082 | struct inet_connection_sock *icsk = inet_csk(sk); |
@@ -2047,7 +2091,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2047 | return -EINVAL; | 2091 | return -EINVAL; |
2048 | 2092 | ||
2049 | val = strncpy_from_user(name, optval, | 2093 | val = strncpy_from_user(name, optval, |
2050 | min(TCP_CA_NAME_MAX-1, optlen)); | 2094 | min_t(long, TCP_CA_NAME_MAX-1, optlen)); |
2051 | if (val < 0) | 2095 | if (val < 0) |
2052 | return -EFAULT; | 2096 | return -EFAULT; |
2053 | name[val] = 0; | 2097 | name[val] = 0; |
@@ -2163,16 +2207,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2163 | break; | 2207 | break; |
2164 | 2208 | ||
2165 | case TCP_DEFER_ACCEPT: | 2209 | case TCP_DEFER_ACCEPT: |
2166 | icsk->icsk_accept_queue.rskq_defer_accept = 0; | 2210 | /* Translate value in seconds to number of retransmits */ |
2167 | if (val > 0) { | 2211 | icsk->icsk_accept_queue.rskq_defer_accept = |
2168 | /* Translate value in seconds to number of | 2212 | secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, |
2169 | * retransmits */ | 2213 | TCP_RTO_MAX / HZ); |
2170 | while (icsk->icsk_accept_queue.rskq_defer_accept < 32 && | ||
2171 | val > ((TCP_TIMEOUT_INIT / HZ) << | ||
2172 | icsk->icsk_accept_queue.rskq_defer_accept)) | ||
2173 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
2174 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
2175 | } | ||
2176 | break; | 2214 | break; |
2177 | 2215 | ||
2178 | case TCP_WINDOW_CLAMP: | 2216 | case TCP_WINDOW_CLAMP: |
@@ -2220,7 +2258,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2220 | } | 2258 | } |
2221 | 2259 | ||
2222 | int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | 2260 | int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, |
2223 | int optlen) | 2261 | unsigned int optlen) |
2224 | { | 2262 | { |
2225 | struct inet_connection_sock *icsk = inet_csk(sk); | 2263 | struct inet_connection_sock *icsk = inet_csk(sk); |
2226 | 2264 | ||
@@ -2232,7 +2270,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
2232 | 2270 | ||
2233 | #ifdef CONFIG_COMPAT | 2271 | #ifdef CONFIG_COMPAT |
2234 | int compat_tcp_setsockopt(struct sock *sk, int level, int optname, | 2272 | int compat_tcp_setsockopt(struct sock *sk, int level, int optname, |
2235 | char __user *optval, int optlen) | 2273 | char __user *optval, unsigned int optlen) |
2236 | { | 2274 | { |
2237 | if (level != SOL_TCP) | 2275 | if (level != SOL_TCP) |
2238 | return inet_csk_compat_setsockopt(sk, level, optname, | 2276 | return inet_csk_compat_setsockopt(sk, level, optname, |
@@ -2353,8 +2391,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
2353 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; | 2391 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; |
2354 | break; | 2392 | break; |
2355 | case TCP_DEFER_ACCEPT: | 2393 | case TCP_DEFER_ACCEPT: |
2356 | val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : | 2394 | val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, |
2357 | ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); | 2395 | TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); |
2358 | break; | 2396 | break; |
2359 | case TCP_WINDOW_CLAMP: | 2397 | case TCP_WINDOW_CLAMP: |
2360 | val = tp->window_clamp; | 2398 | val = tp->window_clamp; |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 624c3c9b3c2b..4c03598ed924 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -641,8 +641,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
641 | if (!(flg & TCP_FLAG_ACK)) | 641 | if (!(flg & TCP_FLAG_ACK)) |
642 | return NULL; | 642 | return NULL; |
643 | 643 | ||
644 | /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ | 644 | /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */ |
645 | if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && | 645 | if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && |
646 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { | 646 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { |
647 | inet_rsk(req)->acked = 1; | 647 | inet_rsk(req)->acked = 1; |
648 | return NULL; | 648 | return NULL; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5200aab0ca97..fcd278a7080e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -361,6 +361,7 @@ static inline int tcp_urg_mode(const struct tcp_sock *tp) | |||
361 | #define OPTION_SACK_ADVERTISE (1 << 0) | 361 | #define OPTION_SACK_ADVERTISE (1 << 0) |
362 | #define OPTION_TS (1 << 1) | 362 | #define OPTION_TS (1 << 1) |
363 | #define OPTION_MD5 (1 << 2) | 363 | #define OPTION_MD5 (1 << 2) |
364 | #define OPTION_WSCALE (1 << 3) | ||
364 | 365 | ||
365 | struct tcp_out_options { | 366 | struct tcp_out_options { |
366 | u8 options; /* bit field of OPTION_* */ | 367 | u8 options; /* bit field of OPTION_* */ |
@@ -427,7 +428,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
427 | TCPOLEN_SACK_PERM); | 428 | TCPOLEN_SACK_PERM); |
428 | } | 429 | } |
429 | 430 | ||
430 | if (unlikely(opts->ws)) { | 431 | if (unlikely(OPTION_WSCALE & opts->options)) { |
431 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 432 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
432 | (TCPOPT_WINDOW << 16) | | 433 | (TCPOPT_WINDOW << 16) | |
433 | (TCPOLEN_WINDOW << 8) | | 434 | (TCPOLEN_WINDOW << 8) | |
@@ -494,8 +495,8 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb, | |||
494 | } | 495 | } |
495 | if (likely(sysctl_tcp_window_scaling)) { | 496 | if (likely(sysctl_tcp_window_scaling)) { |
496 | opts->ws = tp->rx_opt.rcv_wscale; | 497 | opts->ws = tp->rx_opt.rcv_wscale; |
497 | if (likely(opts->ws)) | 498 | opts->options |= OPTION_WSCALE; |
498 | size += TCPOLEN_WSCALE_ALIGNED; | 499 | size += TCPOLEN_WSCALE_ALIGNED; |
499 | } | 500 | } |
500 | if (likely(sysctl_tcp_sack)) { | 501 | if (likely(sysctl_tcp_sack)) { |
501 | opts->options |= OPTION_SACK_ADVERTISE; | 502 | opts->options |= OPTION_SACK_ADVERTISE; |
@@ -537,8 +538,8 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
537 | 538 | ||
538 | if (likely(ireq->wscale_ok)) { | 539 | if (likely(ireq->wscale_ok)) { |
539 | opts->ws = ireq->rcv_wscale; | 540 | opts->ws = ireq->rcv_wscale; |
540 | if (likely(opts->ws)) | 541 | opts->options |= OPTION_WSCALE; |
541 | size += TCPOLEN_WSCALE_ALIGNED; | 542 | size += TCPOLEN_WSCALE_ALIGNED; |
542 | } | 543 | } |
543 | if (likely(doing_ts)) { | 544 | if (likely(doing_ts)) { |
544 | opts->options |= OPTION_TS; | 545 | opts->options |= OPTION_TS; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ebaaa7f973d7..0fa9f70e4b19 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -696,6 +696,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
696 | 696 | ||
697 | if (rt == NULL) { | 697 | if (rt == NULL) { |
698 | struct flowi fl = { .oif = ipc.oif, | 698 | struct flowi fl = { .oif = ipc.oif, |
699 | .mark = sk->sk_mark, | ||
699 | .nl_u = { .ip4_u = | 700 | .nl_u = { .ip4_u = |
700 | { .daddr = faddr, | 701 | { .daddr = faddr, |
701 | .saddr = saddr, | 702 | .saddr = saddr, |
@@ -840,6 +841,42 @@ out: | |||
840 | return ret; | 841 | return ret; |
841 | } | 842 | } |
842 | 843 | ||
844 | |||
845 | /** | ||
846 | * first_packet_length - return length of first packet in receive queue | ||
847 | * @sk: socket | ||
848 | * | ||
849 | * Drops all bad checksum frames, until a valid one is found. | ||
850 | * Returns the length of found skb, or 0 if none is found. | ||
851 | */ | ||
852 | static unsigned int first_packet_length(struct sock *sk) | ||
853 | { | ||
854 | struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue; | ||
855 | struct sk_buff *skb; | ||
856 | unsigned int res; | ||
857 | |||
858 | __skb_queue_head_init(&list_kill); | ||
859 | |||
860 | spin_lock_bh(&rcvq->lock); | ||
861 | while ((skb = skb_peek(rcvq)) != NULL && | ||
862 | udp_lib_checksum_complete(skb)) { | ||
863 | UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, | ||
864 | IS_UDPLITE(sk)); | ||
865 | __skb_unlink(skb, rcvq); | ||
866 | __skb_queue_tail(&list_kill, skb); | ||
867 | } | ||
868 | res = skb ? skb->len : 0; | ||
869 | spin_unlock_bh(&rcvq->lock); | ||
870 | |||
871 | if (!skb_queue_empty(&list_kill)) { | ||
872 | lock_sock(sk); | ||
873 | __skb_queue_purge(&list_kill); | ||
874 | sk_mem_reclaim_partial(sk); | ||
875 | release_sock(sk); | ||
876 | } | ||
877 | return res; | ||
878 | } | ||
879 | |||
843 | /* | 880 | /* |
844 | * IOCTL requests applicable to the UDP protocol | 881 | * IOCTL requests applicable to the UDP protocol |
845 | */ | 882 | */ |
@@ -856,21 +893,16 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
856 | 893 | ||
857 | case SIOCINQ: | 894 | case SIOCINQ: |
858 | { | 895 | { |
859 | struct sk_buff *skb; | 896 | unsigned int amount = first_packet_length(sk); |
860 | unsigned long amount; | ||
861 | 897 | ||
862 | amount = 0; | 898 | if (amount) |
863 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
864 | skb = skb_peek(&sk->sk_receive_queue); | ||
865 | if (skb != NULL) { | ||
866 | /* | 899 | /* |
867 | * We will only return the amount | 900 | * We will only return the amount |
868 | * of this packet since that is all | 901 | * of this packet since that is all |
869 | * that will be read. | 902 | * that will be read. |
870 | */ | 903 | */ |
871 | amount = skb->len - sizeof(struct udphdr); | 904 | amount -= sizeof(struct udphdr); |
872 | } | 905 | |
873 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
874 | return put_user(amount, (int __user *)arg); | 906 | return put_user(amount, (int __user *)arg); |
875 | } | 907 | } |
876 | 908 | ||
@@ -967,9 +999,7 @@ try_again: | |||
967 | err = ulen; | 999 | err = ulen; |
968 | 1000 | ||
969 | out_free: | 1001 | out_free: |
970 | lock_sock(sk); | 1002 | skb_free_datagram_locked(sk, skb); |
971 | skb_free_datagram(sk, skb); | ||
972 | release_sock(sk); | ||
973 | out: | 1003 | out: |
974 | return err; | 1004 | return err; |
975 | 1005 | ||
@@ -1359,7 +1389,7 @@ void udp_destroy_sock(struct sock *sk) | |||
1359 | * Socket option code for UDP | 1389 | * Socket option code for UDP |
1360 | */ | 1390 | */ |
1361 | int udp_lib_setsockopt(struct sock *sk, int level, int optname, | 1391 | int udp_lib_setsockopt(struct sock *sk, int level, int optname, |
1362 | char __user *optval, int optlen, | 1392 | char __user *optval, unsigned int optlen, |
1363 | int (*push_pending_frames)(struct sock *)) | 1393 | int (*push_pending_frames)(struct sock *)) |
1364 | { | 1394 | { |
1365 | struct udp_sock *up = udp_sk(sk); | 1395 | struct udp_sock *up = udp_sk(sk); |
@@ -1441,7 +1471,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
1441 | EXPORT_SYMBOL(udp_lib_setsockopt); | 1471 | EXPORT_SYMBOL(udp_lib_setsockopt); |
1442 | 1472 | ||
1443 | int udp_setsockopt(struct sock *sk, int level, int optname, | 1473 | int udp_setsockopt(struct sock *sk, int level, int optname, |
1444 | char __user *optval, int optlen) | 1474 | char __user *optval, unsigned int optlen) |
1445 | { | 1475 | { |
1446 | if (level == SOL_UDP || level == SOL_UDPLITE) | 1476 | if (level == SOL_UDP || level == SOL_UDPLITE) |
1447 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, | 1477 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, |
@@ -1451,7 +1481,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname, | |||
1451 | 1481 | ||
1452 | #ifdef CONFIG_COMPAT | 1482 | #ifdef CONFIG_COMPAT |
1453 | int compat_udp_setsockopt(struct sock *sk, int level, int optname, | 1483 | int compat_udp_setsockopt(struct sock *sk, int level, int optname, |
1454 | char __user *optval, int optlen) | 1484 | char __user *optval, unsigned int optlen) |
1455 | { | 1485 | { |
1456 | if (level == SOL_UDP || level == SOL_UDPLITE) | 1486 | if (level == SOL_UDP || level == SOL_UDPLITE) |
1457 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, | 1487 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, |
@@ -1539,29 +1569,11 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
1539 | { | 1569 | { |
1540 | unsigned int mask = datagram_poll(file, sock, wait); | 1570 | unsigned int mask = datagram_poll(file, sock, wait); |
1541 | struct sock *sk = sock->sk; | 1571 | struct sock *sk = sock->sk; |
1542 | int is_lite = IS_UDPLITE(sk); | ||
1543 | 1572 | ||
1544 | /* Check for false positives due to checksum errors */ | 1573 | /* Check for false positives due to checksum errors */ |
1545 | if ((mask & POLLRDNORM) && | 1574 | if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) && |
1546 | !(file->f_flags & O_NONBLOCK) && | 1575 | !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk)) |
1547 | !(sk->sk_shutdown & RCV_SHUTDOWN)) { | 1576 | mask &= ~(POLLIN | POLLRDNORM); |
1548 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; | ||
1549 | struct sk_buff *skb; | ||
1550 | |||
1551 | spin_lock_bh(&rcvq->lock); | ||
1552 | while ((skb = skb_peek(rcvq)) != NULL && | ||
1553 | udp_lib_checksum_complete(skb)) { | ||
1554 | UDP_INC_STATS_BH(sock_net(sk), | ||
1555 | UDP_MIB_INERRORS, is_lite); | ||
1556 | __skb_unlink(skb, rcvq); | ||
1557 | kfree_skb(skb); | ||
1558 | } | ||
1559 | spin_unlock_bh(&rcvq->lock); | ||
1560 | |||
1561 | /* nothing to see, move along */ | ||
1562 | if (skb == NULL) | ||
1563 | mask &= ~(POLLIN | POLLRDNORM); | ||
1564 | } | ||
1565 | 1577 | ||
1566 | return mask; | 1578 | return mask; |
1567 | 1579 | ||
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index 9f4a6165f722..aaad650d47d9 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h | |||
@@ -11,13 +11,13 @@ extern void __udp4_lib_err(struct sk_buff *, u32, struct udp_table *); | |||
11 | extern int udp_v4_get_port(struct sock *sk, unsigned short snum); | 11 | extern int udp_v4_get_port(struct sock *sk, unsigned short snum); |
12 | 12 | ||
13 | extern int udp_setsockopt(struct sock *sk, int level, int optname, | 13 | extern int udp_setsockopt(struct sock *sk, int level, int optname, |
14 | char __user *optval, int optlen); | 14 | char __user *optval, unsigned int optlen); |
15 | extern int udp_getsockopt(struct sock *sk, int level, int optname, | 15 | extern int udp_getsockopt(struct sock *sk, int level, int optname, |
16 | char __user *optval, int __user *optlen); | 16 | char __user *optval, int __user *optlen); |
17 | 17 | ||
18 | #ifdef CONFIG_COMPAT | 18 | #ifdef CONFIG_COMPAT |
19 | extern int compat_udp_setsockopt(struct sock *sk, int level, int optname, | 19 | extern int compat_udp_setsockopt(struct sock *sk, int level, int optname, |
20 | char __user *optval, int optlen); | 20 | char __user *optval, unsigned int optlen); |
21 | extern int compat_udp_getsockopt(struct sock *sk, int level, int optname, | 21 | extern int compat_udp_getsockopt(struct sock *sk, int level, int optname, |
22 | char __user *optval, int __user *optlen); | 22 | char __user *optval, int __user *optlen); |
23 | #endif | 23 | #endif |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 090675e269ee..716153941fc4 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1281,7 +1281,7 @@ int ip6mr_sk_done(struct sock *sk) | |||
1281 | * MOSPF/PIM router set up we can clean this up. | 1281 | * MOSPF/PIM router set up we can clean this up. |
1282 | */ | 1282 | */ |
1283 | 1283 | ||
1284 | int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen) | 1284 | int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen) |
1285 | { | 1285 | { |
1286 | int ret; | 1286 | int ret; |
1287 | struct mif6ctl vif; | 1287 | struct mif6ctl vif; |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index f5e0682b402d..4f7aaf6996a3 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -123,7 +123,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, | |||
123 | } | 123 | } |
124 | 124 | ||
125 | static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | 125 | static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, |
126 | char __user *optval, int optlen) | 126 | char __user *optval, unsigned int optlen) |
127 | { | 127 | { |
128 | struct ipv6_pinfo *np = inet6_sk(sk); | 128 | struct ipv6_pinfo *np = inet6_sk(sk); |
129 | struct net *net = sock_net(sk); | 129 | struct net *net = sock_net(sk); |
@@ -496,13 +496,17 @@ done: | |||
496 | goto e_inval; | 496 | goto e_inval; |
497 | 497 | ||
498 | if (val) { | 498 | if (val) { |
499 | struct net_device *dev; | ||
500 | |||
499 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) | 501 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) |
500 | goto e_inval; | 502 | goto e_inval; |
501 | 503 | ||
502 | if (__dev_get_by_index(net, val) == NULL) { | 504 | dev = dev_get_by_index(net, val); |
505 | if (!dev) { | ||
503 | retv = -ENODEV; | 506 | retv = -ENODEV; |
504 | break; | 507 | break; |
505 | } | 508 | } |
509 | dev_put(dev); | ||
506 | } | 510 | } |
507 | np->mcast_oif = val; | 511 | np->mcast_oif = val; |
508 | retv = 0; | 512 | retv = 0; |
@@ -773,7 +777,7 @@ e_inval: | |||
773 | } | 777 | } |
774 | 778 | ||
775 | int ipv6_setsockopt(struct sock *sk, int level, int optname, | 779 | int ipv6_setsockopt(struct sock *sk, int level, int optname, |
776 | char __user *optval, int optlen) | 780 | char __user *optval, unsigned int optlen) |
777 | { | 781 | { |
778 | int err; | 782 | int err; |
779 | 783 | ||
@@ -801,7 +805,7 @@ EXPORT_SYMBOL(ipv6_setsockopt); | |||
801 | 805 | ||
802 | #ifdef CONFIG_COMPAT | 806 | #ifdef CONFIG_COMPAT |
803 | int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, | 807 | int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, |
804 | char __user *optval, int optlen) | 808 | char __user *optval, unsigned int optlen) |
805 | { | 809 | { |
806 | int err; | 810 | int err; |
807 | 811 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 498b9b0b0fad..f74e4e2cdd06 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -658,7 +658,6 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, | |||
658 | &icmp6h, NULL, | 658 | &icmp6h, NULL, |
659 | send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0); | 659 | send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0); |
660 | } | 660 | } |
661 | EXPORT_SYMBOL(ndisc_send_rs); | ||
662 | 661 | ||
663 | 662 | ||
664 | static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb) | 663 | static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb) |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 7d675b8d82d3..4f24570b0869 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -957,7 +957,7 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, | |||
957 | 957 | ||
958 | 958 | ||
959 | static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, | 959 | static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, |
960 | char __user *optval, int optlen) | 960 | char __user *optval, unsigned int optlen) |
961 | { | 961 | { |
962 | struct raw6_sock *rp = raw6_sk(sk); | 962 | struct raw6_sock *rp = raw6_sk(sk); |
963 | int val; | 963 | int val; |
@@ -1000,7 +1000,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, | |||
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | static int rawv6_setsockopt(struct sock *sk, int level, int optname, | 1002 | static int rawv6_setsockopt(struct sock *sk, int level, int optname, |
1003 | char __user *optval, int optlen) | 1003 | char __user *optval, unsigned int optlen) |
1004 | { | 1004 | { |
1005 | switch(level) { | 1005 | switch(level) { |
1006 | case SOL_RAW: | 1006 | case SOL_RAW: |
@@ -1024,7 +1024,7 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname, | |||
1024 | 1024 | ||
1025 | #ifdef CONFIG_COMPAT | 1025 | #ifdef CONFIG_COMPAT |
1026 | static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, | 1026 | static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, |
1027 | char __user *optval, int optlen) | 1027 | char __user *optval, unsigned int optlen) |
1028 | { | 1028 | { |
1029 | switch (level) { | 1029 | switch (level) { |
1030 | case SOL_RAW: | 1030 | case SOL_RAW: |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index fcb539628847..dbd19a78ca73 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * Roger Venning <r.venning@telstra.com>: 6to4 support | 15 | * Roger Venning <r.venning@telstra.com>: 6to4 support |
16 | * Nate Thompson <nate@thebog.net>: 6to4 support | 16 | * Nate Thompson <nate@thebog.net>: 6to4 support |
17 | * Fred Templin <fred.l.templin@boeing.com>: isatap support | 17 | * Fred Templin <fred.l.templin@boeing.com>: isatap support |
18 | * Sascha Hlusiak <mail@saschahlusiak.de>: stateless autoconf for isatap | ||
19 | */ | 18 | */ |
20 | 19 | ||
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -223,44 +222,6 @@ failed: | |||
223 | return NULL; | 222 | return NULL; |
224 | } | 223 | } |
225 | 224 | ||
226 | static void ipip6_tunnel_rs_timer(unsigned long data) | ||
227 | { | ||
228 | struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *) data; | ||
229 | struct inet6_dev *ifp; | ||
230 | struct inet6_ifaddr *addr; | ||
231 | |||
232 | spin_lock(&p->lock); | ||
233 | ifp = __in6_dev_get(p->tunnel->dev); | ||
234 | |||
235 | read_lock_bh(&ifp->lock); | ||
236 | for (addr = ifp->addr_list; addr; addr = addr->if_next) { | ||
237 | struct in6_addr rtr; | ||
238 | |||
239 | if (!(ipv6_addr_type(&addr->addr) & IPV6_ADDR_LINKLOCAL)) | ||
240 | continue; | ||
241 | |||
242 | /* Send RS to guessed linklocal address of router | ||
243 | * | ||
244 | * Better: send to ff02::2 encapsuled in unicast directly | ||
245 | * to router-v4 instead of guessing the v6 address. | ||
246 | * | ||
247 | * Cisco/Windows seem to not set the u/l bit correctly, | ||
248 | * so we won't guess right. | ||
249 | */ | ||
250 | ipv6_addr_set(&rtr, htonl(0xFE800000), 0, 0, 0); | ||
251 | if (!__ipv6_isatap_ifid(rtr.s6_addr + 8, | ||
252 | p->addr)) { | ||
253 | ndisc_send_rs(p->tunnel->dev, &addr->addr, &rtr); | ||
254 | } | ||
255 | } | ||
256 | read_unlock_bh(&ifp->lock); | ||
257 | |||
258 | mod_timer(&p->rs_timer, jiffies + HZ * p->rs_delay); | ||
259 | spin_unlock(&p->lock); | ||
260 | |||
261 | return; | ||
262 | } | ||
263 | |||
264 | static struct ip_tunnel_prl_entry * | 225 | static struct ip_tunnel_prl_entry * |
265 | __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) | 226 | __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) |
266 | { | 227 | { |
@@ -313,13 +274,12 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t, | |||
313 | 274 | ||
314 | c = 0; | 275 | c = 0; |
315 | for (prl = t->prl; prl; prl = prl->next) { | 276 | for (prl = t->prl; prl; prl = prl->next) { |
316 | if (c > cmax) | 277 | if (c >= cmax) |
317 | break; | 278 | break; |
318 | if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) | 279 | if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) |
319 | continue; | 280 | continue; |
320 | kp[c].addr = prl->addr; | 281 | kp[c].addr = prl->addr; |
321 | kp[c].flags = prl->flags; | 282 | kp[c].flags = prl->flags; |
322 | kp[c].rs_delay = prl->rs_delay; | ||
323 | c++; | 283 | c++; |
324 | if (kprl.addr != htonl(INADDR_ANY)) | 284 | if (kprl.addr != htonl(INADDR_ANY)) |
325 | break; | 285 | break; |
@@ -369,23 +329,11 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) | |||
369 | } | 329 | } |
370 | 330 | ||
371 | p->next = t->prl; | 331 | p->next = t->prl; |
372 | p->tunnel = t; | ||
373 | t->prl = p; | 332 | t->prl = p; |
374 | t->prl_count++; | 333 | t->prl_count++; |
375 | |||
376 | spin_lock_init(&p->lock); | ||
377 | setup_timer(&p->rs_timer, ipip6_tunnel_rs_timer, (unsigned long) p); | ||
378 | update: | 334 | update: |
379 | p->addr = a->addr; | 335 | p->addr = a->addr; |
380 | p->flags = a->flags; | 336 | p->flags = a->flags; |
381 | p->rs_delay = a->rs_delay; | ||
382 | if (p->rs_delay == 0) | ||
383 | p->rs_delay = IPTUNNEL_RS_DEFAULT_DELAY; | ||
384 | spin_lock(&p->lock); | ||
385 | del_timer(&p->rs_timer); | ||
386 | if (p->flags & PRL_DEFAULT) | ||
387 | mod_timer(&p->rs_timer, jiffies + 1); | ||
388 | spin_unlock(&p->lock); | ||
389 | out: | 337 | out: |
390 | write_unlock(&ipip6_lock); | 338 | write_unlock(&ipip6_lock); |
391 | return err; | 339 | return err; |
@@ -404,9 +352,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) | |||
404 | if ((*p)->addr == a->addr) { | 352 | if ((*p)->addr == a->addr) { |
405 | x = *p; | 353 | x = *p; |
406 | *p = x->next; | 354 | *p = x->next; |
407 | spin_lock(&x->lock); | ||
408 | del_timer(&x->rs_timer); | ||
409 | spin_unlock(&x->lock); | ||
410 | kfree(x); | 355 | kfree(x); |
411 | t->prl_count--; | 356 | t->prl_count--; |
412 | goto out; | 357 | goto out; |
@@ -417,9 +362,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) | |||
417 | while (t->prl) { | 362 | while (t->prl) { |
418 | x = t->prl; | 363 | x = t->prl; |
419 | t->prl = t->prl->next; | 364 | t->prl = t->prl->next; |
420 | spin_lock(&x->lock); | ||
421 | del_timer(&x->rs_timer); | ||
422 | spin_unlock(&x->lock); | ||
423 | kfree(x); | 365 | kfree(x); |
424 | t->prl_count--; | 366 | t->prl_count--; |
425 | } | 367 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b265b7047d3e..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 | ||
@@ -1044,7 +1042,7 @@ void udpv6_destroy_sock(struct sock *sk) | |||
1044 | * Socket option code for UDP | 1042 | * Socket option code for UDP |
1045 | */ | 1043 | */ |
1046 | int udpv6_setsockopt(struct sock *sk, int level, int optname, | 1044 | int udpv6_setsockopt(struct sock *sk, int level, int optname, |
1047 | char __user *optval, int optlen) | 1045 | char __user *optval, unsigned int optlen) |
1048 | { | 1046 | { |
1049 | if (level == SOL_UDP || level == SOL_UDPLITE) | 1047 | if (level == SOL_UDP || level == SOL_UDPLITE) |
1050 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, | 1048 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, |
@@ -1054,7 +1052,7 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname, | |||
1054 | 1052 | ||
1055 | #ifdef CONFIG_COMPAT | 1053 | #ifdef CONFIG_COMPAT |
1056 | int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, | 1054 | int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, |
1057 | char __user *optval, int optlen) | 1055 | char __user *optval, unsigned int optlen) |
1058 | { | 1056 | { |
1059 | if (level == SOL_UDP || level == SOL_UDPLITE) | 1057 | if (level == SOL_UDP || level == SOL_UDPLITE) |
1060 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, | 1058 | return udp_lib_setsockopt(sk, level, optname, optval, optlen, |
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 6bb303471e20..d7571046bfc4 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h | |||
@@ -16,10 +16,10 @@ extern int udp_v6_get_port(struct sock *sk, unsigned short snum); | |||
16 | extern int udpv6_getsockopt(struct sock *sk, int level, int optname, | 16 | extern int udpv6_getsockopt(struct sock *sk, int level, int optname, |
17 | char __user *optval, int __user *optlen); | 17 | char __user *optval, int __user *optlen); |
18 | extern int udpv6_setsockopt(struct sock *sk, int level, int optname, | 18 | extern int udpv6_setsockopt(struct sock *sk, int level, int optname, |
19 | char __user *optval, int optlen); | 19 | char __user *optval, unsigned int optlen); |
20 | #ifdef CONFIG_COMPAT | 20 | #ifdef CONFIG_COMPAT |
21 | extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, | 21 | extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, |
22 | char __user *optval, int optlen); | 22 | char __user *optval, unsigned int optlen); |
23 | extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, | 23 | extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, |
24 | char __user *optval, int __user *optlen); | 24 | char __user *optval, int __user *optlen); |
25 | #endif | 25 | #endif |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index f1118d92a191..66c7a20011f3 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1292,7 +1292,7 @@ const char *ipx_device_name(struct ipx_interface *intrfc) | |||
1292 | * socket object. */ | 1292 | * socket object. */ |
1293 | 1293 | ||
1294 | static int ipx_setsockopt(struct socket *sock, int level, int optname, | 1294 | static int ipx_setsockopt(struct socket *sock, int level, int optname, |
1295 | char __user *optval, int optlen) | 1295 | char __user *optval, unsigned int optlen) |
1296 | { | 1296 | { |
1297 | struct sock *sk = sock->sk; | 1297 | struct sock *sk = sock->sk; |
1298 | int opt; | 1298 | int opt; |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 50b43c57d5d8..dd35641835f4 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -1826,7 +1826,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon | |||
1826 | * | 1826 | * |
1827 | */ | 1827 | */ |
1828 | static int irda_setsockopt(struct socket *sock, int level, int optname, | 1828 | static int irda_setsockopt(struct socket *sock, int level, int optname, |
1829 | char __user *optval, int optlen) | 1829 | char __user *optval, unsigned int optlen) |
1830 | { | 1830 | { |
1831 | struct sock *sk = sock->sk; | 1831 | struct sock *sk = sock->sk; |
1832 | struct irda_sock *self = irda_sk(sk); | 1832 | struct irda_sock *self = irda_sk(sk); |
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index eafc010907c2..3c1754023022 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c | |||
@@ -30,6 +30,7 @@ | |||
30 | ********************************************************************/ | 30 | ********************************************************************/ |
31 | 31 | ||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | ||
33 | 34 | ||
34 | #include <net/irda/irda.h> | 35 | #include <net/irda/irda.h> |
35 | #include <net/irda/irlmp.h> | 36 | #include <net/irda/irlmp.h> |
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index 62116829b817..315ead3cb926 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/sched.h> | ||
33 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
34 | #include <linux/random.h> | 35 | #include <linux/random.h> |
35 | #include <linux/netdevice.h> | 36 | #include <linux/netdevice.h> |
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index 7b6b631f647f..d340110f5c0c 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/inetdevice.h> | 30 | #include <linux/inetdevice.h> |
31 | #include <linux/if_arp.h> | 31 | #include <linux/if_arp.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/sched.h> | ||
33 | #include <net/arp.h> | 34 | #include <net/arp.h> |
34 | 35 | ||
35 | #include <net/irda/irda.h> | 36 | #include <net/irda/irda.h> |
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c index cf9a4b531a98..cccc2e93234f 100644 --- a/net/irda/irnet/irnet_irda.c +++ b/net/irda/irnet/irnet_irda.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include "irnet_irda.h" /* Private header */ | 11 | #include "irnet_irda.h" /* Private header */ |
12 | #include <linux/sched.h> | ||
12 | #include <linux/seq_file.h> | 13 | #include <linux/seq_file.h> |
13 | #include <asm/unaligned.h> | 14 | #include <asm/unaligned.h> |
14 | 15 | ||
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index 68cbcb19cbd8..7dea882dbb75 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * 2) as a control channel (write commands, read events) | 13 | * 2) as a control channel (write commands, read events) |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/sched.h> | ||
16 | #include <linux/smp_lock.h> | 17 | #include <linux/smp_lock.h> |
17 | #include "irnet_ppp.h" /* Private header */ | 18 | #include "irnet_ppp.h" /* Private header */ |
18 | /* Please put other headers in irnet.h - Thanks */ | 19 | /* Please put other headers in irnet.h - Thanks */ |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index d985d163dcfc..bada1b9c670b 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1387,7 +1387,7 @@ static int iucv_sock_release(struct socket *sock) | |||
1387 | 1387 | ||
1388 | /* getsockopt and setsockopt */ | 1388 | /* getsockopt and setsockopt */ |
1389 | static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, | 1389 | static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, |
1390 | char __user *optval, int optlen) | 1390 | char __user *optval, unsigned int optlen) |
1391 | { | 1391 | { |
1392 | struct sock *sk = sock->sk; | 1392 | struct sock *sk = sock->sk; |
1393 | struct iucv_sock *iucv = iucv_sk(sk); | 1393 | struct iucv_sock *iucv = iucv_sk(sk); |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index c45eee1c0e8d..7aa4fd170104 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -973,7 +973,7 @@ static int llc_ui_ioctl(struct socket *sock, unsigned int cmd, | |||
973 | * Set various connection specific parameters. | 973 | * Set various connection specific parameters. |
974 | */ | 974 | */ |
975 | static int llc_ui_setsockopt(struct socket *sock, int level, int optname, | 975 | static int llc_ui_setsockopt(struct socket *sock, int level, int optname, |
976 | char __user *optval, int optlen) | 976 | char __user *optval, unsigned int optlen) |
977 | { | 977 | { |
978 | struct sock *sk = sock->sk; | 978 | struct sock *sk = sock->sk; |
979 | struct llc_sock *llc = llc_sk(sk); | 979 | struct llc_sock *llc = llc_sk(sk); |
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 920ec8792f4b..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"); |
@@ -829,7 +829,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) | |||
829 | if (!sdata->u.ibss.ssid_len) | 829 | if (!sdata->u.ibss.ssid_len) |
830 | continue; | 830 | continue; |
831 | sdata->u.ibss.last_scan_completed = jiffies; | 831 | sdata->u.ibss.last_scan_completed = jiffies; |
832 | ieee80211_sta_find_ibss(sdata); | 832 | mod_timer(&sdata->u.ibss.timer, 0); |
833 | } | 833 | } |
834 | mutex_unlock(&local->iflist_mtx); | 834 | mutex_unlock(&local->iflist_mtx); |
835 | } | 835 | } |
diff --git a/net/mac80211/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 97a278a2f48e..dc5049d58c51 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1388,8 +1388,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1388 | 1388 | ||
1389 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1389 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1390 | 1390 | ||
1391 | printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", | 1391 | printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", |
1392 | sdata->dev->name, reason_code); | 1392 | sdata->dev->name, mgmt->sa, reason_code); |
1393 | 1393 | ||
1394 | ieee80211_set_disassoc(sdata, false); | 1394 | ieee80211_set_disassoc(sdata, false); |
1395 | return RX_MGMT_CFG80211_DISASSOC; | 1395 | return RX_MGMT_CFG80211_DISASSOC; |
@@ -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 | ||
@@ -1675,7 +1674,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1675 | 1674 | ||
1676 | /* direct probe may be part of the association flow */ | 1675 | /* direct probe may be part of the association flow */ |
1677 | if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) { | 1676 | if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) { |
1678 | printk(KERN_DEBUG "%s direct probe responded\n", | 1677 | printk(KERN_DEBUG "%s: direct probe responded\n", |
1679 | sdata->dev->name); | 1678 | sdata->dev->name); |
1680 | wk->tries = 0; | 1679 | wk->tries = 0; |
1681 | wk->state = IEEE80211_MGD_STATE_AUTH; | 1680 | wk->state = IEEE80211_MGD_STATE_AUTH; |
@@ -2502,9 +2501,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2502 | struct ieee80211_mgd_work *wk; | 2501 | struct ieee80211_mgd_work *wk; |
2503 | const u8 *bssid = NULL; | 2502 | const u8 *bssid = NULL; |
2504 | 2503 | ||
2505 | printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", | ||
2506 | sdata->dev->name, req->reason_code); | ||
2507 | |||
2508 | mutex_lock(&ifmgd->mtx); | 2504 | mutex_lock(&ifmgd->mtx); |
2509 | 2505 | ||
2510 | if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { | 2506 | if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { |
@@ -2532,6 +2528,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2532 | 2528 | ||
2533 | mutex_unlock(&ifmgd->mtx); | 2529 | mutex_unlock(&ifmgd->mtx); |
2534 | 2530 | ||
2531 | printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", | ||
2532 | sdata->dev->name, bssid, req->reason_code); | ||
2533 | |||
2535 | ieee80211_send_deauth_disassoc(sdata, bssid, | 2534 | ieee80211_send_deauth_disassoc(sdata, bssid, |
2536 | IEEE80211_STYPE_DEAUTH, req->reason_code, | 2535 | IEEE80211_STYPE_DEAUTH, req->reason_code, |
2537 | cookie); | 2536 | cookie); |
@@ -2545,9 +2544,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2545 | { | 2544 | { |
2546 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2545 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2547 | 2546 | ||
2548 | printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", | ||
2549 | sdata->dev->name, req->reason_code); | ||
2550 | |||
2551 | mutex_lock(&ifmgd->mtx); | 2547 | mutex_lock(&ifmgd->mtx); |
2552 | 2548 | ||
2553 | /* | 2549 | /* |
@@ -2561,6 +2557,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2561 | return -ENOLINK; | 2557 | return -ENOLINK; |
2562 | } | 2558 | } |
2563 | 2559 | ||
2560 | printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", | ||
2561 | sdata->dev->name, req->bss->bssid, req->reason_code); | ||
2562 | |||
2564 | ieee80211_set_disassoc(sdata, false); | 2563 | ieee80211_set_disassoc(sdata, false); |
2565 | 2564 | ||
2566 | mutex_unlock(&ifmgd->mtx); | 2565 | mutex_unlock(&ifmgd->mtx); |
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index a59043fbb0ff..45667054a5f3 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/sched.h> | ||
9 | #include <linux/spinlock.h> | 10 | #include <linux/spinlock.h> |
10 | #include <linux/poll.h> | 11 | #include <linux/poll.h> |
11 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c01588f9d453..7170bf4565a8 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2164,11 +2164,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2164 | 2164 | ||
2165 | skb = rx.skb; | 2165 | skb = rx.skb; |
2166 | 2166 | ||
2167 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 2167 | if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { |
2168 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
2169 | prepares = prepare_for_handlers(rx.sdata, &rx, hdr); | ||
2170 | if (prepares) | ||
2171 | prev = rx.sdata; | ||
2172 | } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
2168 | if (!netif_running(sdata->dev)) | 2173 | if (!netif_running(sdata->dev)) |
2169 | continue; | 2174 | continue; |
2170 | 2175 | ||
2171 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | 2176 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
2177 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
2172 | continue; | 2178 | continue; |
2173 | 2179 | ||
2174 | rx.flags |= IEEE80211_RX_RA_MATCH; | 2180 | rx.flags |= IEEE80211_RX_RA_MATCH; |
@@ -2447,6 +2453,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2447 | struct ieee80211_supported_band *sband; | 2453 | struct ieee80211_supported_band *sband; |
2448 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2454 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2449 | 2455 | ||
2456 | WARN_ON_ONCE(softirq_count() == 0); | ||
2457 | |||
2450 | if (WARN_ON(status->band < 0 || | 2458 | if (WARN_ON(status->band < 0 || |
2451 | status->band >= IEEE80211_NUM_BANDS)) | 2459 | status->band >= IEEE80211_NUM_BANDS)) |
2452 | goto drop; | 2460 | goto drop; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index eec001491e66..594f2318c3d8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -361,6 +361,7 @@ int sta_info_insert(struct sta_info *sta) | |||
361 | u.ap); | 361 | u.ap); |
362 | 362 | ||
363 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); | 363 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); |
364 | sdata = sta->sdata; | ||
364 | } | 365 | } |
365 | 366 | ||
366 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 367 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -496,6 +497,7 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
496 | 497 | ||
497 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, | 498 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, |
498 | &(*sta)->sta); | 499 | &(*sta)->sta); |
500 | sdata = (*sta)->sdata; | ||
499 | } | 501 | } |
500 | 502 | ||
501 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 503 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5143d203256b..eaa4118de988 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -367,7 +367,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
367 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 367 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
368 | u32 staflags; | 368 | u32 staflags; |
369 | 369 | ||
370 | if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control))) | 370 | if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control) |
371 | || ieee80211_is_auth(hdr->frame_control) | ||
372 | || ieee80211_is_assoc_resp(hdr->frame_control) | ||
373 | || ieee80211_is_reassoc_resp(hdr->frame_control))) | ||
371 | return TX_CONTINUE; | 374 | return TX_CONTINUE; |
372 | 375 | ||
373 | staflags = get_sta_flags(sta); | 376 | staflags = get_sta_flags(sta); |
@@ -1442,7 +1445,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1442 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1445 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) |
1443 | continue; | 1446 | continue; |
1444 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, | 1447 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, |
1445 | hdr->addr2)) { | 1448 | hdr->addr2) == 0) { |
1446 | dev_hold(tmp_sdata->dev); | 1449 | dev_hold(tmp_sdata->dev); |
1447 | dev_put(sdata->dev); | 1450 | dev_put(sdata->dev); |
1448 | sdata = tmp_sdata; | 1451 | sdata = tmp_sdata; |
@@ -1701,7 +1704,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1701 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1704 | if (!is_multicast_ether_addr(hdr.addr1)) { |
1702 | rcu_read_lock(); | 1705 | rcu_read_lock(); |
1703 | sta = sta_info_get(local, hdr.addr1); | 1706 | sta = sta_info_get(local, hdr.addr1); |
1704 | if (sta) | 1707 | /* XXX: in the future, use sdata to look up the sta */ |
1708 | if (sta && sta->sdata == sdata) | ||
1705 | sta_flags = get_sta_flags(sta); | 1709 | sta_flags = get_sta_flags(sta); |
1706 | rcu_read_unlock(); | 1710 | rcu_read_unlock(); |
1707 | } | 1711 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index dd6564321369..e6c08da8da26 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -339,7 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
339 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 339 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
340 | 340 | ||
341 | if (WARN_ON(!info->control.vif)) { | 341 | if (WARN_ON(!info->control.vif)) { |
342 | kfree(skb); | 342 | kfree_skb(skb); |
343 | return; | 343 | return; |
344 | } | 344 | } |
345 | 345 | ||
@@ -367,7 +367,7 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local, | |||
367 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 367 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
368 | 368 | ||
369 | if (WARN_ON(!info->control.vif)) { | 369 | if (WARN_ON(!info->control.vif)) { |
370 | kfree(skb); | 370 | kfree_skb(skb); |
371 | continue; | 371 | continue; |
372 | } | 372 | } |
373 | 373 | ||
@@ -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 7c9ec3dee96e..b9168c1864ca 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/netfilter.h> | 15 | #include <linux/netfilter.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/sched.h> | ||
17 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
18 | #include <linux/proc_fs.h> | 19 | #include <linux/proc_fs.h> |
19 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
@@ -1350,6 +1351,11 @@ err_stat: | |||
1350 | return ret; | 1351 | return ret; |
1351 | } | 1352 | } |
1352 | 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 | |||
1353 | int nf_conntrack_init(struct net *net) | 1359 | int nf_conntrack_init(struct net *net) |
1354 | { | 1360 | { |
1355 | int ret; | 1361 | int ret; |
@@ -1367,6 +1373,9 @@ int nf_conntrack_init(struct net *net) | |||
1367 | /* For use by REJECT target */ | 1373 | /* For use by REJECT target */ |
1368 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); | 1374 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); |
1369 | 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); | ||
1370 | } | 1379 | } |
1371 | return 0; | 1380 | return 0; |
1372 | 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/nf_sockopt.c b/net/netfilter/nf_sockopt.c index 8ab829f86574..f042ae521557 100644 --- a/net/netfilter/nf_sockopt.c +++ b/net/netfilter/nf_sockopt.c | |||
@@ -113,7 +113,7 @@ static int nf_sockopt(struct sock *sk, u_int8_t pf, int val, | |||
113 | } | 113 | } |
114 | 114 | ||
115 | int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, | 115 | int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, |
116 | int len) | 116 | unsigned int len) |
117 | { | 117 | { |
118 | return nf_sockopt(sk, pf, val, opt, &len, 0); | 118 | return nf_sockopt(sk, pf, val, opt, &len, 0); |
119 | } | 119 | } |
@@ -154,7 +154,7 @@ static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val, | |||
154 | } | 154 | } |
155 | 155 | ||
156 | int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, | 156 | int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, |
157 | int val, char __user *opt, int len) | 157 | int val, char __user *opt, unsigned int len) |
158 | { | 158 | { |
159 | return compat_nf_sockopt(sk, pf, val, opt, &len, 0); | 159 | return compat_nf_sockopt(sk, pf, val, opt, &len, 0); |
160 | } | 160 | } |
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/netlink/af_netlink.c b/net/netlink/af_netlink.c index a4bafbf15097..19e98007691c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1150,7 +1150,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk, | |||
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | static int netlink_setsockopt(struct socket *sock, int level, int optname, | 1152 | static int netlink_setsockopt(struct socket *sock, int level, int optname, |
1153 | char __user *optval, int optlen) | 1153 | char __user *optval, unsigned int optlen) |
1154 | { | 1154 | { |
1155 | struct sock *sk = sock->sk; | 1155 | struct sock *sk = sock->sk; |
1156 | struct netlink_sock *nlk = nlk_sk(sk); | 1156 | struct netlink_sock *nlk = nlk_sk(sk); |
@@ -1788,7 +1788,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) | |||
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, | 1790 | rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, |
1791 | NLMSG_ERROR, sizeof(struct nlmsgerr), 0); | 1791 | NLMSG_ERROR, payload, 0); |
1792 | errmsg = nlmsg_data(rep); | 1792 | errmsg = nlmsg_data(rep); |
1793 | errmsg->error = err; | 1793 | errmsg->error = err; |
1794 | memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh)); | 1794 | memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh)); |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index ce1a34b99c23..7a834952f67f 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -301,7 +301,7 @@ void nr_destroy_socket(struct sock *sk) | |||
301 | */ | 301 | */ |
302 | 302 | ||
303 | static int nr_setsockopt(struct socket *sock, int level, int optname, | 303 | static int nr_setsockopt(struct socket *sock, int level, int optname, |
304 | char __user *optval, int optlen) | 304 | char __user *optval, unsigned int optlen) |
305 | { | 305 | { |
306 | struct sock *sk = sock->sk; | 306 | struct sock *sk = sock->sk; |
307 | struct nr_sock *nr = nr_sk(sk); | 307 | struct nr_sock *nr = nr_sk(sk); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 103d5611b818..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; |
@@ -1701,7 +1698,7 @@ static void packet_flush_mclist(struct sock *sk) | |||
1701 | } | 1698 | } |
1702 | 1699 | ||
1703 | static int | 1700 | static int |
1704 | packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 1701 | packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
1705 | { | 1702 | { |
1706 | struct sock *sk = sock->sk; | 1703 | struct sock *sk = sock->sk; |
1707 | struct packet_sock *po = pkt_sk(sk); | 1704 | struct packet_sock *po = pkt_sk(sk); |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b8252d289cd7..5f32d217535b 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -742,7 +742,7 @@ static int pep_init(struct sock *sk) | |||
742 | } | 742 | } |
743 | 743 | ||
744 | static int pep_setsockopt(struct sock *sk, int level, int optname, | 744 | static int pep_setsockopt(struct sock *sk, int level, int optname, |
745 | char __user *optval, int optlen) | 745 | char __user *optval, unsigned int optlen) |
746 | { | 746 | { |
747 | struct pep_sock *pn = pep_sk(sk); | 747 | struct pep_sock *pn = pep_sk(sk); |
748 | int val = 0, err = 0; | 748 | int val = 0, err = 0; |
diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 07aa9f08d5fb..aa5b5a972bff 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c | |||
@@ -407,7 +407,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport) | |||
407 | return -EADDRINUSE; | 407 | return -EADDRINUSE; |
408 | 408 | ||
409 | found: | 409 | found: |
410 | mutex_unlock(&port_mutex); | ||
411 | pn->sobject = pn_object(pn_addr(pn->sobject), sport); | 410 | pn->sobject = pn_object(pn_addr(pn->sobject), sport); |
412 | return 0; | 411 | return 0; |
413 | } | 412 | } |
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 6b58aeff4c7a..98e05382fd3c 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c | |||
@@ -248,7 +248,7 @@ static int rds_cong_monitor(struct rds_sock *rs, char __user *optval, | |||
248 | } | 248 | } |
249 | 249 | ||
250 | static int rds_setsockopt(struct socket *sock, int level, int optname, | 250 | static int rds_setsockopt(struct socket *sock, int level, int optname, |
251 | char __user *optval, int optlen) | 251 | char __user *optval, unsigned int optlen) |
252 | { | 252 | { |
253 | struct rds_sock *rs = rds_sk_to_rs(sock->sk); | 253 | struct rds_sock *rs = rds_sk_to_rs(sock->sk); |
254 | int ret; | 254 | int ret; |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index dbeaf2983822..a001f7c1f711 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <linux/rfkill.h> | 29 | #include <linux/rfkill.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
31 | #include <linux/miscdevice.h> | 32 | #include <linux/miscdevice.h> |
32 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
@@ -1188,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, | |||
1188 | #endif | 1189 | #endif |
1189 | 1190 | ||
1190 | static const struct file_operations rfkill_fops = { | 1191 | static const struct file_operations rfkill_fops = { |
1192 | .owner = THIS_MODULE, | ||
1191 | .open = rfkill_fop_open, | 1193 | .open = rfkill_fop_open, |
1192 | .read = rfkill_fop_read, | 1194 | .read = rfkill_fop_read, |
1193 | .write = rfkill_fop_write, | 1195 | .write = rfkill_fop_write, |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 1e166c9685aa..502cce76621d 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -370,7 +370,7 @@ void rose_destroy_socket(struct sock *sk) | |||
370 | */ | 370 | */ |
371 | 371 | ||
372 | static int rose_setsockopt(struct socket *sock, int level, int optname, | 372 | static int rose_setsockopt(struct socket *sock, int level, int optname, |
373 | char __user *optval, int optlen) | 373 | char __user *optval, unsigned int optlen) |
374 | { | 374 | { |
375 | struct sock *sk = sock->sk; | 375 | struct sock *sk = sock->sk; |
376 | struct rose_sock *rose = rose_sk(sk); | 376 | struct rose_sock *rose = rose_sk(sk); |
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/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index bfe493ebf27c..a86afceaa94f 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -507,7 +507,7 @@ out: | |||
507 | * set RxRPC socket options | 507 | * set RxRPC socket options |
508 | */ | 508 | */ |
509 | static int rxrpc_setsockopt(struct socket *sock, int level, int optname, | 509 | static int rxrpc_setsockopt(struct socket *sock, int level, int optname, |
510 | char __user *optval, int optlen) | 510 | char __user *optval, unsigned int optlen) |
511 | { | 511 | { |
512 | struct rxrpc_sock *rx = rxrpc_sk(sock->sk); | 512 | struct rxrpc_sock *rx = rxrpc_sk(sock->sk); |
513 | unsigned min_sec_level; | 513 | unsigned min_sec_level; |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 96c0ed115e2a..6b0359a500e6 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -34,7 +34,7 @@ static struct tcf_hashinfo pedit_hash_info = { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { | 36 | static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { |
37 | [TCA_PEDIT_PARMS] = { .len = sizeof(struct tcf_pedit) }, | 37 | [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, | 40 | static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 6a536949cdc0..7cf6c0fbc7a6 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -350,7 +350,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, | |||
350 | tcm = NLMSG_DATA(nlh); | 350 | tcm = NLMSG_DATA(nlh); |
351 | tcm->tcm_family = AF_UNSPEC; | 351 | tcm->tcm_family = AF_UNSPEC; |
352 | tcm->tcm__pad1 = 0; | 352 | tcm->tcm__pad1 = 0; |
353 | tcm->tcm__pad1 = 0; | 353 | tcm->tcm__pad2 = 0; |
354 | tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; | 354 | tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; |
355 | tcm->tcm_parent = tp->classid; | 355 | tcm->tcm_parent = tp->classid; |
356 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); | 356 | tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); |
diff --git a/net/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 89af37a6c871..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. */ |
@@ -2027,7 +2037,8 @@ out: | |||
2027 | * instead a error will be indicated to the user. | 2037 | * instead a error will be indicated to the user. |
2028 | */ | 2038 | */ |
2029 | static int sctp_setsockopt_disable_fragments(struct sock *sk, | 2039 | static int sctp_setsockopt_disable_fragments(struct sock *sk, |
2030 | char __user *optval, int optlen) | 2040 | char __user *optval, |
2041 | unsigned int optlen) | ||
2031 | { | 2042 | { |
2032 | int val; | 2043 | int val; |
2033 | 2044 | ||
@@ -2043,7 +2054,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, | |||
2043 | } | 2054 | } |
2044 | 2055 | ||
2045 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | 2056 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, |
2046 | int optlen) | 2057 | unsigned int optlen) |
2047 | { | 2058 | { |
2048 | if (optlen > sizeof(struct sctp_event_subscribe)) | 2059 | if (optlen > sizeof(struct sctp_event_subscribe)) |
2049 | return -EINVAL; | 2060 | return -EINVAL; |
@@ -2064,7 +2075,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2064 | * association is closed. | 2075 | * association is closed. |
2065 | */ | 2076 | */ |
2066 | static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | 2077 | static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, |
2067 | int optlen) | 2078 | unsigned int optlen) |
2068 | { | 2079 | { |
2069 | struct sctp_sock *sp = sctp_sk(sk); | 2080 | struct sctp_sock *sp = sctp_sk(sk); |
2070 | 2081 | ||
@@ -2318,7 +2329,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2318 | } | 2329 | } |
2319 | 2330 | ||
2320 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, | 2331 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, |
2321 | char __user *optval, int optlen) | 2332 | char __user *optval, |
2333 | unsigned int optlen) | ||
2322 | { | 2334 | { |
2323 | struct sctp_paddrparams params; | 2335 | struct sctp_paddrparams params; |
2324 | struct sctp_transport *trans = NULL; | 2336 | struct sctp_transport *trans = NULL; |
@@ -2430,7 +2442,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk, | |||
2430 | */ | 2442 | */ |
2431 | 2443 | ||
2432 | static int sctp_setsockopt_delayed_ack(struct sock *sk, | 2444 | static int sctp_setsockopt_delayed_ack(struct sock *sk, |
2433 | char __user *optval, int optlen) | 2445 | char __user *optval, unsigned int optlen) |
2434 | { | 2446 | { |
2435 | struct sctp_sack_info params; | 2447 | struct sctp_sack_info params; |
2436 | struct sctp_transport *trans = NULL; | 2448 | struct sctp_transport *trans = NULL; |
@@ -2546,7 +2558,7 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, | |||
2546 | * by the change). With TCP-style sockets, this option is inherited by | 2558 | * by the change). With TCP-style sockets, this option is inherited by |
2547 | * sockets derived from a listener socket. | 2559 | * sockets derived from a listener socket. |
2548 | */ | 2560 | */ |
2549 | static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int optlen) | 2561 | static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen) |
2550 | { | 2562 | { |
2551 | struct sctp_initmsg sinit; | 2563 | struct sctp_initmsg sinit; |
2552 | struct sctp_sock *sp = sctp_sk(sk); | 2564 | struct sctp_sock *sp = sctp_sk(sk); |
@@ -2583,7 +2595,8 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int opt | |||
2583 | * to this call if the caller is using the UDP model. | 2595 | * to this call if the caller is using the UDP model. |
2584 | */ | 2596 | */ |
2585 | static int sctp_setsockopt_default_send_param(struct sock *sk, | 2597 | static int sctp_setsockopt_default_send_param(struct sock *sk, |
2586 | char __user *optval, int optlen) | 2598 | char __user *optval, |
2599 | unsigned int optlen) | ||
2587 | { | 2600 | { |
2588 | struct sctp_sndrcvinfo info; | 2601 | struct sctp_sndrcvinfo info; |
2589 | struct sctp_association *asoc; | 2602 | struct sctp_association *asoc; |
@@ -2622,7 +2635,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, | |||
2622 | * association peer's addresses. | 2635 | * association peer's addresses. |
2623 | */ | 2636 | */ |
2624 | static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, | 2637 | static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, |
2625 | int optlen) | 2638 | unsigned int optlen) |
2626 | { | 2639 | { |
2627 | struct sctp_prim prim; | 2640 | struct sctp_prim prim; |
2628 | struct sctp_transport *trans; | 2641 | struct sctp_transport *trans; |
@@ -2651,7 +2664,7 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, | |||
2651 | * integer boolean flag. | 2664 | * integer boolean flag. |
2652 | */ | 2665 | */ |
2653 | static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, | 2666 | static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, |
2654 | int optlen) | 2667 | unsigned int optlen) |
2655 | { | 2668 | { |
2656 | int val; | 2669 | int val; |
2657 | 2670 | ||
@@ -2676,7 +2689,8 @@ static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, | |||
2676 | * be changed. | 2689 | * be changed. |
2677 | * | 2690 | * |
2678 | */ | 2691 | */ |
2679 | static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int optlen) { | 2692 | static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen) |
2693 | { | ||
2680 | struct sctp_rtoinfo rtoinfo; | 2694 | struct sctp_rtoinfo rtoinfo; |
2681 | struct sctp_association *asoc; | 2695 | struct sctp_association *asoc; |
2682 | 2696 | ||
@@ -2728,7 +2742,7 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int opt | |||
2728 | * See [SCTP] for more information. | 2742 | * See [SCTP] for more information. |
2729 | * | 2743 | * |
2730 | */ | 2744 | */ |
2731 | static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int optlen) | 2745 | static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen) |
2732 | { | 2746 | { |
2733 | 2747 | ||
2734 | struct sctp_assocparams assocparams; | 2748 | struct sctp_assocparams assocparams; |
@@ -2800,7 +2814,7 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o | |||
2800 | * addresses and a user will receive both PF_INET6 and PF_INET type | 2814 | * addresses and a user will receive both PF_INET6 and PF_INET type |
2801 | * addresses on the socket. | 2815 | * addresses on the socket. |
2802 | */ | 2816 | */ |
2803 | static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int optlen) | 2817 | static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen) |
2804 | { | 2818 | { |
2805 | int val; | 2819 | int val; |
2806 | struct sctp_sock *sp = sctp_sk(sk); | 2820 | struct sctp_sock *sp = sctp_sk(sk); |
@@ -2844,7 +2858,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op | |||
2844 | * changed (effecting future associations only). | 2858 | * changed (effecting future associations only). |
2845 | * assoc_value: This parameter specifies the maximum size in bytes. | 2859 | * assoc_value: This parameter specifies the maximum size in bytes. |
2846 | */ | 2860 | */ |
2847 | static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen) | 2861 | static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen) |
2848 | { | 2862 | { |
2849 | struct sctp_assoc_value params; | 2863 | struct sctp_assoc_value params; |
2850 | struct sctp_association *asoc; | 2864 | struct sctp_association *asoc; |
@@ -2899,7 +2913,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl | |||
2899 | * set primary request: | 2913 | * set primary request: |
2900 | */ | 2914 | */ |
2901 | static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval, | 2915 | static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval, |
2902 | int optlen) | 2916 | unsigned int optlen) |
2903 | { | 2917 | { |
2904 | struct sctp_sock *sp; | 2918 | struct sctp_sock *sp; |
2905 | struct sctp_endpoint *ep; | 2919 | struct sctp_endpoint *ep; |
@@ -2950,7 +2964,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2950 | } | 2964 | } |
2951 | 2965 | ||
2952 | static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval, | 2966 | static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval, |
2953 | int optlen) | 2967 | unsigned int optlen) |
2954 | { | 2968 | { |
2955 | struct sctp_setadaptation adaptation; | 2969 | struct sctp_setadaptation adaptation; |
2956 | 2970 | ||
@@ -2979,7 +2993,7 @@ static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval | |||
2979 | * saved with outbound messages. | 2993 | * saved with outbound messages. |
2980 | */ | 2994 | */ |
2981 | static int sctp_setsockopt_context(struct sock *sk, char __user *optval, | 2995 | static int sctp_setsockopt_context(struct sock *sk, char __user *optval, |
2982 | int optlen) | 2996 | unsigned int optlen) |
2983 | { | 2997 | { |
2984 | struct sctp_assoc_value params; | 2998 | struct sctp_assoc_value params; |
2985 | struct sctp_sock *sp; | 2999 | struct sctp_sock *sp; |
@@ -3030,7 +3044,7 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval, | |||
3030 | */ | 3044 | */ |
3031 | static int sctp_setsockopt_fragment_interleave(struct sock *sk, | 3045 | static int sctp_setsockopt_fragment_interleave(struct sock *sk, |
3032 | char __user *optval, | 3046 | char __user *optval, |
3033 | int optlen) | 3047 | unsigned int optlen) |
3034 | { | 3048 | { |
3035 | int val; | 3049 | int val; |
3036 | 3050 | ||
@@ -3063,7 +3077,7 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk, | |||
3063 | */ | 3077 | */ |
3064 | static int sctp_setsockopt_partial_delivery_point(struct sock *sk, | 3078 | static int sctp_setsockopt_partial_delivery_point(struct sock *sk, |
3065 | char __user *optval, | 3079 | char __user *optval, |
3066 | int optlen) | 3080 | unsigned int optlen) |
3067 | { | 3081 | { |
3068 | u32 val; | 3082 | u32 val; |
3069 | 3083 | ||
@@ -3096,7 +3110,7 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk, | |||
3096 | */ | 3110 | */ |
3097 | static int sctp_setsockopt_maxburst(struct sock *sk, | 3111 | static int sctp_setsockopt_maxburst(struct sock *sk, |
3098 | char __user *optval, | 3112 | char __user *optval, |
3099 | int optlen) | 3113 | unsigned int optlen) |
3100 | { | 3114 | { |
3101 | struct sctp_assoc_value params; | 3115 | struct sctp_assoc_value params; |
3102 | struct sctp_sock *sp; | 3116 | struct sctp_sock *sp; |
@@ -3140,8 +3154,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, | |||
3140 | * will only effect future associations on the socket. | 3154 | * will only effect future associations on the socket. |
3141 | */ | 3155 | */ |
3142 | static int sctp_setsockopt_auth_chunk(struct sock *sk, | 3156 | static int sctp_setsockopt_auth_chunk(struct sock *sk, |
3143 | char __user *optval, | 3157 | char __user *optval, |
3144 | int optlen) | 3158 | unsigned int optlen) |
3145 | { | 3159 | { |
3146 | struct sctp_authchunk val; | 3160 | struct sctp_authchunk val; |
3147 | 3161 | ||
@@ -3172,8 +3186,8 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3172 | * endpoint requires the peer to use. | 3186 | * endpoint requires the peer to use. |
3173 | */ | 3187 | */ |
3174 | static int sctp_setsockopt_hmac_ident(struct sock *sk, | 3188 | static int sctp_setsockopt_hmac_ident(struct sock *sk, |
3175 | char __user *optval, | 3189 | char __user *optval, |
3176 | int optlen) | 3190 | unsigned int optlen) |
3177 | { | 3191 | { |
3178 | struct sctp_hmacalgo *hmacs; | 3192 | struct sctp_hmacalgo *hmacs; |
3179 | u32 idents; | 3193 | u32 idents; |
@@ -3215,7 +3229,7 @@ out: | |||
3215 | */ | 3229 | */ |
3216 | static int sctp_setsockopt_auth_key(struct sock *sk, | 3230 | static int sctp_setsockopt_auth_key(struct sock *sk, |
3217 | char __user *optval, | 3231 | char __user *optval, |
3218 | int optlen) | 3232 | unsigned int optlen) |
3219 | { | 3233 | { |
3220 | struct sctp_authkey *authkey; | 3234 | struct sctp_authkey *authkey; |
3221 | struct sctp_association *asoc; | 3235 | struct sctp_association *asoc; |
@@ -3260,8 +3274,8 @@ out: | |||
3260 | * the association shared key. | 3274 | * the association shared key. |
3261 | */ | 3275 | */ |
3262 | static int sctp_setsockopt_active_key(struct sock *sk, | 3276 | static int sctp_setsockopt_active_key(struct sock *sk, |
3263 | char __user *optval, | 3277 | char __user *optval, |
3264 | int optlen) | 3278 | unsigned int optlen) |
3265 | { | 3279 | { |
3266 | struct sctp_authkeyid val; | 3280 | struct sctp_authkeyid val; |
3267 | struct sctp_association *asoc; | 3281 | struct sctp_association *asoc; |
@@ -3288,8 +3302,8 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3288 | * This set option will delete a shared secret key from use. | 3302 | * This set option will delete a shared secret key from use. |
3289 | */ | 3303 | */ |
3290 | static int sctp_setsockopt_del_key(struct sock *sk, | 3304 | static int sctp_setsockopt_del_key(struct sock *sk, |
3291 | char __user *optval, | 3305 | char __user *optval, |
3292 | int optlen) | 3306 | unsigned int optlen) |
3293 | { | 3307 | { |
3294 | struct sctp_authkeyid val; | 3308 | struct sctp_authkeyid val; |
3295 | struct sctp_association *asoc; | 3309 | struct sctp_association *asoc; |
@@ -3332,7 +3346,7 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3332 | * optlen - the size of the buffer. | 3346 | * optlen - the size of the buffer. |
3333 | */ | 3347 | */ |
3334 | SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | 3348 | SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, |
3335 | char __user *optval, int optlen) | 3349 | char __user *optval, unsigned int optlen) |
3336 | { | 3350 | { |
3337 | int retval = 0; | 3351 | int retval = 0; |
3338 | 3352 | ||
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/socket.c b/net/socket.c index 49917a1cac7d..75655365b5fd 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2098,12 +2098,17 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) | |||
2098 | unsigned long a[6]; | 2098 | unsigned long a[6]; |
2099 | unsigned long a0, a1; | 2099 | unsigned long a0, a1; |
2100 | int err; | 2100 | int err; |
2101 | unsigned int len; | ||
2101 | 2102 | ||
2102 | if (call < 1 || call > SYS_ACCEPT4) | 2103 | if (call < 1 || call > SYS_ACCEPT4) |
2103 | return -EINVAL; | 2104 | return -EINVAL; |
2104 | 2105 | ||
2106 | len = nargs[call]; | ||
2107 | if (len > sizeof(a)) | ||
2108 | return -EINVAL; | ||
2109 | |||
2105 | /* copy_from_user should be SMP safe. */ | 2110 | /* copy_from_user should be SMP safe. */ |
2106 | if (copy_from_user(a, args, nargs[call])) | 2111 | if (copy_from_user(a, args, len)) |
2107 | return -EFAULT; | 2112 | return -EFAULT; |
2108 | 2113 | ||
2109 | audit_socketcall(nargs[call] / sizeof(unsigned long), a); | 2114 | audit_socketcall(nargs[call] / sizeof(unsigned long), a); |
@@ -2386,7 +2391,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, | |||
2386 | } | 2391 | } |
2387 | 2392 | ||
2388 | int kernel_setsockopt(struct socket *sock, int level, int optname, | 2393 | int kernel_setsockopt(struct socket *sock, int level, int optname, |
2389 | char *optval, int optlen) | 2394 | char *optval, unsigned int optlen) |
2390 | { | 2395 | { |
2391 | mm_segment_t oldfs = get_fs(); | 2396 | mm_segment_t oldfs = get_fs(); |
2392 | int err; | 2397 | int err; |
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/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 0cf5e8c27a10..3fa5751af0ec 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/sunrpc/svc_xprt.h> | 42 | #include <linux/sunrpc/svc_xprt.h> |
43 | #include <linux/sunrpc/debug.h> | 43 | #include <linux/sunrpc/debug.h> |
44 | #include <linux/sunrpc/rpc_rdma.h> | 44 | #include <linux/sunrpc/rpc_rdma.h> |
45 | #include <linux/sched.h> | ||
45 | #include <linux/spinlock.h> | 46 | #include <linux/spinlock.h> |
46 | #include <rdma/ib_verbs.h> | 47 | #include <rdma/ib_verbs.h> |
47 | #include <rdma/rdma_cm.h> | 48 | #include <rdma/rdma_cm.h> |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e8254e809b79..e6d9abf7440e 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1658,7 +1658,7 @@ restart: | |||
1658 | */ | 1658 | */ |
1659 | 1659 | ||
1660 | static int setsockopt(struct socket *sock, | 1660 | static int setsockopt(struct socket *sock, |
1661 | int lvl, int opt, char __user *ov, int ol) | 1661 | int lvl, int opt, char __user *ov, unsigned int ol) |
1662 | { | 1662 | { |
1663 | struct sock *sk = sock->sk; | 1663 | struct sock *sk = sock->sk; |
1664 | struct tipc_port *tport = tipc_sk_port(sk); | 1664 | struct tipc_port *tport = tipc_sk_port(sk); |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51ab497115eb..fc820cd75453 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1074,6 +1074,8 @@ restart: | |||
1074 | err = -ECONNREFUSED; | 1074 | err = -ECONNREFUSED; |
1075 | if (other->sk_state != TCP_LISTEN) | 1075 | if (other->sk_state != TCP_LISTEN) |
1076 | goto out_unlock; | 1076 | goto out_unlock; |
1077 | if (other->sk_shutdown & RCV_SHUTDOWN) | ||
1078 | goto out_unlock; | ||
1077 | 1079 | ||
1078 | if (unix_recvq_full(other)) { | 1080 | if (unix_recvq_full(other)) { |
1079 | err = -EAGAIN; | 1081 | err = -EAGAIN; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 45b2be3274db..a595f712b5bf 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/etherdevice.h> | 15 | #include <linux/etherdevice.h> |
16 | #include <linux/rtnetlink.h> | 16 | #include <linux/rtnetlink.h> |
17 | #include <linux/sched.h> | ||
17 | #include <net/genetlink.h> | 18 | #include <net/genetlink.h> |
18 | #include <net/cfg80211.h> | 19 | #include <net/cfg80211.h> |
19 | #include "nl80211.h" | 20 | #include "nl80211.h" |
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/nl80211.c b/net/wireless/nl80211.c index eddab097435c..ca3c92a0a14f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -4029,7 +4029,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) | |||
4029 | rdev = cfg80211_get_dev_from_info(info); | 4029 | rdev = cfg80211_get_dev_from_info(info); |
4030 | if (IS_ERR(rdev)) { | 4030 | if (IS_ERR(rdev)) { |
4031 | err = PTR_ERR(rdev); | 4031 | err = PTR_ERR(rdev); |
4032 | goto out; | 4032 | goto out_rtnl; |
4033 | } | 4033 | } |
4034 | 4034 | ||
4035 | net = get_net_ns_by_pid(pid); | 4035 | net = get_net_ns_by_pid(pid); |
@@ -4049,6 +4049,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) | |||
4049 | put_net(net); | 4049 | put_net(net); |
4050 | out: | 4050 | out: |
4051 | cfg80211_unlock_rdev(rdev); | 4051 | cfg80211_unlock_rdev(rdev); |
4052 | out_rtnl: | ||
4052 | rtnl_unlock(); | 4053 | rtnl_unlock(); |
4053 | return err; | 4054 | return err; |
4054 | } | 4055 | } |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 7fae7eee65de..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, |
@@ -762,9 +782,8 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
762 | wdev->conn->params.ssid = wdev->ssid; | 782 | wdev->conn->params.ssid = wdev->ssid; |
763 | wdev->conn->params.ssid_len = connect->ssid_len; | 783 | wdev->conn->params.ssid_len = connect->ssid_len; |
764 | 784 | ||
765 | /* don't care about result -- but fill bssid & channel */ | 785 | /* see if we have the bss already */ |
766 | if (!wdev->conn->params.bssid || !wdev->conn->params.channel) | 786 | bss = cfg80211_get_conn_bss(wdev); |
767 | bss = cfg80211_get_conn_bss(wdev); | ||
768 | 787 | ||
769 | wdev->sme_state = CFG80211_SME_CONNECTING; | 788 | wdev->sme_state = CFG80211_SME_CONNECTING; |
770 | wdev->connect_keys = connkeys; | 789 | wdev->connect_keys = connkeys; |
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index bf725275eb8d..5615a8802536 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c | |||
@@ -30,7 +30,8 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | |||
30 | if (wdev->wext.keys) { | 30 | if (wdev->wext.keys) { |
31 | wdev->wext.keys->def = wdev->wext.default_key; | 31 | wdev->wext.keys->def = wdev->wext.default_key; |
32 | wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; | 32 | wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; |
33 | wdev->wext.connect.privacy = true; | 33 | if (wdev->wext.default_key != -1) |
34 | wdev->wext.connect.privacy = true; | ||
34 | } | 35 | } |
35 | 36 | ||
36 | if (!wdev->wext.connect.ssid_len) | 37 | if (!wdev->wext.connect.ssid_len) |
@@ -229,8 +230,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, | |||
229 | data->flags = 1; | 230 | data->flags = 1; |
230 | data->length = wdev->wext.connect.ssid_len; | 231 | data->length = wdev->wext.connect.ssid_len; |
231 | memcpy(ssid, wdev->wext.connect.ssid, data->length); | 232 | memcpy(ssid, wdev->wext.connect.ssid, data->length); |
232 | } else | 233 | } |
233 | data->flags = 0; | ||
234 | wdev_unlock(wdev); | 234 | wdev_unlock(wdev); |
235 | 235 | ||
236 | return 0; | 236 | return 0; |
@@ -306,8 +306,6 @@ int cfg80211_mgd_wext_giwap(struct net_device *dev, | |||
306 | wdev_lock(wdev); | 306 | wdev_lock(wdev); |
307 | if (wdev->current_bss) | 307 | if (wdev->current_bss) |
308 | memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); | 308 | memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); |
309 | else if (wdev->wext.connect.bssid) | ||
310 | memcpy(ap_addr->sa_data, wdev->wext.connect.bssid, ETH_ALEN); | ||
311 | else | 309 | else |
312 | memset(ap_addr->sa_data, 0, ETH_ALEN); | 310 | memset(ap_addr->sa_data, 0, ETH_ALEN); |
313 | wdev_unlock(wdev); | 311 | wdev_unlock(wdev); |
diff --git a/net/wireless/wext.c b/net/wireless/wext.c index 5b4a0cee4418..60fe57761ca9 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c | |||
@@ -470,7 +470,7 @@ static iw_handler get_handler(struct net_device *dev, unsigned int cmd) | |||
470 | /* | 470 | /* |
471 | * Get statistics out of the driver | 471 | * Get statistics out of the driver |
472 | */ | 472 | */ |
473 | static struct iw_statistics *get_wireless_stats(struct net_device *dev) | 473 | struct iw_statistics *get_wireless_stats(struct net_device *dev) |
474 | { | 474 | { |
475 | /* New location */ | 475 | /* New location */ |
476 | if ((dev->wireless_handlers != NULL) && | 476 | if ((dev->wireless_handlers != NULL) && |
@@ -773,10 +773,13 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
773 | essid_compat = 1; | 773 | essid_compat = 1; |
774 | else if (IW_IS_SET(cmd) && (iwp->length != 0)) { | 774 | else if (IW_IS_SET(cmd) && (iwp->length != 0)) { |
775 | char essid[IW_ESSID_MAX_SIZE + 1]; | 775 | char essid[IW_ESSID_MAX_SIZE + 1]; |
776 | unsigned int len; | ||
777 | len = iwp->length * descr->token_size; | ||
776 | 778 | ||
777 | err = copy_from_user(essid, iwp->pointer, | 779 | if (len > IW_ESSID_MAX_SIZE) |
778 | iwp->length * | 780 | return -EFAULT; |
779 | descr->token_size); | 781 | |
782 | err = copy_from_user(essid, iwp->pointer, len); | ||
780 | if (err) | 783 | if (err) |
781 | return -EFAULT; | 784 | return -EFAULT; |
782 | 785 | ||
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 5e6c072c64d3..7fa9c7ad3d3b 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -409,7 +409,7 @@ static void x25_destroy_socket(struct sock *sk) | |||
409 | */ | 409 | */ |
410 | 410 | ||
411 | static int x25_setsockopt(struct socket *sock, int level, int optname, | 411 | static int x25_setsockopt(struct socket *sock, int level, int optname, |
412 | char __user *optval, int optlen) | 412 | char __user *optval, unsigned int optlen) |
413 | { | 413 | { |
414 | int opt; | 414 | int opt; |
415 | struct sock *sk = sock->sk; | 415 | struct sock *sk = sock->sk; |