diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/bluetooth/hci_conn.c | 16 | ||||
| -rw-r--r-- | net/bluetooth/hci_core.c | 4 | ||||
| -rw-r--r-- | net/bluetooth/hci_event.c | 9 | ||||
| -rw-r--r-- | net/bluetooth/l2cap.c | 84 | ||||
| -rw-r--r-- | net/bluetooth/rfcomm/core.c | 3 | ||||
| -rw-r--r-- | net/core/dev.c | 3 | ||||
| -rw-r--r-- | net/core/ethtool.c | 2 | ||||
| -rw-r--r-- | net/core/skbuff.c | 8 | ||||
| -rw-r--r-- | net/dcb/dcbnl.c | 13 | ||||
| -rw-r--r-- | net/ipv4/arp.c | 11 | ||||
| -rw-r--r-- | net/ipv4/inetpeer.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 1 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 81 | ||||
| -rw-r--r-- | net/ipv6/route.c | 9 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_policy.c | 6 | ||||
| -rw-r--r-- | net/mac80211/tx.c | 3 | ||||
| -rw-r--r-- | net/sched/sch_cbq.c | 3 | ||||
| -rw-r--r-- | net/sched/sch_drr.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_dsmark.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_fifo.c | 5 | ||||
| -rw-r--r-- | net/sched/sch_hfsc.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_htb.c | 12 | ||||
| -rw-r--r-- | net/sched/sch_multiq.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_netem.c | 3 | ||||
| -rw-r--r-- | net/sched/sch_prio.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_red.c | 11 | ||||
| -rw-r--r-- | net/sched/sch_sfq.c | 5 | ||||
| -rw-r--r-- | net/sched/sch_tbf.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_teql.c | 3 |
30 files changed, 146 insertions, 165 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6b90a4191734..99cd8d9d891b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
| @@ -379,14 +379,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
| 379 | hci_conn_hold(acl); | 379 | hci_conn_hold(acl); |
| 380 | 380 | ||
| 381 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { | 381 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { |
| 382 | acl->sec_level = sec_level; | 382 | acl->sec_level = BT_SECURITY_LOW; |
| 383 | acl->pending_sec_level = sec_level; | ||
| 383 | acl->auth_type = auth_type; | 384 | acl->auth_type = auth_type; |
| 384 | hci_acl_connect(acl); | 385 | hci_acl_connect(acl); |
| 385 | } else { | ||
| 386 | if (acl->sec_level < sec_level) | ||
| 387 | acl->sec_level = sec_level; | ||
| 388 | if (acl->auth_type < auth_type) | ||
| 389 | acl->auth_type = auth_type; | ||
| 390 | } | 386 | } |
| 391 | 387 | ||
| 392 | if (type == ACL_LINK) | 388 | if (type == ACL_LINK) |
| @@ -442,11 +438,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
| 442 | { | 438 | { |
| 443 | BT_DBG("conn %p", conn); | 439 | BT_DBG("conn %p", conn); |
| 444 | 440 | ||
| 441 | if (conn->pending_sec_level > sec_level) | ||
| 442 | sec_level = conn->pending_sec_level; | ||
| 443 | |||
| 445 | if (sec_level > conn->sec_level) | 444 | if (sec_level > conn->sec_level) |
| 446 | conn->sec_level = sec_level; | 445 | conn->pending_sec_level = sec_level; |
| 447 | else if (conn->link_mode & HCI_LM_AUTH) | 446 | else if (conn->link_mode & HCI_LM_AUTH) |
| 448 | return 1; | 447 | return 1; |
| 449 | 448 | ||
| 449 | /* Make sure we preserve an existing MITM requirement*/ | ||
| 450 | auth_type |= (conn->auth_type & 0x01); | ||
| 451 | |||
| 450 | conn->auth_type = auth_type; | 452 | conn->auth_type = auth_type; |
| 451 | 453 | ||
| 452 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 454 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8b602d881fd7..9c4541bc488a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -1011,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
| 1011 | 1011 | ||
| 1012 | destroy_workqueue(hdev->workqueue); | 1012 | destroy_workqueue(hdev->workqueue); |
| 1013 | 1013 | ||
| 1014 | hci_dev_lock_bh(hdev); | ||
| 1015 | hci_blacklist_clear(hdev); | ||
| 1016 | hci_dev_unlock_bh(hdev); | ||
| 1017 | |||
| 1014 | __hci_dev_put(hdev); | 1018 | __hci_dev_put(hdev); |
| 1015 | 1019 | ||
| 1016 | return 0; | 1020 | return 0; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 38100170d380..a290854fdaa6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, | |||
| 692 | if (conn->state != BT_CONFIG || !conn->out) | 692 | if (conn->state != BT_CONFIG || !conn->out) |
| 693 | return 0; | 693 | return 0; |
| 694 | 694 | ||
| 695 | if (conn->sec_level == BT_SECURITY_SDP) | 695 | if (conn->pending_sec_level == BT_SECURITY_SDP) |
| 696 | return 0; | 696 | return 0; |
| 697 | 697 | ||
| 698 | /* Only request authentication for SSP connections or non-SSP | 698 | /* Only request authentication for SSP connections or non-SSP |
| 699 | * devices with sec_level HIGH */ | 699 | * devices with sec_level HIGH */ |
| 700 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && | 700 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && |
| 701 | conn->sec_level != BT_SECURITY_HIGH) | 701 | conn->pending_sec_level != BT_SECURITY_HIGH) |
| 702 | return 0; | 702 | return 0; |
| 703 | 703 | ||
| 704 | return 1; | 704 | return 1; |
| @@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
| 1095 | 1095 | ||
| 1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
| 1097 | if (conn) { | 1097 | if (conn) { |
| 1098 | if (!ev->status) | 1098 | if (!ev->status) { |
| 1099 | conn->link_mode |= HCI_LM_AUTH; | 1099 | conn->link_mode |= HCI_LM_AUTH; |
| 1100 | else | 1100 | conn->sec_level = conn->pending_sec_level; |
| 1101 | } else | ||
| 1101 | conn->sec_level = BT_SECURITY_LOW; | 1102 | conn->sec_level = BT_SECURITY_LOW; |
| 1102 | 1103 | ||
| 1103 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1104 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c791fcda7b2d..7550abb0c96a 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -305,33 +305,44 @@ static void l2cap_chan_del(struct sock *sk, int err) | |||
| 305 | } | 305 | } |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | /* Service level security */ | 308 | static inline u8 l2cap_get_auth_type(struct sock *sk) |
| 309 | static inline int l2cap_check_security(struct sock *sk) | ||
| 310 | { | 309 | { |
| 311 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 310 | if (sk->sk_type == SOCK_RAW) { |
| 312 | __u8 auth_type; | 311 | switch (l2cap_pi(sk)->sec_level) { |
| 312 | case BT_SECURITY_HIGH: | ||
| 313 | return HCI_AT_DEDICATED_BONDING_MITM; | ||
| 314 | case BT_SECURITY_MEDIUM: | ||
| 315 | return HCI_AT_DEDICATED_BONDING; | ||
| 316 | default: | ||
| 317 | return HCI_AT_NO_BONDING; | ||
| 318 | } | ||
| 319 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
| 320 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | ||
| 321 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
| 313 | 322 | ||
| 314 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
| 315 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | 323 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) |
| 316 | auth_type = HCI_AT_NO_BONDING_MITM; | 324 | return HCI_AT_NO_BONDING_MITM; |
| 317 | else | 325 | else |
| 318 | auth_type = HCI_AT_NO_BONDING; | 326 | return HCI_AT_NO_BONDING; |
| 319 | |||
| 320 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | ||
| 321 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
| 322 | } else { | 327 | } else { |
| 323 | switch (l2cap_pi(sk)->sec_level) { | 328 | switch (l2cap_pi(sk)->sec_level) { |
| 324 | case BT_SECURITY_HIGH: | 329 | case BT_SECURITY_HIGH: |
| 325 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | 330 | return HCI_AT_GENERAL_BONDING_MITM; |
| 326 | break; | ||
| 327 | case BT_SECURITY_MEDIUM: | 331 | case BT_SECURITY_MEDIUM: |
| 328 | auth_type = HCI_AT_GENERAL_BONDING; | 332 | return HCI_AT_GENERAL_BONDING; |
| 329 | break; | ||
| 330 | default: | 333 | default: |
| 331 | auth_type = HCI_AT_NO_BONDING; | 334 | return HCI_AT_NO_BONDING; |
| 332 | break; | ||
| 333 | } | 335 | } |
| 334 | } | 336 | } |
| 337 | } | ||
| 338 | |||
| 339 | /* Service level security */ | ||
| 340 | static inline int l2cap_check_security(struct sock *sk) | ||
| 341 | { | ||
| 342 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
| 343 | __u8 auth_type; | ||
| 344 | |||
| 345 | auth_type = l2cap_get_auth_type(sk); | ||
| 335 | 346 | ||
| 336 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, | 347 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, |
| 337 | auth_type); | 348 | auth_type); |
| @@ -1068,39 +1079,7 @@ static int l2cap_do_connect(struct sock *sk) | |||
| 1068 | 1079 | ||
| 1069 | err = -ENOMEM; | 1080 | err = -ENOMEM; |
| 1070 | 1081 | ||
| 1071 | if (sk->sk_type == SOCK_RAW) { | 1082 | auth_type = l2cap_get_auth_type(sk); |
| 1072 | switch (l2cap_pi(sk)->sec_level) { | ||
| 1073 | case BT_SECURITY_HIGH: | ||
| 1074 | auth_type = HCI_AT_DEDICATED_BONDING_MITM; | ||
| 1075 | break; | ||
| 1076 | case BT_SECURITY_MEDIUM: | ||
| 1077 | auth_type = HCI_AT_DEDICATED_BONDING; | ||
| 1078 | break; | ||
| 1079 | default: | ||
| 1080 | auth_type = HCI_AT_NO_BONDING; | ||
| 1081 | break; | ||
| 1082 | } | ||
| 1083 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
| 1084 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | ||
| 1085 | auth_type = HCI_AT_NO_BONDING_MITM; | ||
| 1086 | else | ||
| 1087 | auth_type = HCI_AT_NO_BONDING; | ||
| 1088 | |||
| 1089 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | ||
| 1090 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
| 1091 | } else { | ||
| 1092 | switch (l2cap_pi(sk)->sec_level) { | ||
| 1093 | case BT_SECURITY_HIGH: | ||
| 1094 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
| 1095 | break; | ||
| 1096 | case BT_SECURITY_MEDIUM: | ||
| 1097 | auth_type = HCI_AT_GENERAL_BONDING; | ||
| 1098 | break; | ||
| 1099 | default: | ||
| 1100 | auth_type = HCI_AT_NO_BONDING; | ||
| 1101 | break; | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | 1083 | ||
| 1105 | hcon = hci_connect(hdev, ACL_LINK, dst, | 1084 | hcon = hci_connect(hdev, ACL_LINK, dst, |
| 1106 | l2cap_pi(sk)->sec_level, auth_type); | 1085 | l2cap_pi(sk)->sec_level, auth_type); |
| @@ -1127,7 +1106,8 @@ static int l2cap_do_connect(struct sock *sk) | |||
| 1127 | if (sk->sk_type != SOCK_SEQPACKET && | 1106 | if (sk->sk_type != SOCK_SEQPACKET && |
| 1128 | sk->sk_type != SOCK_STREAM) { | 1107 | sk->sk_type != SOCK_STREAM) { |
| 1129 | l2cap_sock_clear_timer(sk); | 1108 | l2cap_sock_clear_timer(sk); |
| 1130 | sk->sk_state = BT_CONNECTED; | 1109 | if (l2cap_check_security(sk)) |
| 1110 | sk->sk_state = BT_CONNECTED; | ||
| 1131 | } else | 1111 | } else |
| 1132 | l2cap_do_start(sk); | 1112 | l2cap_do_start(sk); |
| 1133 | } | 1113 | } |
| @@ -1893,8 +1873,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
| 1893 | if (pi->mode == L2CAP_MODE_STREAMING) { | 1873 | if (pi->mode == L2CAP_MODE_STREAMING) { |
| 1894 | l2cap_streaming_send(sk); | 1874 | l2cap_streaming_send(sk); |
| 1895 | } else { | 1875 | } else { |
| 1896 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && | 1876 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
| 1897 | pi->conn_state && L2CAP_CONN_WAIT_F) { | 1877 | (pi->conn_state & L2CAP_CONN_WAIT_F)) { |
| 1898 | err = len; | 1878 | err = len; |
| 1899 | break; | 1879 | break; |
| 1900 | } | 1880 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index ff8aaa736650..6b83776534fb 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
| @@ -1164,7 +1164,8 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | |||
| 1164 | * initiator rfcomm_process_rx already calls | 1164 | * initiator rfcomm_process_rx already calls |
| 1165 | * rfcomm_session_put() */ | 1165 | * rfcomm_session_put() */ |
| 1166 | if (s->sock->sk->sk_state != BT_CLOSED) | 1166 | if (s->sock->sk->sk_state != BT_CLOSED) |
| 1167 | rfcomm_session_put(s); | 1167 | if (list_empty(&s->dlcs)) |
| 1168 | rfcomm_session_put(s); | ||
| 1168 | break; | 1169 | break; |
| 1169 | } | 1170 | } |
| 1170 | } | 1171 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 7c6a46f80372..24ea2d71e7ea 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -749,7 +749,8 @@ EXPORT_SYMBOL(dev_get_by_index); | |||
| 749 | * @ha: hardware address | 749 | * @ha: hardware address |
| 750 | * | 750 | * |
| 751 | * Search for an interface by MAC address. Returns NULL if the device | 751 | * Search for an interface by MAC address. Returns NULL if the device |
| 752 | * is not found or a pointer to the device. The caller must hold RCU | 752 | * is not found or a pointer to the device. |
| 753 | * The caller must hold RCU or RTNL. | ||
| 753 | * The returned device has not had its ref count increased | 754 | * The returned device has not had its ref count increased |
| 754 | * and the caller must therefore be careful about locking | 755 | * and the caller must therefore be careful about locking |
| 755 | * | 756 | * |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 17741782a345..ff2302910b5e 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -817,7 +817,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | |||
| 817 | if (regs.len > reglen) | 817 | if (regs.len > reglen) |
| 818 | regs.len = reglen; | 818 | regs.len = reglen; |
| 819 | 819 | ||
| 820 | regbuf = vmalloc(reglen); | 820 | regbuf = vzalloc(reglen); |
| 821 | if (!regbuf) | 821 | if (!regbuf) |
| 822 | return -ENOMEM; | 822 | return -ENOMEM; |
| 823 | 823 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d31bb36ae0dc..7cd1bc86d591 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -2744,8 +2744,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
| 2744 | 2744 | ||
| 2745 | merge: | 2745 | merge: |
| 2746 | if (offset > headlen) { | 2746 | if (offset > headlen) { |
| 2747 | skbinfo->frags[0].page_offset += offset - headlen; | 2747 | unsigned int eat = offset - headlen; |
| 2748 | skbinfo->frags[0].size -= offset - headlen; | 2748 | |
| 2749 | skbinfo->frags[0].page_offset += eat; | ||
| 2750 | skbinfo->frags[0].size -= eat; | ||
| 2751 | skb->data_len -= eat; | ||
| 2752 | skb->len -= eat; | ||
| 2749 | offset = headlen; | 2753 | offset = headlen; |
| 2750 | } | 2754 | } |
| 2751 | 2755 | ||
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index d900ab99814a..6b03f561caec 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
| @@ -583,7 +583,7 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, | |||
| 583 | u8 up, idtype; | 583 | u8 up, idtype; |
| 584 | int ret = -EINVAL; | 584 | int ret = -EINVAL; |
| 585 | 585 | ||
| 586 | if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->getapp) | 586 | if (!tb[DCB_ATTR_APP]) |
| 587 | goto out; | 587 | goto out; |
| 588 | 588 | ||
| 589 | ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], | 589 | ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], |
| @@ -604,7 +604,16 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, | |||
| 604 | goto out; | 604 | goto out; |
| 605 | 605 | ||
| 606 | id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); | 606 | id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); |
| 607 | up = netdev->dcbnl_ops->getapp(netdev, idtype, id); | 607 | |
| 608 | if (netdev->dcbnl_ops->getapp) { | ||
| 609 | up = netdev->dcbnl_ops->getapp(netdev, idtype, id); | ||
| 610 | } else { | ||
| 611 | struct dcb_app app = { | ||
| 612 | .selector = idtype, | ||
| 613 | .protocol = id, | ||
| 614 | }; | ||
| 615 | up = dcb_getapp(netdev, &app); | ||
| 616 | } | ||
| 608 | 617 | ||
| 609 | /* send this back */ | 618 | /* send this back */ |
| 610 | dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 619 | dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 04c8b69fd426..7927589813b5 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
| @@ -1017,14 +1017,13 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on) | |||
| 1017 | IPV4_DEVCONF_ALL(net, PROXY_ARP) = on; | 1017 | IPV4_DEVCONF_ALL(net, PROXY_ARP) = on; |
| 1018 | return 0; | 1018 | return 0; |
| 1019 | } | 1019 | } |
| 1020 | if (__in_dev_get_rcu(dev)) { | 1020 | if (__in_dev_get_rtnl(dev)) { |
| 1021 | IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on); | 1021 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on); |
| 1022 | return 0; | 1022 | return 0; |
| 1023 | } | 1023 | } |
| 1024 | return -ENXIO; | 1024 | return -ENXIO; |
| 1025 | } | 1025 | } |
| 1026 | 1026 | ||
| 1027 | /* must be called with rcu_read_lock() */ | ||
| 1028 | static int arp_req_set_public(struct net *net, struct arpreq *r, | 1027 | static int arp_req_set_public(struct net *net, struct arpreq *r, |
| 1029 | struct net_device *dev) | 1028 | struct net_device *dev) |
| 1030 | { | 1029 | { |
| @@ -1233,10 +1232,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
| 1233 | if (!(r.arp_flags & ATF_NETMASK)) | 1232 | if (!(r.arp_flags & ATF_NETMASK)) |
| 1234 | ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = | 1233 | ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = |
| 1235 | htonl(0xFFFFFFFFUL); | 1234 | htonl(0xFFFFFFFFUL); |
| 1236 | rcu_read_lock(); | 1235 | rtnl_lock(); |
| 1237 | if (r.arp_dev[0]) { | 1236 | if (r.arp_dev[0]) { |
| 1238 | err = -ENODEV; | 1237 | err = -ENODEV; |
| 1239 | dev = dev_get_by_name_rcu(net, r.arp_dev); | 1238 | dev = __dev_get_by_name(net, r.arp_dev); |
| 1240 | if (dev == NULL) | 1239 | if (dev == NULL) |
| 1241 | goto out; | 1240 | goto out; |
| 1242 | 1241 | ||
| @@ -1263,7 +1262,7 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
| 1263 | break; | 1262 | break; |
| 1264 | } | 1263 | } |
| 1265 | out: | 1264 | out: |
| 1266 | rcu_read_unlock(); | 1265 | rtnl_unlock(); |
| 1267 | if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r))) | 1266 | if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r))) |
| 1268 | err = -EFAULT; | 1267 | err = -EFAULT; |
| 1269 | return err; | 1268 | return err; |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index d9bc85751c74..a96e65674ac3 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
| @@ -475,7 +475,7 @@ static int cleanup_once(unsigned long ttl) | |||
| 475 | struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) | 475 | struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) |
| 476 | { | 476 | { |
| 477 | struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; | 477 | struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; |
| 478 | struct inet_peer_base *base = family_to_base(AF_INET); | 478 | struct inet_peer_base *base = family_to_base(daddr->family); |
| 479 | struct inet_peer *p; | 479 | struct inet_peer *p; |
| 480 | 480 | ||
| 481 | /* Look up for the address quickly, lockless. | 481 | /* Look up for the address quickly, lockless. |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2549b29b062d..eb7f82ebf4a3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -4399,7 +4399,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
| 4399 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { | 4399 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { |
| 4400 | tp->ucopy.len -= chunk; | 4400 | tp->ucopy.len -= chunk; |
| 4401 | tp->copied_seq += chunk; | 4401 | tp->copied_seq += chunk; |
| 4402 | eaten = (chunk == skb->len && !th->fin); | 4402 | eaten = (chunk == skb->len); |
| 4403 | tcp_rcv_space_adjust(sk); | 4403 | tcp_rcv_space_adjust(sk); |
| 4404 | } | 4404 | } |
| 4405 | local_bh_disable(); | 4405 | local_bh_disable(); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 856f68466d49..02f583b3744a 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1994,7 +1994,6 @@ static void *listening_get_next(struct seq_file *seq, void *cur) | |||
| 1994 | } | 1994 | } |
| 1995 | req = req->dl_next; | 1995 | req = req->dl_next; |
| 1996 | } | 1996 | } |
| 1997 | st->offset = 0; | ||
| 1998 | if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries) | 1997 | if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries) |
| 1999 | break; | 1998 | break; |
| 2000 | get_req: | 1999 | get_req: |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 24a1cf110d80..fd6782e3a038 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2661,14 +2661,12 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 2661 | struct net *net = dev_net(dev); | 2661 | struct net *net = dev_net(dev); |
| 2662 | struct inet6_dev *idev; | 2662 | struct inet6_dev *idev; |
| 2663 | struct inet6_ifaddr *ifa; | 2663 | struct inet6_ifaddr *ifa; |
| 2664 | LIST_HEAD(keep_list); | 2664 | int state, i; |
| 2665 | int state; | ||
| 2666 | 2665 | ||
| 2667 | ASSERT_RTNL(); | 2666 | ASSERT_RTNL(); |
| 2668 | 2667 | ||
| 2669 | /* Flush routes if device is being removed or it is not loopback */ | 2668 | rt6_ifdown(net, dev); |
| 2670 | if (how || !(dev->flags & IFF_LOOPBACK)) | 2669 | neigh_ifdown(&nd_tbl, dev); |
| 2671 | rt6_ifdown(net, dev); | ||
| 2672 | 2670 | ||
| 2673 | idev = __in6_dev_get(dev); | 2671 | idev = __in6_dev_get(dev); |
| 2674 | if (idev == NULL) | 2672 | if (idev == NULL) |
| @@ -2689,6 +2687,23 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 2689 | 2687 | ||
| 2690 | } | 2688 | } |
| 2691 | 2689 | ||
| 2690 | /* Step 2: clear hash table */ | ||
| 2691 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { | ||
| 2692 | struct hlist_head *h = &inet6_addr_lst[i]; | ||
| 2693 | struct hlist_node *n; | ||
| 2694 | |||
| 2695 | spin_lock_bh(&addrconf_hash_lock); | ||
| 2696 | restart: | ||
| 2697 | hlist_for_each_entry_rcu(ifa, n, h, addr_lst) { | ||
| 2698 | if (ifa->idev == idev) { | ||
| 2699 | hlist_del_init_rcu(&ifa->addr_lst); | ||
| 2700 | addrconf_del_timer(ifa); | ||
| 2701 | goto restart; | ||
| 2702 | } | ||
| 2703 | } | ||
| 2704 | spin_unlock_bh(&addrconf_hash_lock); | ||
| 2705 | } | ||
| 2706 | |||
| 2692 | write_lock_bh(&idev->lock); | 2707 | write_lock_bh(&idev->lock); |
| 2693 | 2708 | ||
| 2694 | /* Step 2: clear flags for stateless addrconf */ | 2709 | /* Step 2: clear flags for stateless addrconf */ |
| @@ -2722,52 +2737,23 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 2722 | struct inet6_ifaddr, if_list); | 2737 | struct inet6_ifaddr, if_list); |
| 2723 | addrconf_del_timer(ifa); | 2738 | addrconf_del_timer(ifa); |
| 2724 | 2739 | ||
| 2725 | /* If just doing link down, and address is permanent | 2740 | list_del(&ifa->if_list); |
| 2726 | and not link-local, then retain it. */ | ||
| 2727 | if (!how && | ||
| 2728 | (ifa->flags&IFA_F_PERMANENT) && | ||
| 2729 | !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { | ||
| 2730 | list_move_tail(&ifa->if_list, &keep_list); | ||
| 2731 | |||
| 2732 | /* If not doing DAD on this address, just keep it. */ | ||
| 2733 | if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || | ||
| 2734 | idev->cnf.accept_dad <= 0 || | ||
| 2735 | (ifa->flags & IFA_F_NODAD)) | ||
| 2736 | continue; | ||
| 2737 | 2741 | ||
| 2738 | /* If it was tentative already, no need to notify */ | 2742 | write_unlock_bh(&idev->lock); |
| 2739 | if (ifa->flags & IFA_F_TENTATIVE) | ||
| 2740 | continue; | ||
| 2741 | 2743 | ||
| 2742 | /* Flag it for later restoration when link comes up */ | 2744 | spin_lock_bh(&ifa->state_lock); |
| 2743 | ifa->flags |= IFA_F_TENTATIVE; | 2745 | state = ifa->state; |
| 2744 | ifa->state = INET6_IFADDR_STATE_DAD; | 2746 | ifa->state = INET6_IFADDR_STATE_DEAD; |
| 2745 | } else { | 2747 | spin_unlock_bh(&ifa->state_lock); |
| 2746 | list_del(&ifa->if_list); | ||
| 2747 | |||
| 2748 | /* clear hash table */ | ||
| 2749 | spin_lock_bh(&addrconf_hash_lock); | ||
| 2750 | hlist_del_init_rcu(&ifa->addr_lst); | ||
| 2751 | spin_unlock_bh(&addrconf_hash_lock); | ||
| 2752 | |||
| 2753 | write_unlock_bh(&idev->lock); | ||
| 2754 | spin_lock_bh(&ifa->state_lock); | ||
| 2755 | state = ifa->state; | ||
| 2756 | ifa->state = INET6_IFADDR_STATE_DEAD; | ||
| 2757 | spin_unlock_bh(&ifa->state_lock); | ||
| 2758 | |||
| 2759 | if (state != INET6_IFADDR_STATE_DEAD) { | ||
| 2760 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | ||
| 2761 | atomic_notifier_call_chain(&inet6addr_chain, | ||
| 2762 | NETDEV_DOWN, ifa); | ||
| 2763 | } | ||
| 2764 | 2748 | ||
| 2765 | in6_ifa_put(ifa); | 2749 | if (state != INET6_IFADDR_STATE_DEAD) { |
| 2766 | write_lock_bh(&idev->lock); | 2750 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
| 2751 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); | ||
| 2767 | } | 2752 | } |
| 2768 | } | 2753 | in6_ifa_put(ifa); |
| 2769 | 2754 | ||
| 2770 | list_splice(&keep_list, &idev->addr_list); | 2755 | write_lock_bh(&idev->lock); |
| 2756 | } | ||
| 2771 | 2757 | ||
| 2772 | write_unlock_bh(&idev->lock); | 2758 | write_unlock_bh(&idev->lock); |
| 2773 | 2759 | ||
| @@ -4156,8 +4142,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
| 4156 | addrconf_leave_solict(ifp->idev, &ifp->addr); | 4142 | addrconf_leave_solict(ifp->idev, &ifp->addr); |
| 4157 | dst_hold(&ifp->rt->dst); | 4143 | dst_hold(&ifp->rt->dst); |
| 4158 | 4144 | ||
| 4159 | if (ifp->state == INET6_IFADDR_STATE_DEAD && | 4145 | if (ip6_del_rt(ifp->rt)) |
| 4160 | ip6_del_rt(ifp->rt)) | ||
| 4161 | dst_free(&ifp->rt->dst); | 4146 | dst_free(&ifp->rt->dst); |
| 4162 | break; | 4147 | break; |
| 4163 | } | 4148 | } |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 373bd0416f69..1534508f6c68 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -72,8 +72,6 @@ | |||
| 72 | #define RT6_TRACE(x...) do { ; } while (0) | 72 | #define RT6_TRACE(x...) do { ; } while (0) |
| 73 | #endif | 73 | #endif |
| 74 | 74 | ||
| 75 | #define CLONE_OFFLINK_ROUTE 0 | ||
| 76 | |||
| 77 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); | 75 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); |
| 78 | static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); | 76 | static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); |
| 79 | static unsigned int ip6_default_advmss(const struct dst_entry *dst); | 77 | static unsigned int ip6_default_advmss(const struct dst_entry *dst); |
| @@ -738,13 +736,8 @@ restart: | |||
| 738 | 736 | ||
| 739 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 737 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
| 740 | nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); | 738 | nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); |
| 741 | else { | 739 | else |
| 742 | #if CLONE_OFFLINK_ROUTE | ||
| 743 | nrt = rt6_alloc_clone(rt, &fl->fl6_dst); | 740 | nrt = rt6_alloc_clone(rt, &fl->fl6_dst); |
| 744 | #else | ||
| 745 | goto out2; | ||
| 746 | #endif | ||
| 747 | } | ||
| 748 | 741 | ||
| 749 | dst_release(&rt->dst); | 742 | dst_release(&rt->dst); |
| 750 | rt = nrt ? : net->ipv6.ip6_null_entry; | 743 | rt = nrt ? : net->ipv6.ip6_null_entry; |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 7e74023ea6e4..da87428681cc 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -98,6 +98,10 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
| 98 | if (!xdst->u.rt6.rt6i_idev) | 98 | if (!xdst->u.rt6.rt6i_idev) |
| 99 | return -ENODEV; | 99 | return -ENODEV; |
| 100 | 100 | ||
| 101 | xdst->u.rt6.rt6i_peer = rt->rt6i_peer; | ||
| 102 | if (rt->rt6i_peer) | ||
| 103 | atomic_inc(&rt->rt6i_peer->refcnt); | ||
| 104 | |||
| 101 | /* Sheit... I remember I did this right. Apparently, | 105 | /* Sheit... I remember I did this right. Apparently, |
| 102 | * it was magically lost, so this code needs audit */ | 106 | * it was magically lost, so this code needs audit */ |
| 103 | xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST | | 107 | xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST | |
| @@ -216,6 +220,8 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) | |||
| 216 | 220 | ||
| 217 | if (likely(xdst->u.rt6.rt6i_idev)) | 221 | if (likely(xdst->u.rt6.rt6i_idev)) |
| 218 | in6_dev_put(xdst->u.rt6.rt6i_idev); | 222 | in6_dev_put(xdst->u.rt6.rt6i_idev); |
| 223 | if (likely(xdst->u.rt6.rt6i_peer)) | ||
| 224 | inet_putpeer(xdst->u.rt6.rt6i_peer); | ||
| 219 | xfrm_dst_destroy(xdst); | 225 | xfrm_dst_destroy(xdst); |
| 220 | } | 226 | } |
| 221 | 227 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5950e3abead9..b64b42bc774b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -2230,6 +2230,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
| 2230 | 2230 | ||
| 2231 | sdata = vif_to_sdata(vif); | 2231 | sdata = vif_to_sdata(vif); |
| 2232 | 2232 | ||
| 2233 | if (!ieee80211_sdata_running(sdata)) | ||
| 2234 | goto out; | ||
| 2235 | |||
| 2233 | if (tim_offset) | 2236 | if (tim_offset) |
| 2234 | *tim_offset = 0; | 2237 | *tim_offset = 0; |
| 2235 | if (tim_length) | 2238 | if (tim_length) |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index c80d1c210c5d..5f63ec58942c 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
| @@ -390,7 +390,6 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 390 | ret = qdisc_enqueue(skb, cl->q); | 390 | ret = qdisc_enqueue(skb, cl->q); |
| 391 | if (ret == NET_XMIT_SUCCESS) { | 391 | if (ret == NET_XMIT_SUCCESS) { |
| 392 | sch->q.qlen++; | 392 | sch->q.qlen++; |
| 393 | qdisc_bstats_update(sch, skb); | ||
| 394 | cbq_mark_toplevel(q, cl); | 393 | cbq_mark_toplevel(q, cl); |
| 395 | if (!cl->next_alive) | 394 | if (!cl->next_alive) |
| 396 | cbq_activate_class(cl); | 395 | cbq_activate_class(cl); |
| @@ -649,7 +648,6 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child) | |||
| 649 | ret = qdisc_enqueue(skb, cl->q); | 648 | ret = qdisc_enqueue(skb, cl->q); |
| 650 | if (ret == NET_XMIT_SUCCESS) { | 649 | if (ret == NET_XMIT_SUCCESS) { |
| 651 | sch->q.qlen++; | 650 | sch->q.qlen++; |
| 652 | qdisc_bstats_update(sch, skb); | ||
| 653 | if (!cl->next_alive) | 651 | if (!cl->next_alive) |
| 654 | cbq_activate_class(cl); | 652 | cbq_activate_class(cl); |
| 655 | return 0; | 653 | return 0; |
| @@ -971,6 +969,7 @@ cbq_dequeue(struct Qdisc *sch) | |||
| 971 | 969 | ||
| 972 | skb = cbq_dequeue_1(sch); | 970 | skb = cbq_dequeue_1(sch); |
| 973 | if (skb) { | 971 | if (skb) { |
| 972 | qdisc_bstats_update(sch, skb); | ||
| 974 | sch->q.qlen--; | 973 | sch->q.qlen--; |
| 975 | sch->flags &= ~TCQ_F_THROTTLED; | 974 | sch->flags &= ~TCQ_F_THROTTLED; |
| 976 | return skb; | 975 | return skb; |
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index de55e642eafc..6b7fe4a84f13 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c | |||
| @@ -376,7 +376,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | bstats_update(&cl->bstats, skb); | 378 | bstats_update(&cl->bstats, skb); |
| 379 | qdisc_bstats_update(sch, skb); | ||
| 380 | 379 | ||
| 381 | sch->q.qlen++; | 380 | sch->q.qlen++; |
| 382 | return err; | 381 | return err; |
| @@ -403,6 +402,7 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch) | |||
| 403 | skb = qdisc_dequeue_peeked(cl->qdisc); | 402 | skb = qdisc_dequeue_peeked(cl->qdisc); |
| 404 | if (cl->qdisc->q.qlen == 0) | 403 | if (cl->qdisc->q.qlen == 0) |
| 405 | list_del(&cl->alist); | 404 | list_del(&cl->alist); |
| 405 | qdisc_bstats_update(sch, skb); | ||
| 406 | sch->q.qlen--; | 406 | sch->q.qlen--; |
| 407 | return skb; | 407 | return skb; |
| 408 | } | 408 | } |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 60f4bdd4408e..0f7bf3fdfea5 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
| @@ -260,7 +260,6 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 260 | return err; | 260 | return err; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | qdisc_bstats_update(sch, skb); | ||
| 264 | sch->q.qlen++; | 263 | sch->q.qlen++; |
| 265 | 264 | ||
| 266 | return NET_XMIT_SUCCESS; | 265 | return NET_XMIT_SUCCESS; |
| @@ -283,6 +282,7 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) | |||
| 283 | if (skb == NULL) | 282 | if (skb == NULL) |
| 284 | return NULL; | 283 | return NULL; |
| 285 | 284 | ||
| 285 | qdisc_bstats_update(sch, skb); | ||
| 286 | sch->q.qlen--; | 286 | sch->q.qlen--; |
| 287 | 287 | ||
| 288 | index = skb->tc_index & (p->indices - 1); | 288 | index = skb->tc_index & (p->indices - 1); |
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index aa4d6337e43c..d468b479aa93 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c | |||
| @@ -46,17 +46,14 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 46 | 46 | ||
| 47 | static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) | 47 | static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) |
| 48 | { | 48 | { |
| 49 | struct sk_buff *skb_head; | ||
| 50 | struct fifo_sched_data *q = qdisc_priv(sch); | 49 | struct fifo_sched_data *q = qdisc_priv(sch); |
| 51 | 50 | ||
| 52 | if (likely(skb_queue_len(&sch->q) < q->limit)) | 51 | if (likely(skb_queue_len(&sch->q) < q->limit)) |
| 53 | return qdisc_enqueue_tail(skb, sch); | 52 | return qdisc_enqueue_tail(skb, sch); |
| 54 | 53 | ||
| 55 | /* queue full, remove one skb to fulfill the limit */ | 54 | /* queue full, remove one skb to fulfill the limit */ |
| 56 | skb_head = qdisc_dequeue_head(sch); | 55 | __qdisc_queue_drop_head(sch, &sch->q); |
| 57 | sch->qstats.drops++; | 56 | sch->qstats.drops++; |
| 58 | kfree_skb(skb_head); | ||
| 59 | |||
| 60 | qdisc_enqueue_tail(skb, sch); | 57 | qdisc_enqueue_tail(skb, sch); |
| 61 | 58 | ||
| 62 | return NET_XMIT_CN; | 59 | return NET_XMIT_CN; |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 2e45791d4f6c..14a799de1c35 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
| @@ -1600,7 +1600,6 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 1600 | set_active(cl, qdisc_pkt_len(skb)); | 1600 | set_active(cl, qdisc_pkt_len(skb)); |
| 1601 | 1601 | ||
| 1602 | bstats_update(&cl->bstats, skb); | 1602 | bstats_update(&cl->bstats, skb); |
| 1603 | qdisc_bstats_update(sch, skb); | ||
| 1604 | sch->q.qlen++; | 1603 | sch->q.qlen++; |
| 1605 | 1604 | ||
| 1606 | return NET_XMIT_SUCCESS; | 1605 | return NET_XMIT_SUCCESS; |
| @@ -1666,6 +1665,7 @@ hfsc_dequeue(struct Qdisc *sch) | |||
| 1666 | } | 1665 | } |
| 1667 | 1666 | ||
| 1668 | sch->flags &= ~TCQ_F_THROTTLED; | 1667 | sch->flags &= ~TCQ_F_THROTTLED; |
| 1668 | qdisc_bstats_update(sch, skb); | ||
| 1669 | sch->q.qlen--; | 1669 | sch->q.qlen--; |
| 1670 | 1670 | ||
| 1671 | return skb; | 1671 | return skb; |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 984c1b0c6836..fc12fe6f5597 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
| @@ -574,7 +574,6 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | sch->q.qlen++; | 576 | sch->q.qlen++; |
| 577 | qdisc_bstats_update(sch, skb); | ||
| 578 | return NET_XMIT_SUCCESS; | 577 | return NET_XMIT_SUCCESS; |
| 579 | } | 578 | } |
| 580 | 579 | ||
| @@ -842,7 +841,7 @@ next: | |||
| 842 | 841 | ||
| 843 | static struct sk_buff *htb_dequeue(struct Qdisc *sch) | 842 | static struct sk_buff *htb_dequeue(struct Qdisc *sch) |
| 844 | { | 843 | { |
| 845 | struct sk_buff *skb = NULL; | 844 | struct sk_buff *skb; |
| 846 | struct htb_sched *q = qdisc_priv(sch); | 845 | struct htb_sched *q = qdisc_priv(sch); |
| 847 | int level; | 846 | int level; |
| 848 | psched_time_t next_event; | 847 | psched_time_t next_event; |
| @@ -851,6 +850,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
| 851 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ | 850 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ |
| 852 | skb = __skb_dequeue(&q->direct_queue); | 851 | skb = __skb_dequeue(&q->direct_queue); |
| 853 | if (skb != NULL) { | 852 | if (skb != NULL) { |
| 853 | ok: | ||
| 854 | qdisc_bstats_update(sch, skb); | ||
| 854 | sch->flags &= ~TCQ_F_THROTTLED; | 855 | sch->flags &= ~TCQ_F_THROTTLED; |
| 855 | sch->q.qlen--; | 856 | sch->q.qlen--; |
| 856 | return skb; | 857 | return skb; |
| @@ -884,11 +885,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
| 884 | int prio = ffz(m); | 885 | int prio = ffz(m); |
| 885 | m |= 1 << prio; | 886 | m |= 1 << prio; |
| 886 | skb = htb_dequeue_tree(q, prio, level); | 887 | skb = htb_dequeue_tree(q, prio, level); |
| 887 | if (likely(skb != NULL)) { | 888 | if (likely(skb != NULL)) |
| 888 | sch->q.qlen--; | 889 | goto ok; |
| 889 | sch->flags &= ~TCQ_F_THROTTLED; | ||
| 890 | goto fin; | ||
| 891 | } | ||
| 892 | } | 890 | } |
| 893 | } | 891 | } |
| 894 | sch->qstats.overlimits++; | 892 | sch->qstats.overlimits++; |
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 21f13da24763..436a2e75b322 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c | |||
| @@ -83,7 +83,6 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 83 | 83 | ||
| 84 | ret = qdisc_enqueue(skb, qdisc); | 84 | ret = qdisc_enqueue(skb, qdisc); |
| 85 | if (ret == NET_XMIT_SUCCESS) { | 85 | if (ret == NET_XMIT_SUCCESS) { |
| 86 | qdisc_bstats_update(sch, skb); | ||
| 87 | sch->q.qlen++; | 86 | sch->q.qlen++; |
| 88 | return NET_XMIT_SUCCESS; | 87 | return NET_XMIT_SUCCESS; |
| 89 | } | 88 | } |
| @@ -112,6 +111,7 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch) | |||
| 112 | qdisc = q->queues[q->curband]; | 111 | qdisc = q->queues[q->curband]; |
| 113 | skb = qdisc->dequeue(qdisc); | 112 | skb = qdisc->dequeue(qdisc); |
| 114 | if (skb) { | 113 | if (skb) { |
| 114 | qdisc_bstats_update(sch, skb); | ||
| 115 | sch->q.qlen--; | 115 | sch->q.qlen--; |
| 116 | return skb; | 116 | return skb; |
| 117 | } | 117 | } |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 1c4bce863479..6a3006b38dc5 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -240,7 +240,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 240 | 240 | ||
| 241 | if (likely(ret == NET_XMIT_SUCCESS)) { | 241 | if (likely(ret == NET_XMIT_SUCCESS)) { |
| 242 | sch->q.qlen++; | 242 | sch->q.qlen++; |
| 243 | qdisc_bstats_update(sch, skb); | ||
| 244 | } else if (net_xmit_drop_count(ret)) { | 243 | } else if (net_xmit_drop_count(ret)) { |
| 245 | sch->qstats.drops++; | 244 | sch->qstats.drops++; |
| 246 | } | 245 | } |
| @@ -289,6 +288,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) | |||
| 289 | skb->tstamp.tv64 = 0; | 288 | skb->tstamp.tv64 = 0; |
| 290 | #endif | 289 | #endif |
| 291 | pr_debug("netem_dequeue: return skb=%p\n", skb); | 290 | pr_debug("netem_dequeue: return skb=%p\n", skb); |
| 291 | qdisc_bstats_update(sch, skb); | ||
| 292 | sch->q.qlen--; | 292 | sch->q.qlen--; |
| 293 | return skb; | 293 | return skb; |
| 294 | } | 294 | } |
| @@ -476,7 +476,6 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) | |||
| 476 | __skb_queue_after(list, skb, nskb); | 476 | __skb_queue_after(list, skb, nskb); |
| 477 | 477 | ||
| 478 | sch->qstats.backlog += qdisc_pkt_len(nskb); | 478 | sch->qstats.backlog += qdisc_pkt_len(nskb); |
| 479 | qdisc_bstats_update(sch, nskb); | ||
| 480 | 479 | ||
| 481 | return NET_XMIT_SUCCESS; | 480 | return NET_XMIT_SUCCESS; |
| 482 | } | 481 | } |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 966158d49dd1..fbd710d619bf 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
| @@ -84,7 +84,6 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 84 | 84 | ||
| 85 | ret = qdisc_enqueue(skb, qdisc); | 85 | ret = qdisc_enqueue(skb, qdisc); |
| 86 | if (ret == NET_XMIT_SUCCESS) { | 86 | if (ret == NET_XMIT_SUCCESS) { |
| 87 | qdisc_bstats_update(sch, skb); | ||
| 88 | sch->q.qlen++; | 87 | sch->q.qlen++; |
| 89 | return NET_XMIT_SUCCESS; | 88 | return NET_XMIT_SUCCESS; |
| 90 | } | 89 | } |
| @@ -116,6 +115,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc* sch) | |||
| 116 | struct Qdisc *qdisc = q->queues[prio]; | 115 | struct Qdisc *qdisc = q->queues[prio]; |
| 117 | struct sk_buff *skb = qdisc->dequeue(qdisc); | 116 | struct sk_buff *skb = qdisc->dequeue(qdisc); |
| 118 | if (skb) { | 117 | if (skb) { |
| 118 | qdisc_bstats_update(sch, skb); | ||
| 119 | sch->q.qlen--; | 119 | sch->q.qlen--; |
| 120 | return skb; | 120 | return skb; |
| 121 | } | 121 | } |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index a6009c5a2c97..9f98dbd32d4c 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
| @@ -94,7 +94,6 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 94 | 94 | ||
| 95 | ret = qdisc_enqueue(skb, child); | 95 | ret = qdisc_enqueue(skb, child); |
| 96 | if (likely(ret == NET_XMIT_SUCCESS)) { | 96 | if (likely(ret == NET_XMIT_SUCCESS)) { |
| 97 | qdisc_bstats_update(sch, skb); | ||
| 98 | sch->q.qlen++; | 97 | sch->q.qlen++; |
| 99 | } else if (net_xmit_drop_count(ret)) { | 98 | } else if (net_xmit_drop_count(ret)) { |
| 100 | q->stats.pdrop++; | 99 | q->stats.pdrop++; |
| @@ -114,11 +113,13 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch) | |||
| 114 | struct Qdisc *child = q->qdisc; | 113 | struct Qdisc *child = q->qdisc; |
| 115 | 114 | ||
| 116 | skb = child->dequeue(child); | 115 | skb = child->dequeue(child); |
| 117 | if (skb) | 116 | if (skb) { |
| 117 | qdisc_bstats_update(sch, skb); | ||
| 118 | sch->q.qlen--; | 118 | sch->q.qlen--; |
| 119 | else if (!red_is_idling(&q->parms)) | 119 | } else { |
| 120 | red_start_of_idle_period(&q->parms); | 120 | if (!red_is_idling(&q->parms)) |
| 121 | 121 | red_start_of_idle_period(&q->parms); | |
| 122 | } | ||
| 122 | return skb; | 123 | return skb; |
| 123 | } | 124 | } |
| 124 | 125 | ||
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 239ec53a634d..edea8cefec6c 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
| @@ -402,10 +402,8 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 402 | q->tail = slot; | 402 | q->tail = slot; |
| 403 | slot->allot = q->scaled_quantum; | 403 | slot->allot = q->scaled_quantum; |
| 404 | } | 404 | } |
| 405 | if (++sch->q.qlen <= q->limit) { | 405 | if (++sch->q.qlen <= q->limit) |
| 406 | qdisc_bstats_update(sch, skb); | ||
| 407 | return NET_XMIT_SUCCESS; | 406 | return NET_XMIT_SUCCESS; |
| 408 | } | ||
| 409 | 407 | ||
| 410 | sfq_drop(sch); | 408 | sfq_drop(sch); |
| 411 | return NET_XMIT_CN; | 409 | return NET_XMIT_CN; |
| @@ -445,6 +443,7 @@ next_slot: | |||
| 445 | } | 443 | } |
| 446 | skb = slot_dequeue_head(slot); | 444 | skb = slot_dequeue_head(slot); |
| 447 | sfq_dec(q, a); | 445 | sfq_dec(q, a); |
| 446 | qdisc_bstats_update(sch, skb); | ||
| 448 | sch->q.qlen--; | 447 | sch->q.qlen--; |
| 449 | sch->qstats.backlog -= qdisc_pkt_len(skb); | 448 | sch->qstats.backlog -= qdisc_pkt_len(skb); |
| 450 | 449 | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 77565e721811..e93165820c3f 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
| @@ -134,7 +134,6 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | sch->q.qlen++; | 136 | sch->q.qlen++; |
| 137 | qdisc_bstats_update(sch, skb); | ||
| 138 | return NET_XMIT_SUCCESS; | 137 | return NET_XMIT_SUCCESS; |
| 139 | } | 138 | } |
| 140 | 139 | ||
| @@ -187,6 +186,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) | |||
| 187 | q->ptokens = ptoks; | 186 | q->ptokens = ptoks; |
| 188 | sch->q.qlen--; | 187 | sch->q.qlen--; |
| 189 | sch->flags &= ~TCQ_F_THROTTLED; | 188 | sch->flags &= ~TCQ_F_THROTTLED; |
| 189 | qdisc_bstats_update(sch, skb); | ||
| 190 | return skb; | 190 | return skb; |
| 191 | } | 191 | } |
| 192 | 192 | ||
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 84ce48eadff4..d84e7329660f 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
| @@ -87,7 +87,6 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 87 | 87 | ||
| 88 | if (q->q.qlen < dev->tx_queue_len) { | 88 | if (q->q.qlen < dev->tx_queue_len) { |
| 89 | __skb_queue_tail(&q->q, skb); | 89 | __skb_queue_tail(&q->q, skb); |
| 90 | qdisc_bstats_update(sch, skb); | ||
| 91 | return NET_XMIT_SUCCESS; | 90 | return NET_XMIT_SUCCESS; |
| 92 | } | 91 | } |
| 93 | 92 | ||
| @@ -111,6 +110,8 @@ teql_dequeue(struct Qdisc* sch) | |||
| 111 | dat->m->slaves = sch; | 110 | dat->m->slaves = sch; |
| 112 | netif_wake_queue(m); | 111 | netif_wake_queue(m); |
| 113 | } | 112 | } |
| 113 | } else { | ||
| 114 | qdisc_bstats_update(sch, skb); | ||
| 114 | } | 115 | } |
| 115 | sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen; | 116 | sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen; |
| 116 | return skb; | 117 | return skb; |
