diff options
Diffstat (limited to 'net')
96 files changed, 674 insertions, 410 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 6089f0cf23b4..9096bcb08132 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -403,6 +403,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 403 | break; | 403 | break; |
| 404 | 404 | ||
| 405 | case NETDEV_DOWN: | 405 | case NETDEV_DOWN: |
| 406 | if (dev->features & NETIF_F_HW_VLAN_FILTER) | ||
| 407 | vlan_vid_del(dev, 0); | ||
| 408 | |||
| 406 | /* Put all VLANs for this dev in the down state too. */ | 409 | /* Put all VLANs for this dev in the down state too. */ |
| 407 | for (i = 0; i < VLAN_N_VID; i++) { | 410 | for (i = 0; i < VLAN_N_VID; i++) { |
| 408 | vlandev = vlan_group_get_device(grp, i); | 411 | vlandev = vlan_group_get_device(grp, i); |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 9ee48cb30179..3d33ecf13327 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
| @@ -368,7 +368,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
| 368 | const char *sptr = va_arg(ap, const char *); | 368 | const char *sptr = va_arg(ap, const char *); |
| 369 | uint16_t len = 0; | 369 | uint16_t len = 0; |
| 370 | if (sptr) | 370 | if (sptr) |
| 371 | len = min_t(uint16_t, strlen(sptr), | 371 | len = min_t(size_t, strlen(sptr), |
| 372 | USHRT_MAX); | 372 | USHRT_MAX); |
| 373 | 373 | ||
| 374 | errcode = p9pdu_writef(pdu, proto_version, | 374 | errcode = p9pdu_writef(pdu, proto_version, |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 5af18d11b518..2a167658bb95 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -192,10 +192,10 @@ static int pack_sg_list(struct scatterlist *sg, int start, | |||
| 192 | s = rest_of_page(data); | 192 | s = rest_of_page(data); |
| 193 | if (s > count) | 193 | if (s > count) |
| 194 | s = count; | 194 | s = count; |
| 195 | BUG_ON(index > limit); | ||
| 195 | sg_set_buf(&sg[index++], data, s); | 196 | sg_set_buf(&sg[index++], data, s); |
| 196 | count -= s; | 197 | count -= s; |
| 197 | data += s; | 198 | data += s; |
| 198 | BUG_ON(index > limit); | ||
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | return index-start; | 201 | return index-start; |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 0301b328cf0f..86852963b7f7 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
| @@ -1208,9 +1208,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 1208 | if (addr->sat_addr.s_node == ATADDR_BCAST && | 1208 | if (addr->sat_addr.s_node == ATADDR_BCAST && |
| 1209 | !sock_flag(sk, SOCK_BROADCAST)) { | 1209 | !sock_flag(sk, SOCK_BROADCAST)) { |
| 1210 | #if 1 | 1210 | #if 1 |
| 1211 | printk(KERN_WARNING "%s is broken and did not set " | 1211 | pr_warn("atalk_connect: %s is broken and did not set SO_BROADCAST.\n", |
| 1212 | "SO_BROADCAST. It will break when 2.2 is " | ||
| 1213 | "released.\n", | ||
| 1214 | current->comm); | 1212 | current->comm); |
| 1215 | #else | 1213 | #else |
| 1216 | return -EACCES; | 1214 | return -EACCES; |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 051f7abae66d..779095ded689 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
| @@ -842,6 +842,7 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol, | |||
| 842 | case AX25_P_NETROM: | 842 | case AX25_P_NETROM: |
| 843 | if (ax25_protocol_is_registered(AX25_P_NETROM)) | 843 | if (ax25_protocol_is_registered(AX25_P_NETROM)) |
| 844 | return -ESOCKTNOSUPPORT; | 844 | return -ESOCKTNOSUPPORT; |
| 845 | break; | ||
| 845 | #endif | 846 | #endif |
| 846 | #ifdef CONFIG_ROSE_MODULE | 847 | #ifdef CONFIG_ROSE_MODULE |
| 847 | case AX25_P_ROSE: | 848 | case AX25_P_ROSE: |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 8bf97515a77d..c5863f499133 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
| @@ -1351,6 +1351,7 @@ void bla_free(struct bat_priv *bat_priv) | |||
| 1351 | * @bat_priv: the bat priv with all the soft interface information | 1351 | * @bat_priv: the bat priv with all the soft interface information |
| 1352 | * @skb: the frame to be checked | 1352 | * @skb: the frame to be checked |
| 1353 | * @vid: the VLAN ID of the frame | 1353 | * @vid: the VLAN ID of the frame |
| 1354 | * @is_bcast: the packet came in a broadcast packet type. | ||
| 1354 | * | 1355 | * |
| 1355 | * bla_rx avoidance checks if: | 1356 | * bla_rx avoidance checks if: |
| 1356 | * * we have to race for a claim | 1357 | * * we have to race for a claim |
| @@ -1361,7 +1362,8 @@ void bla_free(struct bat_priv *bat_priv) | |||
| 1361 | * process the skb. | 1362 | * process the skb. |
| 1362 | * | 1363 | * |
| 1363 | */ | 1364 | */ |
| 1364 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) | 1365 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid, |
| 1366 | bool is_bcast) | ||
| 1365 | { | 1367 | { |
| 1366 | struct ethhdr *ethhdr; | 1368 | struct ethhdr *ethhdr; |
| 1367 | struct claim search_claim, *claim = NULL; | 1369 | struct claim search_claim, *claim = NULL; |
| @@ -1380,7 +1382,7 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) | |||
| 1380 | 1382 | ||
| 1381 | if (unlikely(atomic_read(&bat_priv->bla_num_requests))) | 1383 | if (unlikely(atomic_read(&bat_priv->bla_num_requests))) |
| 1382 | /* don't allow broadcasts while requests are in flight */ | 1384 | /* don't allow broadcasts while requests are in flight */ |
| 1383 | if (is_multicast_ether_addr(ethhdr->h_dest)) | 1385 | if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) |
| 1384 | goto handled; | 1386 | goto handled; |
| 1385 | 1387 | ||
| 1386 | memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); | 1388 | memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); |
| @@ -1406,8 +1408,13 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) | |||
| 1406 | } | 1408 | } |
| 1407 | 1409 | ||
| 1408 | /* if it is a broadcast ... */ | 1410 | /* if it is a broadcast ... */ |
| 1409 | if (is_multicast_ether_addr(ethhdr->h_dest)) { | 1411 | if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) { |
| 1410 | /* ... drop it. the responsible gateway is in charge. */ | 1412 | /* ... drop it. the responsible gateway is in charge. |
| 1413 | * | ||
| 1414 | * We need to check is_bcast because with the gateway | ||
| 1415 | * feature, broadcasts (like DHCP requests) may be sent | ||
| 1416 | * using a unicast packet type. | ||
| 1417 | */ | ||
| 1411 | goto handled; | 1418 | goto handled; |
| 1412 | } else { | 1419 | } else { |
| 1413 | /* seems the client considers us as its best gateway. | 1420 | /* seems the client considers us as its best gateway. |
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index e39f93acc28f..dc5227b398d4 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h | |||
| @@ -23,7 +23,8 @@ | |||
| 23 | #define _NET_BATMAN_ADV_BLA_H_ | 23 | #define _NET_BATMAN_ADV_BLA_H_ |
| 24 | 24 | ||
| 25 | #ifdef CONFIG_BATMAN_ADV_BLA | 25 | #ifdef CONFIG_BATMAN_ADV_BLA |
| 26 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); | 26 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid, |
| 27 | bool is_bcast); | ||
| 27 | int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); | 28 | int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); |
| 28 | int bla_is_backbone_gw(struct sk_buff *skb, | 29 | int bla_is_backbone_gw(struct sk_buff *skb, |
| 29 | struct orig_node *orig_node, int hdr_size); | 30 | struct orig_node *orig_node, int hdr_size); |
| @@ -41,7 +42,7 @@ void bla_free(struct bat_priv *bat_priv); | |||
| 41 | #else /* ifdef CONFIG_BATMAN_ADV_BLA */ | 42 | #else /* ifdef CONFIG_BATMAN_ADV_BLA */ |
| 42 | 43 | ||
| 43 | static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, | 44 | static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, |
| 44 | short vid) | 45 | short vid, bool is_bcast) |
| 45 | { | 46 | { |
| 46 | return 0; | 47 | return 0; |
| 47 | } | 48 | } |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 840e2c64a301..015471d801b4 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
| @@ -617,6 +617,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) | |||
| 617 | * changes */ | 617 | * changes */ |
| 618 | if (skb_linearize(skb) < 0) | 618 | if (skb_linearize(skb) < 0) |
| 619 | goto out; | 619 | goto out; |
| 620 | /* skb_linearize() possibly changed skb->data */ | ||
| 621 | tt_query = (struct tt_query_packet *)skb->data; | ||
| 620 | 622 | ||
| 621 | tt_len = tt_query->tt_data * sizeof(struct tt_change); | 623 | tt_len = tt_query->tt_data * sizeof(struct tt_change); |
| 622 | 624 | ||
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 6e2530b02043..a0ec0e4ada4c 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
| @@ -256,7 +256,11 @@ void interface_rx(struct net_device *soft_iface, | |||
| 256 | struct bat_priv *bat_priv = netdev_priv(soft_iface); | 256 | struct bat_priv *bat_priv = netdev_priv(soft_iface); |
| 257 | struct ethhdr *ethhdr; | 257 | struct ethhdr *ethhdr; |
| 258 | struct vlan_ethhdr *vhdr; | 258 | struct vlan_ethhdr *vhdr; |
| 259 | struct batman_header *batadv_header = (struct batman_header *)skb->data; | ||
| 259 | short vid __maybe_unused = -1; | 260 | short vid __maybe_unused = -1; |
| 261 | bool is_bcast; | ||
| 262 | |||
| 263 | is_bcast = (batadv_header->packet_type == BAT_BCAST); | ||
| 260 | 264 | ||
| 261 | /* check if enough space is available for pulling, and pull */ | 265 | /* check if enough space is available for pulling, and pull */ |
| 262 | if (!pskb_may_pull(skb, hdr_size)) | 266 | if (!pskb_may_pull(skb, hdr_size)) |
| @@ -302,7 +306,7 @@ void interface_rx(struct net_device *soft_iface, | |||
| 302 | /* Let the bridge loop avoidance check the packet. If will | 306 | /* Let the bridge loop avoidance check the packet. If will |
| 303 | * not handle it, we can safely push it up. | 307 | * not handle it, we can safely push it up. |
| 304 | */ | 308 | */ |
| 305 | if (bla_rx(bat_priv, skb, vid)) | 309 | if (bla_rx(bat_priv, skb, vid, is_bcast)) |
| 306 | goto out; | 310 | goto out; |
| 307 | 311 | ||
| 308 | netif_rx(skb); | 312 | netif_rx(skb); |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a66c2dcd1088..2ab83d7fb1f8 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
| @@ -141,13 +141,14 @@ static void tt_orig_list_entry_free_rcu(struct rcu_head *rcu) | |||
| 141 | struct tt_orig_list_entry *orig_entry; | 141 | struct tt_orig_list_entry *orig_entry; |
| 142 | 142 | ||
| 143 | orig_entry = container_of(rcu, struct tt_orig_list_entry, rcu); | 143 | orig_entry = container_of(rcu, struct tt_orig_list_entry, rcu); |
| 144 | atomic_dec(&orig_entry->orig_node->tt_size); | ||
| 145 | orig_node_free_ref(orig_entry->orig_node); | 144 | orig_node_free_ref(orig_entry->orig_node); |
| 146 | kfree(orig_entry); | 145 | kfree(orig_entry); |
| 147 | } | 146 | } |
| 148 | 147 | ||
| 149 | static void tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) | 148 | static void tt_orig_list_entry_free_ref(struct tt_orig_list_entry *orig_entry) |
| 150 | { | 149 | { |
| 150 | /* to avoid race conditions, immediately decrease the tt counter */ | ||
| 151 | atomic_dec(&orig_entry->orig_node->tt_size); | ||
| 151 | call_rcu(&orig_entry->rcu, tt_orig_list_entry_free_rcu); | 152 | call_rcu(&orig_entry->rcu, tt_orig_list_entry_free_rcu); |
| 152 | } | 153 | } |
| 153 | 154 | ||
| @@ -910,7 +911,6 @@ void tt_global_del_orig(struct bat_priv *bat_priv, | |||
| 910 | } | 911 | } |
| 911 | spin_unlock_bh(list_lock); | 912 | spin_unlock_bh(list_lock); |
| 912 | } | 913 | } |
| 913 | atomic_set(&orig_node->tt_size, 0); | ||
| 914 | orig_node->tt_initialised = false; | 914 | orig_node->tt_initialised = false; |
| 915 | } | 915 | } |
| 916 | 916 | ||
| @@ -2031,10 +2031,10 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) | |||
| 2031 | { | 2031 | { |
| 2032 | struct tt_local_entry *tt_local_entry = NULL; | 2032 | struct tt_local_entry *tt_local_entry = NULL; |
| 2033 | struct tt_global_entry *tt_global_entry = NULL; | 2033 | struct tt_global_entry *tt_global_entry = NULL; |
| 2034 | bool ret = true; | 2034 | bool ret = false; |
| 2035 | 2035 | ||
| 2036 | if (!atomic_read(&bat_priv->ap_isolation)) | 2036 | if (!atomic_read(&bat_priv->ap_isolation)) |
| 2037 | return false; | 2037 | goto out; |
| 2038 | 2038 | ||
| 2039 | tt_local_entry = tt_local_hash_find(bat_priv, dst); | 2039 | tt_local_entry = tt_local_hash_find(bat_priv, dst); |
| 2040 | if (!tt_local_entry) | 2040 | if (!tt_local_entry) |
| @@ -2044,10 +2044,10 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) | |||
| 2044 | if (!tt_global_entry) | 2044 | if (!tt_global_entry) |
| 2045 | goto out; | 2045 | goto out; |
| 2046 | 2046 | ||
| 2047 | if (_is_ap_isolated(tt_local_entry, tt_global_entry)) | 2047 | if (!_is_ap_isolated(tt_local_entry, tt_global_entry)) |
| 2048 | goto out; | 2048 | goto out; |
| 2049 | 2049 | ||
| 2050 | ret = false; | 2050 | ret = true; |
| 2051 | 2051 | ||
| 2052 | out: | 2052 | out: |
| 2053 | if (tt_global_entry) | 2053 | if (tt_global_entry) |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 46e7f86acfc9..3e18af4dadc4 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
| @@ -210,7 +210,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | if (sk->sk_state == BT_CONNECTED || !newsock || | 212 | if (sk->sk_state == BT_CONNECTED || !newsock || |
| 213 | test_bit(BT_DEFER_SETUP, &bt_sk(parent)->flags)) { | 213 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) { |
| 214 | bt_accept_unlink(sk); | 214 | bt_accept_unlink(sk); |
| 215 | if (newsock) | 215 | if (newsock) |
| 216 | sock_graft(sk, newsock); | 216 | sock_graft(sk, newsock); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4eefb7f65cf6..94ad124a4ea3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
| @@ -3043,6 +3043,50 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
| 3043 | hci_dev_unlock(hdev); | 3043 | hci_dev_unlock(hdev); |
| 3044 | } | 3044 | } |
| 3045 | 3045 | ||
| 3046 | static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | ||
| 3047 | struct sk_buff *skb) | ||
| 3048 | { | ||
| 3049 | struct hci_ev_key_refresh_complete *ev = (void *) skb->data; | ||
| 3050 | struct hci_conn *conn; | ||
| 3051 | |||
| 3052 | BT_DBG("%s status %u handle %u", hdev->name, ev->status, | ||
| 3053 | __le16_to_cpu(ev->handle)); | ||
| 3054 | |||
| 3055 | hci_dev_lock(hdev); | ||
| 3056 | |||
| 3057 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
| 3058 | if (!conn) | ||
| 3059 | goto unlock; | ||
| 3060 | |||
| 3061 | if (!ev->status) | ||
| 3062 | conn->sec_level = conn->pending_sec_level; | ||
| 3063 | |||
| 3064 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | ||
| 3065 | |||
| 3066 | if (ev->status && conn->state == BT_CONNECTED) { | ||
| 3067 | hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE); | ||
| 3068 | hci_conn_put(conn); | ||
| 3069 | goto unlock; | ||
| 3070 | } | ||
| 3071 | |||
| 3072 | if (conn->state == BT_CONFIG) { | ||
| 3073 | if (!ev->status) | ||
| 3074 | conn->state = BT_CONNECTED; | ||
| 3075 | |||
| 3076 | hci_proto_connect_cfm(conn, ev->status); | ||
| 3077 | hci_conn_put(conn); | ||
| 3078 | } else { | ||
| 3079 | hci_auth_cfm(conn, ev->status); | ||
| 3080 | |||
| 3081 | hci_conn_hold(conn); | ||
| 3082 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
| 3083 | hci_conn_put(conn); | ||
| 3084 | } | ||
| 3085 | |||
| 3086 | unlock: | ||
| 3087 | hci_dev_unlock(hdev); | ||
| 3088 | } | ||
| 3089 | |||
| 3046 | static inline u8 hci_get_auth_req(struct hci_conn *conn) | 3090 | static inline u8 hci_get_auth_req(struct hci_conn *conn) |
| 3047 | { | 3091 | { |
| 3048 | /* If remote requests dedicated bonding follow that lead */ | 3092 | /* If remote requests dedicated bonding follow that lead */ |
| @@ -3559,6 +3603,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 3559 | hci_extended_inquiry_result_evt(hdev, skb); | 3603 | hci_extended_inquiry_result_evt(hdev, skb); |
| 3560 | break; | 3604 | break; |
| 3561 | 3605 | ||
| 3606 | case HCI_EV_KEY_REFRESH_COMPLETE: | ||
| 3607 | hci_key_refresh_complete_evt(hdev, skb); | ||
| 3608 | break; | ||
| 3609 | |||
| 3562 | case HCI_EV_IO_CAPA_REQUEST: | 3610 | case HCI_EV_IO_CAPA_REQUEST: |
| 3563 | hci_io_capa_request_evt(hdev, skb); | 3611 | hci_io_capa_request_evt(hdev, skb); |
| 3564 | break; | 3612 | break; |
diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 4deaca78e91e..9332bc7aa851 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config BT_HIDP | 1 | config BT_HIDP |
| 2 | tristate "HIDP protocol support" | 2 | tristate "HIDP protocol support" |
| 3 | depends on BT && INPUT && HID_SUPPORT | 3 | depends on BT && INPUT |
| 4 | select HID | 4 | select HID |
| 5 | help | 5 | help |
| 6 | HIDP (Human Interface Device Protocol) is a transport layer | 6 | HIDP (Human Interface Device Protocol) is a transport layer |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 24f144b72a96..4554e80d16a3 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -1295,7 +1295,12 @@ static void security_timeout(struct work_struct *work) | |||
| 1295 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, | 1295 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
| 1296 | security_timer.work); | 1296 | security_timer.work); |
| 1297 | 1297 | ||
| 1298 | l2cap_conn_del(conn->hcon, ETIMEDOUT); | 1298 | BT_DBG("conn %p", conn); |
| 1299 | |||
| 1300 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { | ||
| 1301 | smp_chan_destroy(conn); | ||
| 1302 | l2cap_conn_del(conn->hcon, ETIMEDOUT); | ||
| 1303 | } | ||
| 1299 | } | 1304 | } |
| 1300 | 1305 | ||
| 1301 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 1306 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) |
| @@ -2910,12 +2915,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) | |||
| 2910 | while (len >= L2CAP_CONF_OPT_SIZE) { | 2915 | while (len >= L2CAP_CONF_OPT_SIZE) { |
| 2911 | len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); | 2916 | len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); |
| 2912 | 2917 | ||
| 2913 | switch (type) { | 2918 | if (type != L2CAP_CONF_RFC) |
| 2914 | case L2CAP_CONF_RFC: | 2919 | continue; |
| 2915 | if (olen == sizeof(rfc)) | 2920 | |
| 2916 | memcpy(&rfc, (void *)val, olen); | 2921 | if (olen != sizeof(rfc)) |
| 2917 | goto done; | 2922 | break; |
| 2918 | } | 2923 | |
| 2924 | memcpy(&rfc, (void *)val, olen); | ||
| 2925 | goto done; | ||
| 2919 | } | 2926 | } |
| 2920 | 2927 | ||
| 2921 | /* Use sane default values in case a misbehaving remote device | 2928 | /* Use sane default values in case a misbehaving remote device |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 25d220776079..3e5e3362ea00 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
| @@ -1598,7 +1598,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 1598 | else | 1598 | else |
| 1599 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); | 1599 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); |
| 1600 | 1600 | ||
| 1601 | if (!conn) { | 1601 | if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { |
| 1602 | err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, | 1602 | err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, |
| 1603 | MGMT_STATUS_NOT_CONNECTED); | 1603 | MGMT_STATUS_NOT_CONNECTED); |
| 1604 | goto failed; | 1604 | goto failed; |
| @@ -1873,6 +1873,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) | |||
| 1873 | pairing_complete(cmd, mgmt_status(status)); | 1873 | pairing_complete(cmd, mgmt_status(status)); |
| 1874 | } | 1874 | } |
| 1875 | 1875 | ||
| 1876 | static void le_connect_complete_cb(struct hci_conn *conn, u8 status) | ||
| 1877 | { | ||
| 1878 | struct pending_cmd *cmd; | ||
| 1879 | |||
| 1880 | BT_DBG("status %u", status); | ||
| 1881 | |||
| 1882 | if (!status) | ||
| 1883 | return; | ||
| 1884 | |||
| 1885 | cmd = find_pairing(conn); | ||
| 1886 | if (!cmd) | ||
| 1887 | BT_DBG("Unable to find a pending command"); | ||
| 1888 | else | ||
| 1889 | pairing_complete(cmd, mgmt_status(status)); | ||
| 1890 | } | ||
| 1891 | |||
| 1876 | static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | 1892 | static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, |
| 1877 | u16 len) | 1893 | u16 len) |
| 1878 | { | 1894 | { |
| @@ -1934,6 +1950,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
| 1934 | /* For LE, just connecting isn't a proof that the pairing finished */ | 1950 | /* For LE, just connecting isn't a proof that the pairing finished */ |
| 1935 | if (cp->addr.type == BDADDR_BREDR) | 1951 | if (cp->addr.type == BDADDR_BREDR) |
| 1936 | conn->connect_cfm_cb = pairing_complete_cb; | 1952 | conn->connect_cfm_cb = pairing_complete_cb; |
| 1953 | else | ||
| 1954 | conn->connect_cfm_cb = le_connect_complete_cb; | ||
| 1937 | 1955 | ||
| 1938 | conn->security_cfm_cb = pairing_complete_cb; | 1956 | conn->security_cfm_cb = pairing_complete_cb; |
| 1939 | conn->disconn_cfm_cb = pairing_complete_cb; | 1957 | conn->disconn_cfm_cb = pairing_complete_cb; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6fc7c4708f3e..37df4e9b3896 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
| @@ -648,7 +648,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
| 648 | 648 | ||
| 649 | auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; | 649 | auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; |
| 650 | 650 | ||
| 651 | ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability); | 651 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); |
| 652 | if (ret) | 652 | if (ret) |
| 653 | return SMP_UNSPECIFIED; | 653 | return SMP_UNSPECIFIED; |
| 654 | 654 | ||
| @@ -703,7 +703,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | |||
| 703 | return 0; | 703 | return 0; |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | static u8 smp_ltk_encrypt(struct l2cap_conn *conn) | 706 | static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) |
| 707 | { | 707 | { |
| 708 | struct smp_ltk *key; | 708 | struct smp_ltk *key; |
| 709 | struct hci_conn *hcon = conn->hcon; | 709 | struct hci_conn *hcon = conn->hcon; |
| @@ -712,6 +712,9 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn) | |||
| 712 | if (!key) | 712 | if (!key) |
| 713 | return 0; | 713 | return 0; |
| 714 | 714 | ||
| 715 | if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) | ||
| 716 | return 0; | ||
| 717 | |||
| 715 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) | 718 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) |
| 716 | return 1; | 719 | return 1; |
| 717 | 720 | ||
| @@ -732,7 +735,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
| 732 | 735 | ||
| 733 | hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); | 736 | hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); |
| 734 | 737 | ||
| 735 | if (smp_ltk_encrypt(conn)) | 738 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) |
| 736 | return 0; | 739 | return 0; |
| 737 | 740 | ||
| 738 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 741 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) |
| @@ -771,7 +774,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | |||
| 771 | return 1; | 774 | return 1; |
| 772 | 775 | ||
| 773 | if (hcon->link_mode & HCI_LM_MASTER) | 776 | if (hcon->link_mode & HCI_LM_MASTER) |
| 774 | if (smp_ltk_encrypt(conn)) | 777 | if (smp_ltk_encrypt(conn, sec_level)) |
| 775 | goto done; | 778 | goto done; |
| 776 | 779 | ||
| 777 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 780 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 0a942fbccc9a..e1144e1617be 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -240,6 +240,7 @@ int br_add_bridge(struct net *net, const char *name) | |||
| 240 | return -ENOMEM; | 240 | return -ENOMEM; |
| 241 | 241 | ||
| 242 | dev_net_set(dev, net); | 242 | dev_net_set(dev, net); |
| 243 | dev->rtnl_link_ops = &br_link_ops; | ||
| 243 | 244 | ||
| 244 | res = register_netdev(dev); | 245 | res = register_netdev(dev); |
| 245 | if (res) | 246 | if (res) |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2080485515f1..fe41260fbf38 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
| @@ -208,7 +208,7 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) | |||
| 208 | return 0; | 208 | return 0; |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static struct rtnl_link_ops br_link_ops __read_mostly = { | 211 | struct rtnl_link_ops br_link_ops __read_mostly = { |
| 212 | .kind = "bridge", | 212 | .kind = "bridge", |
| 213 | .priv_size = sizeof(struct net_bridge), | 213 | .priv_size = sizeof(struct net_bridge), |
| 214 | .setup = br_dev_setup, | 214 | .setup = br_dev_setup, |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1a8ad4fb9a6b..a768b2408edf 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -549,6 +549,7 @@ extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr) | |||
| 549 | #endif | 549 | #endif |
| 550 | 550 | ||
| 551 | /* br_netlink.c */ | 551 | /* br_netlink.c */ |
| 552 | extern struct rtnl_link_ops br_link_ops; | ||
| 552 | extern int br_netlink_init(void); | 553 | extern int br_netlink_init(void); |
| 553 | extern void br_netlink_fini(void); | 554 | extern void br_netlink_fini(void); |
| 554 | extern void br_ifinfo_notify(int event, struct net_bridge_port *port); | 555 | extern void br_ifinfo_notify(int event, struct net_bridge_port *port); |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index aa6f716524fd..8c83c175b03a 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
| @@ -4,8 +4,7 @@ | |||
| 4 | * Author: Sjur Brendeland/sjur.brandeland@stericsson.com | 4 | * Author: Sjur Brendeland/sjur.brandeland@stericsson.com |
| 5 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
| 6 | * | 6 | * |
| 7 | * Borrowed heavily from file: pn_dev.c. Thanks to | 7 | * Borrowed heavily from file: pn_dev.c. Thanks to Remi Denis-Courmont |
| 8 | * Remi Denis-Courmont <remi.denis-courmont@nokia.com> | ||
| 9 | * and Sakari Ailus <sakari.ailus@nokia.com> | 8 | * and Sakari Ailus <sakari.ailus@nokia.com> |
| 10 | */ | 9 | */ |
| 11 | 10 | ||
| @@ -562,9 +561,9 @@ static int __init caif_device_init(void) | |||
| 562 | 561 | ||
| 563 | static void __exit caif_device_exit(void) | 562 | static void __exit caif_device_exit(void) |
| 564 | { | 563 | { |
| 565 | unregister_pernet_subsys(&caif_net_ops); | ||
| 566 | unregister_netdevice_notifier(&caif_device_notifier); | 564 | unregister_netdevice_notifier(&caif_device_notifier); |
| 567 | dev_remove_pack(&caif_packet_type); | 565 | dev_remove_pack(&caif_packet_type); |
| 566 | unregister_pernet_subsys(&caif_net_ops); | ||
| 568 | } | 567 | } |
| 569 | 568 | ||
| 570 | module_init(caif_device_init); | 569 | module_init(caif_device_init); |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index fb8944355264..78f1cdad5b33 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
| @@ -220,6 +220,7 @@ static void caif_ctrl_cb(struct cflayer *layr, | |||
| 220 | cfsk_hold, cfsk_put); | 220 | cfsk_hold, cfsk_put); |
| 221 | cf_sk->sk.sk_state = CAIF_CONNECTED; | 221 | cf_sk->sk.sk_state = CAIF_CONNECTED; |
| 222 | set_tx_flow_on(cf_sk); | 222 | set_tx_flow_on(cf_sk); |
| 223 | cf_sk->sk.sk_shutdown = 0; | ||
| 223 | cf_sk->sk.sk_state_change(&cf_sk->sk); | 224 | cf_sk->sk.sk_state_change(&cf_sk->sk); |
| 224 | break; | 225 | break; |
| 225 | 226 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index cde1b4a20f75..46cca3a91d19 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -681,9 +681,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 681 | if (err < 0) | 681 | if (err < 0) |
| 682 | goto free_skb; | 682 | goto free_skb; |
| 683 | 683 | ||
| 684 | /* to be able to check the received tx sock reference in raw_rcv() */ | ||
| 685 | skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; | ||
| 686 | |||
| 687 | skb->dev = dev; | 684 | skb->dev = dev; |
| 688 | skb->sk = sk; | 685 | skb->sk = sk; |
| 689 | 686 | ||
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index a776f751edbf..ba4323bce0e9 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c | |||
| @@ -504,13 +504,6 @@ void ceph_destroy_client(struct ceph_client *client) | |||
| 504 | /* unmount */ | 504 | /* unmount */ |
| 505 | ceph_osdc_stop(&client->osdc); | 505 | ceph_osdc_stop(&client->osdc); |
| 506 | 506 | ||
| 507 | /* | ||
| 508 | * make sure osd connections close out before destroying the | ||
| 509 | * auth module, which is needed to free those connections' | ||
| 510 | * ceph_authorizers. | ||
| 511 | */ | ||
| 512 | ceph_msgr_flush(); | ||
| 513 | |||
| 514 | ceph_monc_stop(&client->monc); | 507 | ceph_monc_stop(&client->monc); |
| 515 | 508 | ||
| 516 | ceph_debugfs_client_cleanup(client); | 509 | ceph_debugfs_client_cleanup(client); |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 524f4e4f598b..10255e81be79 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
| @@ -563,6 +563,10 @@ static void prepare_write_message(struct ceph_connection *con) | |||
| 563 | m->hdr.seq = cpu_to_le64(++con->out_seq); | 563 | m->hdr.seq = cpu_to_le64(++con->out_seq); |
| 564 | m->needs_out_seq = false; | 564 | m->needs_out_seq = false; |
| 565 | } | 565 | } |
| 566 | #ifdef CONFIG_BLOCK | ||
| 567 | else | ||
| 568 | m->bio_iter = NULL; | ||
| 569 | #endif | ||
| 566 | 570 | ||
| 567 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", | 571 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", |
| 568 | m, con->out_seq, le16_to_cpu(m->hdr.type), | 572 | m, con->out_seq, le16_to_cpu(m->hdr.type), |
| @@ -1419,7 +1423,7 @@ static int process_connect(struct ceph_connection *con) | |||
| 1419 | * dropped messages. | 1423 | * dropped messages. |
| 1420 | */ | 1424 | */ |
| 1421 | dout("process_connect got RESET peer seq %u\n", | 1425 | dout("process_connect got RESET peer seq %u\n", |
| 1422 | le32_to_cpu(con->in_connect.connect_seq)); | 1426 | le32_to_cpu(con->in_reply.connect_seq)); |
| 1423 | pr_err("%s%lld %s connection reset\n", | 1427 | pr_err("%s%lld %s connection reset\n", |
| 1424 | ENTITY_NAME(con->peer_name), | 1428 | ENTITY_NAME(con->peer_name), |
| 1425 | ceph_pr_addr(&con->peer_addr.in_addr)); | 1429 | ceph_pr_addr(&con->peer_addr.in_addr)); |
| @@ -1446,10 +1450,10 @@ static int process_connect(struct ceph_connection *con) | |||
| 1446 | * If we sent a smaller connect_seq than the peer has, try | 1450 | * If we sent a smaller connect_seq than the peer has, try |
| 1447 | * again with a larger value. | 1451 | * again with a larger value. |
| 1448 | */ | 1452 | */ |
| 1449 | dout("process_connect got RETRY my seq = %u, peer_seq = %u\n", | 1453 | dout("process_connect got RETRY_SESSION my seq %u, peer %u\n", |
| 1450 | le32_to_cpu(con->out_connect.connect_seq), | 1454 | le32_to_cpu(con->out_connect.connect_seq), |
| 1451 | le32_to_cpu(con->in_connect.connect_seq)); | 1455 | le32_to_cpu(con->in_reply.connect_seq)); |
| 1452 | con->connect_seq = le32_to_cpu(con->in_connect.connect_seq); | 1456 | con->connect_seq = le32_to_cpu(con->in_reply.connect_seq); |
| 1453 | ceph_con_out_kvec_reset(con); | 1457 | ceph_con_out_kvec_reset(con); |
| 1454 | ret = prepare_write_connect(con); | 1458 | ret = prepare_write_connect(con); |
| 1455 | if (ret < 0) | 1459 | if (ret < 0) |
| @@ -1464,9 +1468,9 @@ static int process_connect(struct ceph_connection *con) | |||
| 1464 | */ | 1468 | */ |
| 1465 | dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n", | 1469 | dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n", |
| 1466 | con->peer_global_seq, | 1470 | con->peer_global_seq, |
| 1467 | le32_to_cpu(con->in_connect.global_seq)); | 1471 | le32_to_cpu(con->in_reply.global_seq)); |
| 1468 | get_global_seq(con->msgr, | 1472 | get_global_seq(con->msgr, |
| 1469 | le32_to_cpu(con->in_connect.global_seq)); | 1473 | le32_to_cpu(con->in_reply.global_seq)); |
| 1470 | ceph_con_out_kvec_reset(con); | 1474 | ceph_con_out_kvec_reset(con); |
| 1471 | ret = prepare_write_connect(con); | 1475 | ret = prepare_write_connect(con); |
| 1472 | if (ret < 0) | 1476 | if (ret < 0) |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 10d6008d31f2..d0649a9655be 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
| @@ -847,6 +847,14 @@ void ceph_monc_stop(struct ceph_mon_client *monc) | |||
| 847 | 847 | ||
| 848 | mutex_unlock(&monc->mutex); | 848 | mutex_unlock(&monc->mutex); |
| 849 | 849 | ||
| 850 | /* | ||
| 851 | * flush msgr queue before we destroy ourselves to ensure that: | ||
| 852 | * - any work that references our embedded con is finished. | ||
| 853 | * - any osd_client or other work that may reference an authorizer | ||
| 854 | * finishes before we shut down the auth subsystem. | ||
| 855 | */ | ||
| 856 | ceph_msgr_flush(); | ||
| 857 | |||
| 850 | ceph_auth_destroy(monc->auth); | 858 | ceph_auth_destroy(monc->auth); |
| 851 | 859 | ||
| 852 | ceph_msg_put(monc->m_auth); | 860 | ceph_msg_put(monc->m_auth); |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 1ffebed5ce0f..ca59e66c9787 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -139,15 +139,15 @@ void ceph_osdc_release_request(struct kref *kref) | |||
| 139 | 139 | ||
| 140 | if (req->r_request) | 140 | if (req->r_request) |
| 141 | ceph_msg_put(req->r_request); | 141 | ceph_msg_put(req->r_request); |
| 142 | if (req->r_reply) | ||
| 143 | ceph_msg_put(req->r_reply); | ||
| 144 | if (req->r_con_filling_msg) { | 142 | if (req->r_con_filling_msg) { |
| 145 | dout("release_request revoking pages %p from con %p\n", | 143 | dout("release_request revoking pages %p from con %p\n", |
| 146 | req->r_pages, req->r_con_filling_msg); | 144 | req->r_pages, req->r_con_filling_msg); |
| 147 | ceph_con_revoke_message(req->r_con_filling_msg, | 145 | ceph_con_revoke_message(req->r_con_filling_msg, |
| 148 | req->r_reply); | 146 | req->r_reply); |
| 149 | ceph_con_put(req->r_con_filling_msg); | 147 | req->r_con_filling_msg->ops->put(req->r_con_filling_msg); |
| 150 | } | 148 | } |
| 149 | if (req->r_reply) | ||
| 150 | ceph_msg_put(req->r_reply); | ||
| 151 | if (req->r_own_pages) | 151 | if (req->r_own_pages) |
| 152 | ceph_release_page_vector(req->r_pages, | 152 | ceph_release_page_vector(req->r_pages, |
| 153 | req->r_num_pages); | 153 | req->r_num_pages); |
| @@ -1216,7 +1216,7 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 1216 | if (req->r_con_filling_msg == con && req->r_reply == msg) { | 1216 | if (req->r_con_filling_msg == con && req->r_reply == msg) { |
| 1217 | dout(" dropping con_filling_msg ref %p\n", con); | 1217 | dout(" dropping con_filling_msg ref %p\n", con); |
| 1218 | req->r_con_filling_msg = NULL; | 1218 | req->r_con_filling_msg = NULL; |
| 1219 | ceph_con_put(con); | 1219 | con->ops->put(con); |
| 1220 | } | 1220 | } |
| 1221 | 1221 | ||
| 1222 | if (!req->r_got_reply) { | 1222 | if (!req->r_got_reply) { |
| @@ -2028,7 +2028,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, | |||
| 2028 | dout("get_reply revoking msg %p from old con %p\n", | 2028 | dout("get_reply revoking msg %p from old con %p\n", |
| 2029 | req->r_reply, req->r_con_filling_msg); | 2029 | req->r_reply, req->r_con_filling_msg); |
| 2030 | ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); | 2030 | ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); |
| 2031 | ceph_con_put(req->r_con_filling_msg); | 2031 | req->r_con_filling_msg->ops->put(req->r_con_filling_msg); |
| 2032 | req->r_con_filling_msg = NULL; | 2032 | req->r_con_filling_msg = NULL; |
| 2033 | } | 2033 | } |
| 2034 | 2034 | ||
| @@ -2063,7 +2063,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, | |||
| 2063 | #endif | 2063 | #endif |
| 2064 | } | 2064 | } |
| 2065 | *skip = 0; | 2065 | *skip = 0; |
| 2066 | req->r_con_filling_msg = ceph_con_get(con); | 2066 | req->r_con_filling_msg = con->ops->get(con); |
| 2067 | dout("get_reply tid %lld %p\n", tid, m); | 2067 | dout("get_reply tid %lld %p\n", tid, m); |
| 2068 | 2068 | ||
| 2069 | out: | 2069 | out: |
diff --git a/net/core/dev.c b/net/core/dev.c index cd0981977f5c..1cb0d8a6aa6c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1136,8 +1136,8 @@ void dev_load(struct net *net, const char *name) | |||
| 1136 | no_module = request_module("netdev-%s", name); | 1136 | no_module = request_module("netdev-%s", name); |
| 1137 | if (no_module && capable(CAP_SYS_MODULE)) { | 1137 | if (no_module && capable(CAP_SYS_MODULE)) { |
| 1138 | if (!request_module("%s", name)) | 1138 | if (!request_module("%s", name)) |
| 1139 | pr_err("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", | 1139 | pr_warn("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", |
| 1140 | name); | 1140 | name); |
| 1141 | } | 1141 | } |
| 1142 | } | 1142 | } |
| 1143 | EXPORT_SYMBOL(dev_load); | 1143 | EXPORT_SYMBOL(dev_load); |
| @@ -2089,25 +2089,6 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2089 | return 0; | 2089 | return 0; |
| 2090 | } | 2090 | } |
| 2091 | 2091 | ||
| 2092 | /* | ||
| 2093 | * Try to orphan skb early, right before transmission by the device. | ||
| 2094 | * We cannot orphan skb if tx timestamp is requested or the sk-reference | ||
| 2095 | * is needed on driver level for other reasons, e.g. see net/can/raw.c | ||
| 2096 | */ | ||
| 2097 | static inline void skb_orphan_try(struct sk_buff *skb) | ||
| 2098 | { | ||
| 2099 | struct sock *sk = skb->sk; | ||
| 2100 | |||
| 2101 | if (sk && !skb_shinfo(skb)->tx_flags) { | ||
| 2102 | /* skb_tx_hash() wont be able to get sk. | ||
| 2103 | * We copy sk_hash into skb->rxhash | ||
| 2104 | */ | ||
| 2105 | if (!skb->rxhash) | ||
| 2106 | skb->rxhash = sk->sk_hash; | ||
| 2107 | skb_orphan(skb); | ||
| 2108 | } | ||
| 2109 | } | ||
| 2110 | |||
| 2111 | static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) | 2092 | static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) |
| 2112 | { | 2093 | { |
| 2113 | return ((features & NETIF_F_GEN_CSUM) || | 2094 | return ((features & NETIF_F_GEN_CSUM) || |
| @@ -2193,8 +2174,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 2193 | if (!list_empty(&ptype_all)) | 2174 | if (!list_empty(&ptype_all)) |
| 2194 | dev_queue_xmit_nit(skb, dev); | 2175 | dev_queue_xmit_nit(skb, dev); |
| 2195 | 2176 | ||
| 2196 | skb_orphan_try(skb); | ||
| 2197 | |||
| 2198 | features = netif_skb_features(skb); | 2177 | features = netif_skb_features(skb); |
| 2199 | 2178 | ||
| 2200 | if (vlan_tx_tag_present(skb) && | 2179 | if (vlan_tx_tag_present(skb) && |
| @@ -2304,7 +2283,7 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb, | |||
| 2304 | if (skb->sk && skb->sk->sk_hash) | 2283 | if (skb->sk && skb->sk->sk_hash) |
| 2305 | hash = skb->sk->sk_hash; | 2284 | hash = skb->sk->sk_hash; |
| 2306 | else | 2285 | else |
| 2307 | hash = (__force u16) skb->protocol ^ skb->rxhash; | 2286 | hash = (__force u16) skb->protocol; |
| 2308 | hash = jhash_1word(hash, hashrnd); | 2287 | hash = jhash_1word(hash, hashrnd); |
| 2309 | 2288 | ||
| 2310 | return (u16) (((u64) hash * qcount) >> 32) + qoffset; | 2289 | return (u16) (((u64) hash * qcount) >> 32) + qoffset; |
| @@ -2465,8 +2444,12 @@ static void skb_update_prio(struct sk_buff *skb) | |||
| 2465 | { | 2444 | { |
| 2466 | struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); | 2445 | struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); |
| 2467 | 2446 | ||
| 2468 | if ((!skb->priority) && (skb->sk) && map) | 2447 | if (!skb->priority && skb->sk && map) { |
| 2469 | skb->priority = map->priomap[skb->sk->sk_cgrp_prioidx]; | 2448 | unsigned int prioidx = skb->sk->sk_cgrp_prioidx; |
| 2449 | |||
| 2450 | if (prioidx < map->priomap_len) | ||
| 2451 | skb->priority = map->priomap[prioidx]; | ||
| 2452 | } | ||
| 2470 | } | 2453 | } |
| 2471 | #else | 2454 | #else |
| 2472 | #define skb_update_prio(skb) | 2455 | #define skb_update_prio(skb) |
| @@ -6300,7 +6283,8 @@ static struct hlist_head *netdev_create_hash(void) | |||
| 6300 | /* Initialize per network namespace state */ | 6283 | /* Initialize per network namespace state */ |
| 6301 | static int __net_init netdev_init(struct net *net) | 6284 | static int __net_init netdev_init(struct net *net) |
| 6302 | { | 6285 | { |
| 6303 | INIT_LIST_HEAD(&net->dev_base_head); | 6286 | if (net != &init_net) |
| 6287 | INIT_LIST_HEAD(&net->dev_base_head); | ||
| 6304 | 6288 | ||
| 6305 | net->dev_name_head = netdev_create_hash(); | 6289 | net->dev_name_head = netdev_create_hash(); |
| 6306 | if (net->dev_name_head == NULL) | 6290 | if (net->dev_name_head == NULL) |
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index ea5fb9fcc3f5..d23b6682f4e9 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -36,9 +36,6 @@ | |||
| 36 | #define TRACE_ON 1 | 36 | #define TRACE_ON 1 |
| 37 | #define TRACE_OFF 0 | 37 | #define TRACE_OFF 0 |
| 38 | 38 | ||
| 39 | static void send_dm_alert(struct work_struct *unused); | ||
| 40 | |||
| 41 | |||
| 42 | /* | 39 | /* |
| 43 | * Globals, our netlink socket pointer | 40 | * Globals, our netlink socket pointer |
| 44 | * and the work handle that will send up | 41 | * and the work handle that will send up |
| @@ -48,11 +45,10 @@ static int trace_state = TRACE_OFF; | |||
| 48 | static DEFINE_MUTEX(trace_state_mutex); | 45 | static DEFINE_MUTEX(trace_state_mutex); |
| 49 | 46 | ||
| 50 | struct per_cpu_dm_data { | 47 | struct per_cpu_dm_data { |
| 51 | struct work_struct dm_alert_work; | 48 | spinlock_t lock; |
| 52 | struct sk_buff __rcu *skb; | 49 | struct sk_buff *skb; |
| 53 | atomic_t dm_hit_count; | 50 | struct work_struct dm_alert_work; |
| 54 | struct timer_list send_timer; | 51 | struct timer_list send_timer; |
| 55 | int cpu; | ||
| 56 | }; | 52 | }; |
| 57 | 53 | ||
| 58 | struct dm_hw_stat_delta { | 54 | struct dm_hw_stat_delta { |
| @@ -78,13 +74,13 @@ static int dm_delay = 1; | |||
| 78 | static unsigned long dm_hw_check_delta = 2*HZ; | 74 | static unsigned long dm_hw_check_delta = 2*HZ; |
| 79 | static LIST_HEAD(hw_stats_list); | 75 | static LIST_HEAD(hw_stats_list); |
| 80 | 76 | ||
| 81 | static void reset_per_cpu_data(struct per_cpu_dm_data *data) | 77 | static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) |
| 82 | { | 78 | { |
| 83 | size_t al; | 79 | size_t al; |
| 84 | struct net_dm_alert_msg *msg; | 80 | struct net_dm_alert_msg *msg; |
| 85 | struct nlattr *nla; | 81 | struct nlattr *nla; |
| 86 | struct sk_buff *skb; | 82 | struct sk_buff *skb; |
| 87 | struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1); | 83 | unsigned long flags; |
| 88 | 84 | ||
| 89 | al = sizeof(struct net_dm_alert_msg); | 85 | al = sizeof(struct net_dm_alert_msg); |
| 90 | al += dm_hit_limit * sizeof(struct net_dm_drop_point); | 86 | al += dm_hit_limit * sizeof(struct net_dm_drop_point); |
| @@ -99,65 +95,40 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data) | |||
| 99 | sizeof(struct net_dm_alert_msg)); | 95 | sizeof(struct net_dm_alert_msg)); |
| 100 | msg = nla_data(nla); | 96 | msg = nla_data(nla); |
| 101 | memset(msg, 0, al); | 97 | memset(msg, 0, al); |
| 102 | } else | 98 | } else { |
| 103 | schedule_work_on(data->cpu, &data->dm_alert_work); | 99 | mod_timer(&data->send_timer, jiffies + HZ / 10); |
| 104 | |||
| 105 | /* | ||
| 106 | * Don't need to lock this, since we are guaranteed to only | ||
| 107 | * run this on a single cpu at a time. | ||
| 108 | * Note also that we only update data->skb if the old and new skb | ||
| 109 | * pointers don't match. This ensures that we don't continually call | ||
| 110 | * synchornize_rcu if we repeatedly fail to alloc a new netlink message. | ||
| 111 | */ | ||
| 112 | if (skb != oskb) { | ||
| 113 | rcu_assign_pointer(data->skb, skb); | ||
| 114 | |||
| 115 | synchronize_rcu(); | ||
| 116 | |||
| 117 | atomic_set(&data->dm_hit_count, dm_hit_limit); | ||
| 118 | } | 100 | } |
| 119 | 101 | ||
| 102 | spin_lock_irqsave(&data->lock, flags); | ||
| 103 | swap(data->skb, skb); | ||
| 104 | spin_unlock_irqrestore(&data->lock, flags); | ||
| 105 | |||
| 106 | return skb; | ||
| 120 | } | 107 | } |
| 121 | 108 | ||
| 122 | static void send_dm_alert(struct work_struct *unused) | 109 | static void send_dm_alert(struct work_struct *work) |
| 123 | { | 110 | { |
| 124 | struct sk_buff *skb; | 111 | struct sk_buff *skb; |
| 125 | struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); | 112 | struct per_cpu_dm_data *data; |
| 126 | 113 | ||
| 127 | WARN_ON_ONCE(data->cpu != smp_processor_id()); | 114 | data = container_of(work, struct per_cpu_dm_data, dm_alert_work); |
| 128 | 115 | ||
| 129 | /* | 116 | skb = reset_per_cpu_data(data); |
| 130 | * Grab the skb we're about to send | ||
| 131 | */ | ||
| 132 | skb = rcu_dereference_protected(data->skb, 1); | ||
| 133 | |||
| 134 | /* | ||
| 135 | * Replace it with a new one | ||
| 136 | */ | ||
| 137 | reset_per_cpu_data(data); | ||
| 138 | 117 | ||
| 139 | /* | ||
| 140 | * Ship it! | ||
| 141 | */ | ||
| 142 | if (skb) | 118 | if (skb) |
| 143 | genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); | 119 | genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); |
| 144 | |||
| 145 | put_cpu_var(dm_cpu_data); | ||
| 146 | } | 120 | } |
| 147 | 121 | ||
| 148 | /* | 122 | /* |
| 149 | * This is the timer function to delay the sending of an alert | 123 | * This is the timer function to delay the sending of an alert |
| 150 | * in the event that more drops will arrive during the | 124 | * in the event that more drops will arrive during the |
| 151 | * hysteresis period. Note that it operates under the timer interrupt | 125 | * hysteresis period. |
| 152 | * so we don't need to disable preemption here | ||
| 153 | */ | 126 | */ |
| 154 | static void sched_send_work(unsigned long unused) | 127 | static void sched_send_work(unsigned long _data) |
| 155 | { | 128 | { |
| 156 | struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); | 129 | struct per_cpu_dm_data *data = (struct per_cpu_dm_data *)_data; |
| 157 | |||
| 158 | schedule_work_on(smp_processor_id(), &data->dm_alert_work); | ||
| 159 | 130 | ||
| 160 | put_cpu_var(dm_cpu_data); | 131 | schedule_work(&data->dm_alert_work); |
| 161 | } | 132 | } |
| 162 | 133 | ||
| 163 | static void trace_drop_common(struct sk_buff *skb, void *location) | 134 | static void trace_drop_common(struct sk_buff *skb, void *location) |
| @@ -167,33 +138,28 @@ static void trace_drop_common(struct sk_buff *skb, void *location) | |||
| 167 | struct nlattr *nla; | 138 | struct nlattr *nla; |
| 168 | int i; | 139 | int i; |
| 169 | struct sk_buff *dskb; | 140 | struct sk_buff *dskb; |
| 170 | struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); | 141 | struct per_cpu_dm_data *data; |
| 171 | 142 | unsigned long flags; | |
| 172 | 143 | ||
| 173 | rcu_read_lock(); | 144 | local_irq_save(flags); |
| 174 | dskb = rcu_dereference(data->skb); | 145 | data = &__get_cpu_var(dm_cpu_data); |
| 146 | spin_lock(&data->lock); | ||
| 147 | dskb = data->skb; | ||
| 175 | 148 | ||
| 176 | if (!dskb) | 149 | if (!dskb) |
| 177 | goto out; | 150 | goto out; |
| 178 | 151 | ||
| 179 | if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) { | ||
| 180 | /* | ||
| 181 | * we're already at zero, discard this hit | ||
| 182 | */ | ||
| 183 | goto out; | ||
| 184 | } | ||
| 185 | |||
| 186 | nlh = (struct nlmsghdr *)dskb->data; | 152 | nlh = (struct nlmsghdr *)dskb->data; |
| 187 | nla = genlmsg_data(nlmsg_data(nlh)); | 153 | nla = genlmsg_data(nlmsg_data(nlh)); |
| 188 | msg = nla_data(nla); | 154 | msg = nla_data(nla); |
| 189 | for (i = 0; i < msg->entries; i++) { | 155 | for (i = 0; i < msg->entries; i++) { |
| 190 | if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { | 156 | if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { |
| 191 | msg->points[i].count++; | 157 | msg->points[i].count++; |
| 192 | atomic_inc(&data->dm_hit_count); | ||
| 193 | goto out; | 158 | goto out; |
| 194 | } | 159 | } |
| 195 | } | 160 | } |
| 196 | 161 | if (msg->entries == dm_hit_limit) | |
| 162 | goto out; | ||
| 197 | /* | 163 | /* |
| 198 | * We need to create a new entry | 164 | * We need to create a new entry |
| 199 | */ | 165 | */ |
| @@ -205,13 +171,11 @@ static void trace_drop_common(struct sk_buff *skb, void *location) | |||
| 205 | 171 | ||
| 206 | if (!timer_pending(&data->send_timer)) { | 172 | if (!timer_pending(&data->send_timer)) { |
| 207 | data->send_timer.expires = jiffies + dm_delay * HZ; | 173 | data->send_timer.expires = jiffies + dm_delay * HZ; |
| 208 | add_timer_on(&data->send_timer, smp_processor_id()); | 174 | add_timer(&data->send_timer); |
| 209 | } | 175 | } |
| 210 | 176 | ||
| 211 | out: | 177 | out: |
| 212 | rcu_read_unlock(); | 178 | spin_unlock_irqrestore(&data->lock, flags); |
| 213 | put_cpu_var(dm_cpu_data); | ||
| 214 | return; | ||
| 215 | } | 179 | } |
| 216 | 180 | ||
| 217 | static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location) | 181 | static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location) |
| @@ -418,11 +382,11 @@ static int __init init_net_drop_monitor(void) | |||
| 418 | 382 | ||
| 419 | for_each_possible_cpu(cpu) { | 383 | for_each_possible_cpu(cpu) { |
| 420 | data = &per_cpu(dm_cpu_data, cpu); | 384 | data = &per_cpu(dm_cpu_data, cpu); |
| 421 | data->cpu = cpu; | ||
| 422 | INIT_WORK(&data->dm_alert_work, send_dm_alert); | 385 | INIT_WORK(&data->dm_alert_work, send_dm_alert); |
| 423 | init_timer(&data->send_timer); | 386 | init_timer(&data->send_timer); |
| 424 | data->send_timer.data = cpu; | 387 | data->send_timer.data = (unsigned long)data; |
| 425 | data->send_timer.function = sched_send_work; | 388 | data->send_timer.function = sched_send_work; |
| 389 | spin_lock_init(&data->lock); | ||
| 426 | reset_per_cpu_data(data); | 390 | reset_per_cpu_data(data); |
| 427 | } | 391 | } |
| 428 | 392 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index a3eddb515d1b..d4ce2dc712e3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -616,9 +616,9 @@ static int __sk_prepare_filter(struct sk_filter *fp) | |||
| 616 | /** | 616 | /** |
| 617 | * sk_unattached_filter_create - create an unattached filter | 617 | * sk_unattached_filter_create - create an unattached filter |
| 618 | * @fprog: the filter program | 618 | * @fprog: the filter program |
| 619 | * @sk: the socket to use | 619 | * @pfp: the unattached filter that is created |
| 620 | * | 620 | * |
| 621 | * Create a filter independent ofr any socket. We first run some | 621 | * Create a filter independent of any socket. We first run some |
| 622 | * sanity checks on it to make sure it does not explode on us later. | 622 | * sanity checks on it to make sure it does not explode on us later. |
| 623 | * If an error occurs or there is insufficient memory for the filter | 623 | * If an error occurs or there is insufficient memory for the filter |
| 624 | * a negative errno code is returned. On success the return is zero. | 624 | * a negative errno code is returned. On success the return is zero. |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index eb09f8bbbf07..d81d026138f0 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -2219,9 +2219,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | |||
| 2219 | rcu_read_lock_bh(); | 2219 | rcu_read_lock_bh(); |
| 2220 | nht = rcu_dereference_bh(tbl->nht); | 2220 | nht = rcu_dereference_bh(tbl->nht); |
| 2221 | 2221 | ||
| 2222 | for (h = 0; h < (1 << nht->hash_shift); h++) { | 2222 | for (h = s_h; h < (1 << nht->hash_shift); h++) { |
| 2223 | if (h < s_h) | ||
| 2224 | continue; | ||
| 2225 | if (h > s_h) | 2223 | if (h > s_h) |
| 2226 | s_idx = 0; | 2224 | s_idx = 0; |
| 2227 | for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; | 2225 | for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; |
| @@ -2260,9 +2258,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | |||
| 2260 | 2258 | ||
| 2261 | read_lock_bh(&tbl->lock); | 2259 | read_lock_bh(&tbl->lock); |
| 2262 | 2260 | ||
| 2263 | for (h = 0; h <= PNEIGH_HASHMASK; h++) { | 2261 | for (h = s_h; h <= PNEIGH_HASHMASK; h++) { |
| 2264 | if (h < s_h) | ||
| 2265 | continue; | ||
| 2266 | if (h > s_h) | 2262 | if (h > s_h) |
| 2267 | s_idx = 0; | 2263 | s_idx = 0; |
| 2268 | for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { | 2264 | for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { |
| @@ -2297,7 +2293,7 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2297 | struct neigh_table *tbl; | 2293 | struct neigh_table *tbl; |
| 2298 | int t, family, s_t; | 2294 | int t, family, s_t; |
| 2299 | int proxy = 0; | 2295 | int proxy = 0; |
| 2300 | int err = 0; | 2296 | int err; |
| 2301 | 2297 | ||
| 2302 | read_lock(&neigh_tbl_lock); | 2298 | read_lock(&neigh_tbl_lock); |
| 2303 | family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; | 2299 | family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; |
| @@ -2311,7 +2307,7 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2311 | 2307 | ||
| 2312 | s_t = cb->args[0]; | 2308 | s_t = cb->args[0]; |
| 2313 | 2309 | ||
| 2314 | for (tbl = neigh_tables, t = 0; tbl && (err >= 0); | 2310 | for (tbl = neigh_tables, t = 0; tbl; |
| 2315 | tbl = tbl->next, t++) { | 2311 | tbl = tbl->next, t++) { |
| 2316 | if (t < s_t || (family && tbl->family != family)) | 2312 | if (t < s_t || (family && tbl->family != family)) |
| 2317 | continue; | 2313 | continue; |
| @@ -2322,6 +2318,8 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2322 | err = pneigh_dump_table(tbl, skb, cb); | 2318 | err = pneigh_dump_table(tbl, skb, cb); |
| 2323 | else | 2319 | else |
| 2324 | err = neigh_dump_table(tbl, skb, cb); | 2320 | err = neigh_dump_table(tbl, skb, cb); |
| 2321 | if (err < 0) | ||
| 2322 | break; | ||
| 2325 | } | 2323 | } |
| 2326 | read_unlock(&neigh_tbl_lock); | 2324 | read_unlock(&neigh_tbl_lock); |
| 2327 | 2325 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index dddbacb8f28c..42f1e1c7514f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -27,7 +27,9 @@ static DEFINE_MUTEX(net_mutex); | |||
| 27 | LIST_HEAD(net_namespace_list); | 27 | LIST_HEAD(net_namespace_list); |
| 28 | EXPORT_SYMBOL_GPL(net_namespace_list); | 28 | EXPORT_SYMBOL_GPL(net_namespace_list); |
| 29 | 29 | ||
| 30 | struct net init_net; | 30 | struct net init_net = { |
| 31 | .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head), | ||
| 32 | }; | ||
| 31 | EXPORT_SYMBOL(init_net); | 33 | EXPORT_SYMBOL(init_net); |
| 32 | 34 | ||
| 33 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 35 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 3d84fb9d8873..f9f40b932e4b 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -362,22 +362,23 @@ EXPORT_SYMBOL(netpoll_send_skb_on_dev); | |||
| 362 | 362 | ||
| 363 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | 363 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len) |
| 364 | { | 364 | { |
| 365 | int total_len, eth_len, ip_len, udp_len; | 365 | int total_len, ip_len, udp_len; |
| 366 | struct sk_buff *skb; | 366 | struct sk_buff *skb; |
| 367 | struct udphdr *udph; | 367 | struct udphdr *udph; |
| 368 | struct iphdr *iph; | 368 | struct iphdr *iph; |
| 369 | struct ethhdr *eth; | 369 | struct ethhdr *eth; |
| 370 | 370 | ||
| 371 | udp_len = len + sizeof(*udph); | 371 | udp_len = len + sizeof(*udph); |
| 372 | ip_len = eth_len = udp_len + sizeof(*iph); | 372 | ip_len = udp_len + sizeof(*iph); |
| 373 | total_len = eth_len + ETH_HLEN + NET_IP_ALIGN; | 373 | total_len = ip_len + LL_RESERVED_SPACE(np->dev); |
| 374 | 374 | ||
| 375 | skb = find_skb(np, total_len, total_len - len); | 375 | skb = find_skb(np, total_len + np->dev->needed_tailroom, |
| 376 | total_len - len); | ||
| 376 | if (!skb) | 377 | if (!skb) |
| 377 | return; | 378 | return; |
| 378 | 379 | ||
| 379 | skb_copy_to_linear_data(skb, msg, len); | 380 | skb_copy_to_linear_data(skb, msg, len); |
| 380 | skb->len += len; | 381 | skb_put(skb, len); |
| 381 | 382 | ||
| 382 | skb_push(skb, sizeof(*udph)); | 383 | skb_push(skb, sizeof(*udph)); |
| 383 | skb_reset_transport_header(skb); | 384 | skb_reset_transport_header(skb); |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 5b8aa2fae48b..b2e9caa1ad1a 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
| @@ -49,8 +49,9 @@ static int get_prioidx(u32 *prio) | |||
| 49 | return -ENOSPC; | 49 | return -ENOSPC; |
| 50 | } | 50 | } |
| 51 | set_bit(prioidx, prioidx_map); | 51 | set_bit(prioidx, prioidx_map); |
| 52 | if (atomic_read(&max_prioidx) < prioidx) | ||
| 53 | atomic_set(&max_prioidx, prioidx); | ||
| 52 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | 54 | spin_unlock_irqrestore(&prioidx_map_lock, flags); |
| 53 | atomic_set(&max_prioidx, prioidx); | ||
| 54 | *prio = prioidx; | 55 | *prio = prioidx; |
| 55 | return 0; | 56 | return 0; |
| 56 | } | 57 | } |
| @@ -64,7 +65,7 @@ static void put_prioidx(u32 idx) | |||
| 64 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | 65 | spin_unlock_irqrestore(&prioidx_map_lock, flags); |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | static void extend_netdev_table(struct net_device *dev, u32 new_len) | 68 | static int extend_netdev_table(struct net_device *dev, u32 new_len) |
| 68 | { | 69 | { |
| 69 | size_t new_size = sizeof(struct netprio_map) + | 70 | size_t new_size = sizeof(struct netprio_map) + |
| 70 | ((sizeof(u32) * new_len)); | 71 | ((sizeof(u32) * new_len)); |
| @@ -76,7 +77,7 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) | |||
| 76 | 77 | ||
| 77 | if (!new_priomap) { | 78 | if (!new_priomap) { |
| 78 | pr_warn("Unable to alloc new priomap!\n"); | 79 | pr_warn("Unable to alloc new priomap!\n"); |
| 79 | return; | 80 | return -ENOMEM; |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | for (i = 0; | 83 | for (i = 0; |
| @@ -89,46 +90,79 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) | |||
| 89 | rcu_assign_pointer(dev->priomap, new_priomap); | 90 | rcu_assign_pointer(dev->priomap, new_priomap); |
| 90 | if (old_priomap) | 91 | if (old_priomap) |
| 91 | kfree_rcu(old_priomap, rcu); | 92 | kfree_rcu(old_priomap, rcu); |
| 93 | return 0; | ||
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | static void update_netdev_tables(void) | 96 | static int write_update_netdev_table(struct net_device *dev) |
| 95 | { | 97 | { |
| 98 | int ret = 0; | ||
| 99 | u32 max_len; | ||
| 100 | struct netprio_map *map; | ||
| 101 | |||
| 102 | rtnl_lock(); | ||
| 103 | max_len = atomic_read(&max_prioidx) + 1; | ||
| 104 | map = rtnl_dereference(dev->priomap); | ||
| 105 | if (!map || map->priomap_len < max_len) | ||
| 106 | ret = extend_netdev_table(dev, max_len); | ||
| 107 | rtnl_unlock(); | ||
| 108 | |||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 112 | static int update_netdev_tables(void) | ||
| 113 | { | ||
| 114 | int ret = 0; | ||
| 96 | struct net_device *dev; | 115 | struct net_device *dev; |
| 97 | u32 max_len = atomic_read(&max_prioidx) + 1; | 116 | u32 max_len; |
| 98 | struct netprio_map *map; | 117 | struct netprio_map *map; |
| 99 | 118 | ||
| 100 | rtnl_lock(); | 119 | rtnl_lock(); |
| 120 | max_len = atomic_read(&max_prioidx) + 1; | ||
| 101 | for_each_netdev(&init_net, dev) { | 121 | for_each_netdev(&init_net, dev) { |
| 102 | map = rtnl_dereference(dev->priomap); | 122 | map = rtnl_dereference(dev->priomap); |
| 103 | if ((!map) || | 123 | /* |
| 104 | (map->priomap_len < max_len)) | 124 | * don't allocate priomap if we didn't |
| 105 | extend_netdev_table(dev, max_len); | 125 | * change net_prio.ifpriomap (map == NULL), |
| 126 | * this will speed up skb_update_prio. | ||
| 127 | */ | ||
| 128 | if (map && map->priomap_len < max_len) { | ||
| 129 | ret = extend_netdev_table(dev, max_len); | ||
| 130 | if (ret < 0) | ||
| 131 | break; | ||
| 132 | } | ||
| 106 | } | 133 | } |
| 107 | rtnl_unlock(); | 134 | rtnl_unlock(); |
| 135 | return ret; | ||
| 108 | } | 136 | } |
| 109 | 137 | ||
| 110 | static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) | 138 | static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) |
| 111 | { | 139 | { |
| 112 | struct cgroup_netprio_state *cs; | 140 | struct cgroup_netprio_state *cs; |
| 113 | int ret; | 141 | int ret = -EINVAL; |
| 114 | 142 | ||
| 115 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); | 143 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); |
| 116 | if (!cs) | 144 | if (!cs) |
| 117 | return ERR_PTR(-ENOMEM); | 145 | return ERR_PTR(-ENOMEM); |
| 118 | 146 | ||
| 119 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) { | 147 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) |
| 120 | kfree(cs); | 148 | goto out; |
| 121 | return ERR_PTR(-EINVAL); | ||
| 122 | } | ||
| 123 | 149 | ||
| 124 | ret = get_prioidx(&cs->prioidx); | 150 | ret = get_prioidx(&cs->prioidx); |
| 125 | if (ret != 0) { | 151 | if (ret < 0) { |
| 126 | pr_warn("No space in priority index array\n"); | 152 | pr_warn("No space in priority index array\n"); |
| 127 | kfree(cs); | 153 | goto out; |
| 128 | return ERR_PTR(ret); | 154 | } |
| 155 | |||
| 156 | ret = update_netdev_tables(); | ||
| 157 | if (ret < 0) { | ||
| 158 | put_prioidx(cs->prioidx); | ||
| 159 | goto out; | ||
| 129 | } | 160 | } |
| 130 | 161 | ||
| 131 | return &cs->css; | 162 | return &cs->css; |
| 163 | out: | ||
| 164 | kfree(cs); | ||
| 165 | return ERR_PTR(ret); | ||
| 132 | } | 166 | } |
| 133 | 167 | ||
| 134 | static void cgrp_destroy(struct cgroup *cgrp) | 168 | static void cgrp_destroy(struct cgroup *cgrp) |
| @@ -141,7 +175,7 @@ static void cgrp_destroy(struct cgroup *cgrp) | |||
| 141 | rtnl_lock(); | 175 | rtnl_lock(); |
| 142 | for_each_netdev(&init_net, dev) { | 176 | for_each_netdev(&init_net, dev) { |
| 143 | map = rtnl_dereference(dev->priomap); | 177 | map = rtnl_dereference(dev->priomap); |
| 144 | if (map) | 178 | if (map && cs->prioidx < map->priomap_len) |
| 145 | map->priomap[cs->prioidx] = 0; | 179 | map->priomap[cs->prioidx] = 0; |
| 146 | } | 180 | } |
| 147 | rtnl_unlock(); | 181 | rtnl_unlock(); |
| @@ -165,7 +199,7 @@ static int read_priomap(struct cgroup *cont, struct cftype *cft, | |||
| 165 | rcu_read_lock(); | 199 | rcu_read_lock(); |
| 166 | for_each_netdev_rcu(&init_net, dev) { | 200 | for_each_netdev_rcu(&init_net, dev) { |
| 167 | map = rcu_dereference(dev->priomap); | 201 | map = rcu_dereference(dev->priomap); |
| 168 | priority = map ? map->priomap[prioidx] : 0; | 202 | priority = (map && prioidx < map->priomap_len) ? map->priomap[prioidx] : 0; |
| 169 | cb->fill(cb, dev->name, priority); | 203 | cb->fill(cb, dev->name, priority); |
| 170 | } | 204 | } |
| 171 | rcu_read_unlock(); | 205 | rcu_read_unlock(); |
| @@ -220,13 +254,17 @@ static int write_priomap(struct cgroup *cgrp, struct cftype *cft, | |||
| 220 | if (!dev) | 254 | if (!dev) |
| 221 | goto out_free_devname; | 255 | goto out_free_devname; |
| 222 | 256 | ||
| 223 | update_netdev_tables(); | 257 | ret = write_update_netdev_table(dev); |
| 224 | ret = 0; | 258 | if (ret < 0) |
| 259 | goto out_put_dev; | ||
| 260 | |||
| 225 | rcu_read_lock(); | 261 | rcu_read_lock(); |
| 226 | map = rcu_dereference(dev->priomap); | 262 | map = rcu_dereference(dev->priomap); |
| 227 | if (map) | 263 | if (map) |
| 228 | map->priomap[prioidx] = priority; | 264 | map->priomap[prioidx] = priority; |
| 229 | rcu_read_unlock(); | 265 | rcu_read_unlock(); |
| 266 | |||
| 267 | out_put_dev: | ||
| 230 | dev_put(dev); | 268 | dev_put(dev); |
| 231 | 269 | ||
| 232 | out_free_devname: | 270 | out_free_devname: |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index bac3c5756d63..d124306b81fd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -353,7 +353,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, | |||
| 353 | unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + | 353 | unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + |
| 354 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | 354 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
| 355 | 355 | ||
| 356 | if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) { | 356 | if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) { |
| 357 | void *data = netdev_alloc_frag(fragsz); | 357 | void *data = netdev_alloc_frag(fragsz); |
| 358 | 358 | ||
| 359 | if (likely(data)) { | 359 | if (likely(data)) { |
| @@ -3362,7 +3362,7 @@ EXPORT_SYMBOL(kfree_skb_partial); | |||
| 3362 | * @to: prior buffer | 3362 | * @to: prior buffer |
| 3363 | * @from: buffer to add | 3363 | * @from: buffer to add |
| 3364 | * @fragstolen: pointer to boolean | 3364 | * @fragstolen: pointer to boolean |
| 3365 | * | 3365 | * @delta_truesize: how much more was allocated than was requested |
| 3366 | */ | 3366 | */ |
| 3367 | bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, | 3367 | bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, |
| 3368 | bool *fragstolen, int *delta_truesize) | 3368 | bool *fragstolen, int *delta_truesize) |
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 6fbb2ad7bb6d..16705611589a 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
| @@ -230,6 +230,12 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 230 | mtu = dev->mtu; | 230 | mtu = dev->mtu; |
| 231 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); | 231 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); |
| 232 | 232 | ||
| 233 | if (size > mtu) { | ||
| 234 | pr_debug("size = %Zu, mtu = %u\n", size, mtu); | ||
| 235 | err = -EINVAL; | ||
| 236 | goto out_dev; | ||
| 237 | } | ||
| 238 | |||
| 233 | hlen = LL_RESERVED_SPACE(dev); | 239 | hlen = LL_RESERVED_SPACE(dev); |
| 234 | tlen = dev->needed_tailroom; | 240 | tlen = dev->needed_tailroom; |
| 235 | skb = sock_alloc_send_skb(sk, hlen + tlen + size, | 241 | skb = sock_alloc_send_skb(sk, hlen + tlen + size, |
| @@ -258,12 +264,6 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 258 | if (err < 0) | 264 | if (err < 0) |
| 259 | goto out_skb; | 265 | goto out_skb; |
| 260 | 266 | ||
| 261 | if (size > mtu) { | ||
| 262 | pr_debug("size = %Zu, mtu = %u\n", size, mtu); | ||
| 263 | err = -EINVAL; | ||
| 264 | goto out_skb; | ||
| 265 | } | ||
| 266 | |||
| 267 | skb->dev = dev; | 267 | skb->dev = dev; |
| 268 | skb->sk = sk; | 268 | skb->sk = sk; |
| 269 | skb->protocol = htons(ETH_P_IEEE802154); | 269 | skb->protocol = htons(ETH_P_IEEE802154); |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index c48adc565e92..667c1d4ca984 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -1725,8 +1725,10 @@ int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option) | |||
| 1725 | case CIPSO_V4_TAG_LOCAL: | 1725 | case CIPSO_V4_TAG_LOCAL: |
| 1726 | /* This is a non-standard tag that we only allow for | 1726 | /* This is a non-standard tag that we only allow for |
| 1727 | * local connections, so if the incoming interface is | 1727 | * local connections, so if the incoming interface is |
| 1728 | * not the loopback device drop the packet. */ | 1728 | * not the loopback device drop the packet. Further, |
| 1729 | if (!(skb->dev->flags & IFF_LOOPBACK)) { | 1729 | * there is no legitimate reason for setting this from |
| 1730 | * userspace so reject it if skb is NULL. */ | ||
| 1731 | if (skb == NULL || !(skb->dev->flags & IFF_LOOPBACK)) { | ||
| 1730 | err_offset = opt_iter; | 1732 | err_offset = opt_iter; |
| 1731 | goto validate_return_locked; | 1733 | goto validate_return_locked; |
| 1732 | } | 1734 | } |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index d4d61b694fab..dfba343b2509 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
| @@ -560,6 +560,17 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout) | |||
| 560 | } | 560 | } |
| 561 | EXPORT_SYMBOL(inet_peer_xrlim_allow); | 561 | EXPORT_SYMBOL(inet_peer_xrlim_allow); |
| 562 | 562 | ||
| 563 | static void inetpeer_inval_rcu(struct rcu_head *head) | ||
| 564 | { | ||
| 565 | struct inet_peer *p = container_of(head, struct inet_peer, gc_rcu); | ||
| 566 | |||
| 567 | spin_lock_bh(&gc_lock); | ||
| 568 | list_add_tail(&p->gc_list, &gc_list); | ||
| 569 | spin_unlock_bh(&gc_lock); | ||
| 570 | |||
| 571 | schedule_delayed_work(&gc_work, gc_delay); | ||
| 572 | } | ||
| 573 | |||
| 563 | void inetpeer_invalidate_tree(int family) | 574 | void inetpeer_invalidate_tree(int family) |
| 564 | { | 575 | { |
| 565 | struct inet_peer *old, *new, *prev; | 576 | struct inet_peer *old, *new, *prev; |
| @@ -576,10 +587,7 @@ void inetpeer_invalidate_tree(int family) | |||
| 576 | prev = cmpxchg(&base->root, old, new); | 587 | prev = cmpxchg(&base->root, old, new); |
| 577 | if (prev == old) { | 588 | if (prev == old) { |
| 578 | base->total = 0; | 589 | base->total = 0; |
| 579 | spin_lock(&gc_lock); | 590 | call_rcu(&prev->gc_rcu, inetpeer_inval_rcu); |
| 580 | list_add_tail(&prev->gc_list, &gc_list); | ||
| 581 | spin_unlock(&gc_lock); | ||
| 582 | schedule_delayed_work(&gc_work, gc_delay); | ||
| 583 | } | 591 | } |
| 584 | 592 | ||
| 585 | out: | 593 | out: |
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index e5c44fc586ab..ab09b126423c 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
| @@ -44,6 +44,7 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
| 44 | struct ip_options *opt = &(IPCB(skb)->opt); | 44 | struct ip_options *opt = &(IPCB(skb)->opt); |
| 45 | 45 | ||
| 46 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); | 46 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
| 47 | IP_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, skb->len); | ||
| 47 | 48 | ||
| 48 | if (unlikely(opt->optlen)) | 49 | if (unlikely(opt->optlen)) |
| 49 | ip_forward_options(skb); | 50 | ip_forward_options(skb); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index a9e519ad6db5..c94bbc6f2ba3 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -1574,6 +1574,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) | |||
| 1574 | struct ip_options *opt = &(IPCB(skb)->opt); | 1574 | struct ip_options *opt = &(IPCB(skb)->opt); |
| 1575 | 1575 | ||
| 1576 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); | 1576 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
| 1577 | IP_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTOCTETS, skb->len); | ||
| 1577 | 1578 | ||
| 1578 | if (unlikely(opt->optlen)) | 1579 | if (unlikely(opt->optlen)) |
| 1579 | ip_forward_options(skb); | 1580 | ip_forward_options(skb); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 0c220a416626..608327661960 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -1349,8 +1349,8 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
| 1349 | if (w->leaf && fn->fn_flags & RTN_RTINFO) { | 1349 | if (w->leaf && fn->fn_flags & RTN_RTINFO) { |
| 1350 | int err; | 1350 | int err; |
| 1351 | 1351 | ||
| 1352 | if (w->count < w->skip) { | 1352 | if (w->skip) { |
| 1353 | w->count++; | 1353 | w->skip--; |
| 1354 | continue; | 1354 | continue; |
| 1355 | } | 1355 | } |
| 1356 | 1356 | ||
| @@ -1561,7 +1561,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) | |||
| 1561 | neigh_flags = neigh->flags; | 1561 | neigh_flags = neigh->flags; |
| 1562 | neigh_release(neigh); | 1562 | neigh_release(neigh); |
| 1563 | } | 1563 | } |
| 1564 | if (neigh_flags & NTF_ROUTER) { | 1564 | if (!(neigh_flags & NTF_ROUTER)) { |
| 1565 | RT6_TRACE("purging route %p via non-router but gateway\n", | 1565 | RT6_TRACE("purging route %p via non-router but gateway\n", |
| 1566 | rt); | 1566 | rt); |
| 1567 | return -1; | 1567 | return -1; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 17b8c67998bb..decc21d19c53 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -526,6 +526,7 @@ int ip6_forward(struct sk_buff *skb) | |||
| 526 | hdr->hop_limit--; | 526 | hdr->hop_limit--; |
| 527 | 527 | ||
| 528 | IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); | 528 | IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); |
| 529 | IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len); | ||
| 529 | return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev, | 530 | return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev, |
| 530 | ip6_forward_finish); | 531 | ip6_forward_finish); |
| 531 | 532 | ||
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index b15dc08643a4..461e47c8e956 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -1886,6 +1886,8 @@ static inline int ip6mr_forward2_finish(struct sk_buff *skb) | |||
| 1886 | { | 1886 | { |
| 1887 | IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), | 1887 | IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), |
| 1888 | IPSTATS_MIB_OUTFORWDATAGRAMS); | 1888 | IPSTATS_MIB_OUTFORWDATAGRAMS); |
| 1889 | IP6_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), | ||
| 1890 | IPSTATS_MIB_OUTOCTETS, skb->len); | ||
| 1889 | return dst_output(skb); | 1891 | return dst_output(skb); |
| 1890 | } | 1892 | } |
| 1891 | 1893 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 999a982ad3fd..becb048d18d4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2957,10 +2957,6 @@ static int __net_init ip6_route_net_init(struct net *net) | |||
| 2957 | net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; | 2957 | net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; |
| 2958 | net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; | 2958 | net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; |
| 2959 | 2959 | ||
| 2960 | #ifdef CONFIG_PROC_FS | ||
| 2961 | proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); | ||
| 2962 | proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); | ||
| 2963 | #endif | ||
| 2964 | net->ipv6.ip6_rt_gc_expire = 30*HZ; | 2960 | net->ipv6.ip6_rt_gc_expire = 30*HZ; |
| 2965 | 2961 | ||
| 2966 | ret = 0; | 2962 | ret = 0; |
| @@ -2981,10 +2977,6 @@ out_ip6_dst_ops: | |||
| 2981 | 2977 | ||
| 2982 | static void __net_exit ip6_route_net_exit(struct net *net) | 2978 | static void __net_exit ip6_route_net_exit(struct net *net) |
| 2983 | { | 2979 | { |
| 2984 | #ifdef CONFIG_PROC_FS | ||
| 2985 | proc_net_remove(net, "ipv6_route"); | ||
| 2986 | proc_net_remove(net, "rt6_stats"); | ||
| 2987 | #endif | ||
| 2988 | kfree(net->ipv6.ip6_null_entry); | 2980 | kfree(net->ipv6.ip6_null_entry); |
| 2989 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 2981 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 2990 | kfree(net->ipv6.ip6_prohibit_entry); | 2982 | kfree(net->ipv6.ip6_prohibit_entry); |
| @@ -2993,11 +2985,33 @@ static void __net_exit ip6_route_net_exit(struct net *net) | |||
| 2993 | dst_entries_destroy(&net->ipv6.ip6_dst_ops); | 2985 | dst_entries_destroy(&net->ipv6.ip6_dst_ops); |
| 2994 | } | 2986 | } |
| 2995 | 2987 | ||
| 2988 | static int __net_init ip6_route_net_init_late(struct net *net) | ||
| 2989 | { | ||
| 2990 | #ifdef CONFIG_PROC_FS | ||
| 2991 | proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); | ||
| 2992 | proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); | ||
| 2993 | #endif | ||
| 2994 | return 0; | ||
| 2995 | } | ||
| 2996 | |||
| 2997 | static void __net_exit ip6_route_net_exit_late(struct net *net) | ||
| 2998 | { | ||
| 2999 | #ifdef CONFIG_PROC_FS | ||
| 3000 | proc_net_remove(net, "ipv6_route"); | ||
| 3001 | proc_net_remove(net, "rt6_stats"); | ||
| 3002 | #endif | ||
| 3003 | } | ||
| 3004 | |||
| 2996 | static struct pernet_operations ip6_route_net_ops = { | 3005 | static struct pernet_operations ip6_route_net_ops = { |
| 2997 | .init = ip6_route_net_init, | 3006 | .init = ip6_route_net_init, |
| 2998 | .exit = ip6_route_net_exit, | 3007 | .exit = ip6_route_net_exit, |
| 2999 | }; | 3008 | }; |
| 3000 | 3009 | ||
| 3010 | static struct pernet_operations ip6_route_net_late_ops = { | ||
| 3011 | .init = ip6_route_net_init_late, | ||
| 3012 | .exit = ip6_route_net_exit_late, | ||
| 3013 | }; | ||
| 3014 | |||
| 3001 | static struct notifier_block ip6_route_dev_notifier = { | 3015 | static struct notifier_block ip6_route_dev_notifier = { |
| 3002 | .notifier_call = ip6_route_dev_notify, | 3016 | .notifier_call = ip6_route_dev_notify, |
| 3003 | .priority = 0, | 3017 | .priority = 0, |
| @@ -3047,19 +3061,25 @@ int __init ip6_route_init(void) | |||
| 3047 | if (ret) | 3061 | if (ret) |
| 3048 | goto xfrm6_init; | 3062 | goto xfrm6_init; |
| 3049 | 3063 | ||
| 3064 | ret = register_pernet_subsys(&ip6_route_net_late_ops); | ||
| 3065 | if (ret) | ||
| 3066 | goto fib6_rules_init; | ||
| 3067 | |||
| 3050 | ret = -ENOBUFS; | 3068 | ret = -ENOBUFS; |
| 3051 | if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || | 3069 | if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || |
| 3052 | __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || | 3070 | __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || |
| 3053 | __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) | 3071 | __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) |
| 3054 | goto fib6_rules_init; | 3072 | goto out_register_late_subsys; |
| 3055 | 3073 | ||
| 3056 | ret = register_netdevice_notifier(&ip6_route_dev_notifier); | 3074 | ret = register_netdevice_notifier(&ip6_route_dev_notifier); |
| 3057 | if (ret) | 3075 | if (ret) |
| 3058 | goto fib6_rules_init; | 3076 | goto out_register_late_subsys; |
| 3059 | 3077 | ||
| 3060 | out: | 3078 | out: |
| 3061 | return ret; | 3079 | return ret; |
| 3062 | 3080 | ||
| 3081 | out_register_late_subsys: | ||
| 3082 | unregister_pernet_subsys(&ip6_route_net_late_ops); | ||
| 3063 | fib6_rules_init: | 3083 | fib6_rules_init: |
| 3064 | fib6_rules_cleanup(); | 3084 | fib6_rules_cleanup(); |
| 3065 | xfrm6_init: | 3085 | xfrm6_init: |
| @@ -3078,6 +3098,7 @@ out_kmem_cache: | |||
| 3078 | void ip6_route_cleanup(void) | 3098 | void ip6_route_cleanup(void) |
| 3079 | { | 3099 | { |
| 3080 | unregister_netdevice_notifier(&ip6_route_dev_notifier); | 3100 | unregister_netdevice_notifier(&ip6_route_dev_notifier); |
| 3101 | unregister_pernet_subsys(&ip6_route_net_late_ops); | ||
| 3081 | fib6_rules_cleanup(); | 3102 | fib6_rules_cleanup(); |
| 3082 | xfrm6_fini(); | 3103 | xfrm6_fini(); |
| 3083 | fib6_gc_cleanup(); | 3104 | fib6_gc_cleanup(); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3a9aec29581a..9df64a50b075 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1212,7 +1212,8 @@ have_isn: | |||
| 1212 | tcp_rsk(req)->snt_isn = isn; | 1212 | tcp_rsk(req)->snt_isn = isn; |
| 1213 | tcp_rsk(req)->snt_synack = tcp_time_stamp; | 1213 | tcp_rsk(req)->snt_synack = tcp_time_stamp; |
| 1214 | 1214 | ||
| 1215 | security_inet_conn_request(sk, skb, req); | 1215 | if (security_inet_conn_request(sk, skb, req)) |
| 1216 | goto drop_and_release; | ||
| 1216 | 1217 | ||
| 1217 | if (tcp_v6_send_synack(sk, req, | 1218 | if (tcp_v6_send_synack(sk, req, |
| 1218 | (struct request_values *)&tmp_ext, | 1219 | (struct request_values *)&tmp_ext, |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 07d7d55a1b93..cd6f7a991d80 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
| @@ -372,7 +372,6 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, | |||
| 372 | skb_trim(skb, skb->dev->mtu); | 372 | skb_trim(skb, skb->dev->mtu); |
| 373 | } | 373 | } |
| 374 | skb->protocol = ETH_P_AF_IUCV; | 374 | skb->protocol = ETH_P_AF_IUCV; |
| 375 | skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; | ||
| 376 | nskb = skb_clone(skb, GFP_ATOMIC); | 375 | nskb = skb_clone(skb, GFP_ATOMIC); |
| 377 | if (!nskb) | 376 | if (!nskb) |
| 378 | return -ENOMEM; | 377 | return -ENOMEM; |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 443591d629ca..47b259fccd27 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
| @@ -42,6 +42,11 @@ struct l2tp_eth { | |||
| 42 | struct sock *tunnel_sock; | 42 | struct sock *tunnel_sock; |
| 43 | struct l2tp_session *session; | 43 | struct l2tp_session *session; |
| 44 | struct list_head list; | 44 | struct list_head list; |
| 45 | atomic_long_t tx_bytes; | ||
| 46 | atomic_long_t tx_packets; | ||
| 47 | atomic_long_t rx_bytes; | ||
| 48 | atomic_long_t rx_packets; | ||
| 49 | atomic_long_t rx_errors; | ||
| 45 | }; | 50 | }; |
| 46 | 51 | ||
| 47 | /* via l2tp_session_priv() */ | 52 | /* via l2tp_session_priv() */ |
| @@ -88,24 +93,40 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 88 | struct l2tp_eth *priv = netdev_priv(dev); | 93 | struct l2tp_eth *priv = netdev_priv(dev); |
| 89 | struct l2tp_session *session = priv->session; | 94 | struct l2tp_session *session = priv->session; |
| 90 | 95 | ||
| 96 | atomic_long_add(skb->len, &priv->tx_bytes); | ||
| 97 | atomic_long_inc(&priv->tx_packets); | ||
| 98 | |||
| 91 | l2tp_xmit_skb(session, skb, session->hdr_len); | 99 | l2tp_xmit_skb(session, skb, session->hdr_len); |
| 92 | 100 | ||
| 93 | dev->stats.tx_bytes += skb->len; | 101 | return NETDEV_TX_OK; |
| 94 | dev->stats.tx_packets++; | 102 | } |
| 95 | 103 | ||
| 96 | return 0; | 104 | static struct rtnl_link_stats64 *l2tp_eth_get_stats64(struct net_device *dev, |
| 105 | struct rtnl_link_stats64 *stats) | ||
| 106 | { | ||
| 107 | struct l2tp_eth *priv = netdev_priv(dev); | ||
| 108 | |||
| 109 | stats->tx_bytes = atomic_long_read(&priv->tx_bytes); | ||
| 110 | stats->tx_packets = atomic_long_read(&priv->tx_packets); | ||
| 111 | stats->rx_bytes = atomic_long_read(&priv->rx_bytes); | ||
| 112 | stats->rx_packets = atomic_long_read(&priv->rx_packets); | ||
| 113 | stats->rx_errors = atomic_long_read(&priv->rx_errors); | ||
| 114 | return stats; | ||
| 97 | } | 115 | } |
| 98 | 116 | ||
| 117 | |||
| 99 | static struct net_device_ops l2tp_eth_netdev_ops = { | 118 | static struct net_device_ops l2tp_eth_netdev_ops = { |
| 100 | .ndo_init = l2tp_eth_dev_init, | 119 | .ndo_init = l2tp_eth_dev_init, |
| 101 | .ndo_uninit = l2tp_eth_dev_uninit, | 120 | .ndo_uninit = l2tp_eth_dev_uninit, |
| 102 | .ndo_start_xmit = l2tp_eth_dev_xmit, | 121 | .ndo_start_xmit = l2tp_eth_dev_xmit, |
| 122 | .ndo_get_stats64 = l2tp_eth_get_stats64, | ||
| 103 | }; | 123 | }; |
| 104 | 124 | ||
| 105 | static void l2tp_eth_dev_setup(struct net_device *dev) | 125 | static void l2tp_eth_dev_setup(struct net_device *dev) |
| 106 | { | 126 | { |
| 107 | ether_setup(dev); | 127 | ether_setup(dev); |
| 108 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | 128 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
| 129 | dev->features |= NETIF_F_LLTX; | ||
| 109 | dev->netdev_ops = &l2tp_eth_netdev_ops; | 130 | dev->netdev_ops = &l2tp_eth_netdev_ops; |
| 110 | dev->destructor = free_netdev; | 131 | dev->destructor = free_netdev; |
| 111 | } | 132 | } |
| @@ -114,17 +135,17 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, | |||
| 114 | { | 135 | { |
| 115 | struct l2tp_eth_sess *spriv = l2tp_session_priv(session); | 136 | struct l2tp_eth_sess *spriv = l2tp_session_priv(session); |
| 116 | struct net_device *dev = spriv->dev; | 137 | struct net_device *dev = spriv->dev; |
| 138 | struct l2tp_eth *priv = netdev_priv(dev); | ||
| 117 | 139 | ||
| 118 | if (session->debug & L2TP_MSG_DATA) { | 140 | if (session->debug & L2TP_MSG_DATA) { |
| 119 | unsigned int length; | 141 | unsigned int length; |
| 120 | u8 *ptr = skb->data; | ||
| 121 | 142 | ||
| 122 | length = min(32u, skb->len); | 143 | length = min(32u, skb->len); |
| 123 | if (!pskb_may_pull(skb, length)) | 144 | if (!pskb_may_pull(skb, length)) |
| 124 | goto error; | 145 | goto error; |
| 125 | 146 | ||
| 126 | pr_debug("%s: eth recv\n", session->name); | 147 | pr_debug("%s: eth recv\n", session->name); |
| 127 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); | 148 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length); |
| 128 | } | 149 | } |
| 129 | 150 | ||
| 130 | if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) | 151 | if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) |
| @@ -139,15 +160,15 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, | |||
| 139 | nf_reset(skb); | 160 | nf_reset(skb); |
| 140 | 161 | ||
| 141 | if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { | 162 | if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { |
| 142 | dev->stats.rx_packets++; | 163 | atomic_long_inc(&priv->rx_packets); |
| 143 | dev->stats.rx_bytes += data_len; | 164 | atomic_long_add(data_len, &priv->rx_bytes); |
| 144 | } else | 165 | } else { |
| 145 | dev->stats.rx_errors++; | 166 | atomic_long_inc(&priv->rx_errors); |
| 146 | 167 | } | |
| 147 | return; | 168 | return; |
| 148 | 169 | ||
| 149 | error: | 170 | error: |
| 150 | dev->stats.rx_errors++; | 171 | atomic_long_inc(&priv->rx_errors); |
| 151 | kfree_skb(skb); | 172 | kfree_skb(skb); |
| 152 | } | 173 | } |
| 153 | 174 | ||
| @@ -162,6 +183,7 @@ static void l2tp_eth_delete(struct l2tp_session *session) | |||
| 162 | if (dev) { | 183 | if (dev) { |
| 163 | unregister_netdev(dev); | 184 | unregister_netdev(dev); |
| 164 | spriv->dev = NULL; | 185 | spriv->dev = NULL; |
| 186 | module_put(THIS_MODULE); | ||
| 165 | } | 187 | } |
| 166 | } | 188 | } |
| 167 | } | 189 | } |
| @@ -249,6 +271,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p | |||
| 249 | if (rc < 0) | 271 | if (rc < 0) |
| 250 | goto out_del_dev; | 272 | goto out_del_dev; |
| 251 | 273 | ||
| 274 | __module_get(THIS_MODULE); | ||
| 252 | /* Must be done after register_netdev() */ | 275 | /* Must be done after register_netdev() */ |
| 253 | strlcpy(session->ifname, dev->name, IFNAMSIZ); | 276 | strlcpy(session->ifname, dev->name, IFNAMSIZ); |
| 254 | 277 | ||
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 70614e7affab..61d8b75d2686 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
| @@ -464,10 +464,12 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
| 464 | sk->sk_bound_dev_if); | 464 | sk->sk_bound_dev_if); |
| 465 | if (IS_ERR(rt)) | 465 | if (IS_ERR(rt)) |
| 466 | goto no_route; | 466 | goto no_route; |
| 467 | if (connected) | 467 | if (connected) { |
| 468 | sk_setup_caps(sk, &rt->dst); | 468 | sk_setup_caps(sk, &rt->dst); |
| 469 | else | 469 | } else { |
| 470 | dst_release(&rt->dst); /* safe since we hold rcu_read_lock */ | 470 | skb_dst_set(skb, &rt->dst); |
| 471 | goto xmit; | ||
| 472 | } | ||
| 471 | } | 473 | } |
| 472 | 474 | ||
| 473 | /* We dont need to clone dst here, it is guaranteed to not disappear. | 475 | /* We dont need to clone dst here, it is guaranteed to not disappear. |
| @@ -475,6 +477,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
| 475 | */ | 477 | */ |
| 476 | skb_dst_set_noref(skb, &rt->dst); | 478 | skb_dst_set_noref(skb, &rt->dst); |
| 477 | 479 | ||
| 480 | xmit: | ||
| 478 | /* Queue the packet to IP for output */ | 481 | /* Queue the packet to IP for output */ |
| 479 | rc = ip_queue_xmit(skb, &inet->cork.fl); | 482 | rc = ip_queue_xmit(skb, &inet->cork.fl); |
| 480 | rcu_read_unlock(); | 483 | rcu_read_unlock(); |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 26ddb699d693..c649188314cc 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
| @@ -145,15 +145,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
| 145 | struct tid_ampdu_rx *tid_rx; | 145 | struct tid_ampdu_rx *tid_rx; |
| 146 | unsigned long timeout; | 146 | unsigned long timeout; |
| 147 | 147 | ||
| 148 | rcu_read_lock(); | ||
| 148 | tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); | 149 | tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); |
| 149 | if (!tid_rx) | 150 | if (!tid_rx) { |
| 151 | rcu_read_unlock(); | ||
| 150 | return; | 152 | return; |
| 153 | } | ||
| 151 | 154 | ||
| 152 | timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout); | 155 | timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout); |
| 153 | if (time_is_after_jiffies(timeout)) { | 156 | if (time_is_after_jiffies(timeout)) { |
| 154 | mod_timer(&tid_rx->session_timer, timeout); | 157 | mod_timer(&tid_rx->session_timer, timeout); |
| 158 | rcu_read_unlock(); | ||
| 155 | return; | 159 | return; |
| 156 | } | 160 | } |
| 161 | rcu_read_unlock(); | ||
| 157 | 162 | ||
| 158 | #ifdef CONFIG_MAC80211_HT_DEBUG | 163 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 159 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 164 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 495831ee48f1..7d5108a867ad 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -533,16 +533,16 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, | |||
| 533 | sinfo.filled = 0; | 533 | sinfo.filled = 0; |
| 534 | sta_set_sinfo(sta, &sinfo); | 534 | sta_set_sinfo(sta, &sinfo); |
| 535 | 535 | ||
| 536 | if (sinfo.filled | STATION_INFO_TX_BITRATE) | 536 | if (sinfo.filled & STATION_INFO_TX_BITRATE) |
| 537 | data[i] = 100000 * | 537 | data[i] = 100000 * |
| 538 | cfg80211_calculate_bitrate(&sinfo.txrate); | 538 | cfg80211_calculate_bitrate(&sinfo.txrate); |
| 539 | i++; | 539 | i++; |
| 540 | if (sinfo.filled | STATION_INFO_RX_BITRATE) | 540 | if (sinfo.filled & STATION_INFO_RX_BITRATE) |
| 541 | data[i] = 100000 * | 541 | data[i] = 100000 * |
| 542 | cfg80211_calculate_bitrate(&sinfo.rxrate); | 542 | cfg80211_calculate_bitrate(&sinfo.rxrate); |
| 543 | i++; | 543 | i++; |
| 544 | 544 | ||
| 545 | if (sinfo.filled | STATION_INFO_SIGNAL_AVG) | 545 | if (sinfo.filled & STATION_INFO_SIGNAL_AVG) |
| 546 | data[i] = (u8)sinfo.signal_avg; | 546 | data[i] = (u8)sinfo.signal_avg; |
| 547 | i++; | 547 | i++; |
| 548 | } else { | 548 | } else { |
| @@ -2093,6 +2093,9 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
| 2093 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2093 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 2094 | int i, ret; | 2094 | int i, ret; |
| 2095 | 2095 | ||
| 2096 | if (!ieee80211_sdata_running(sdata)) | ||
| 2097 | return -ENETDOWN; | ||
| 2098 | |||
| 2096 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { | 2099 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { |
| 2097 | ret = drv_set_bitrate_mask(local, sdata, mask); | 2100 | ret = drv_set_bitrate_mask(local, sdata, mask); |
| 2098 | if (ret) | 2101 | if (ret) |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d4c19a7773db..8664111d0566 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -637,6 +637,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 637 | ieee80211_configure_filter(local); | 637 | ieee80211_configure_filter(local); |
| 638 | break; | 638 | break; |
| 639 | default: | 639 | default: |
| 640 | mutex_lock(&local->mtx); | ||
| 641 | if (local->hw_roc_dev == sdata->dev && | ||
| 642 | local->hw_roc_channel) { | ||
| 643 | /* ignore return value since this is racy */ | ||
| 644 | drv_cancel_remain_on_channel(local); | ||
| 645 | ieee80211_queue_work(&local->hw, &local->hw_roc_done); | ||
| 646 | } | ||
| 647 | mutex_unlock(&local->mtx); | ||
| 648 | |||
| 649 | flush_work(&local->hw_roc_start); | ||
| 650 | flush_work(&local->hw_roc_done); | ||
| 651 | |||
| 640 | flush_work(&sdata->work); | 652 | flush_work(&sdata->work); |
| 641 | /* | 653 | /* |
| 642 | * When we get here, the interface is marked down. | 654 | * When we get here, the interface is marked down. |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 04c306308987..0db5d34a06b6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 1220 | sdata->vif.bss_conf.qos = true; | 1220 | sdata->vif.bss_conf.qos = true; |
| 1221 | } | 1221 | } |
| 1222 | 1222 | ||
| 1223 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | ||
| 1224 | { | ||
| 1225 | lockdep_assert_held(&sdata->local->mtx); | ||
| 1226 | |||
| 1227 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
| 1228 | IEEE80211_STA_BEACON_POLL); | ||
| 1229 | ieee80211_run_deferred_scan(sdata->local); | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | ||
| 1233 | { | ||
| 1234 | mutex_lock(&sdata->local->mtx); | ||
| 1235 | __ieee80211_stop_poll(sdata); | ||
| 1236 | mutex_unlock(&sdata->local->mtx); | ||
| 1237 | } | ||
| 1238 | |||
| 1223 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | 1239 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
| 1224 | u16 capab, bool erp_valid, u8 erp) | 1240 | u16 capab, bool erp_valid, u8 erp) |
| 1225 | { | 1241 | { |
| @@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
| 1285 | sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; | 1301 | sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; |
| 1286 | 1302 | ||
| 1287 | /* just to be sure */ | 1303 | /* just to be sure */ |
| 1288 | sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1304 | ieee80211_stop_poll(sdata); |
| 1289 | IEEE80211_STA_BEACON_POLL); | ||
| 1290 | 1305 | ||
| 1291 | ieee80211_led_assoc(local, 1); | 1306 | ieee80211_led_assoc(local, 1); |
| 1292 | 1307 | ||
| @@ -1327,7 +1342,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1327 | struct ieee80211_local *local = sdata->local; | 1342 | struct ieee80211_local *local = sdata->local; |
| 1328 | struct sta_info *sta; | 1343 | struct sta_info *sta; |
| 1329 | u32 changed = 0; | 1344 | u32 changed = 0; |
| 1330 | u8 bssid[ETH_ALEN]; | ||
| 1331 | 1345 | ||
| 1332 | ASSERT_MGD_MTX(ifmgd); | 1346 | ASSERT_MGD_MTX(ifmgd); |
| 1333 | 1347 | ||
| @@ -1337,10 +1351,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1337 | if (WARN_ON(!ifmgd->associated)) | 1351 | if (WARN_ON(!ifmgd->associated)) |
| 1338 | return; | 1352 | return; |
| 1339 | 1353 | ||
| 1340 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1354 | ieee80211_stop_poll(sdata); |
| 1341 | 1355 | ||
| 1342 | ifmgd->associated = NULL; | 1356 | ifmgd->associated = NULL; |
| 1343 | memset(ifmgd->bssid, 0, ETH_ALEN); | ||
| 1344 | 1357 | ||
| 1345 | /* | 1358 | /* |
| 1346 | * we need to commit the associated = NULL change because the | 1359 | * we need to commit the associated = NULL change because the |
| @@ -1360,7 +1373,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1360 | netif_carrier_off(sdata->dev); | 1373 | netif_carrier_off(sdata->dev); |
| 1361 | 1374 | ||
| 1362 | mutex_lock(&local->sta_mtx); | 1375 | mutex_lock(&local->sta_mtx); |
| 1363 | sta = sta_info_get(sdata, bssid); | 1376 | sta = sta_info_get(sdata, ifmgd->bssid); |
| 1364 | if (sta) { | 1377 | if (sta) { |
| 1365 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); | 1378 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
| 1366 | ieee80211_sta_tear_down_BA_sessions(sta, tx); | 1379 | ieee80211_sta_tear_down_BA_sessions(sta, tx); |
| @@ -1369,13 +1382,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 1369 | 1382 | ||
| 1370 | /* deauthenticate/disassociate now */ | 1383 | /* deauthenticate/disassociate now */ |
| 1371 | if (tx || frame_buf) | 1384 | if (tx || frame_buf) |
| 1372 | ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason, | 1385 | ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, |
| 1373 | tx, frame_buf); | 1386 | reason, tx, frame_buf); |
| 1374 | 1387 | ||
| 1375 | /* flush out frame */ | 1388 | /* flush out frame */ |
| 1376 | if (tx) | 1389 | if (tx) |
| 1377 | drv_flush(local, false); | 1390 | drv_flush(local, false); |
| 1378 | 1391 | ||
| 1392 | /* clear bssid only after building the needed mgmt frames */ | ||
| 1393 | memset(ifmgd->bssid, 0, ETH_ALEN); | ||
| 1394 | |||
| 1379 | /* remove AP and TDLS peers */ | 1395 | /* remove AP and TDLS peers */ |
| 1380 | sta_info_flush(local, sdata); | 1396 | sta_info_flush(local, sdata); |
| 1381 | 1397 | ||
| @@ -1456,8 +1472,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
| 1456 | return; | 1472 | return; |
| 1457 | } | 1473 | } |
| 1458 | 1474 | ||
| 1459 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 1475 | __ieee80211_stop_poll(sdata); |
| 1460 | IEEE80211_STA_BEACON_POLL); | ||
| 1461 | 1476 | ||
| 1462 | mutex_lock(&local->iflist_mtx); | 1477 | mutex_lock(&local->iflist_mtx); |
| 1463 | ieee80211_recalc_ps(local, -1); | 1478 | ieee80211_recalc_ps(local, -1); |
| @@ -1477,7 +1492,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) | |||
| 1477 | round_jiffies_up(jiffies + | 1492 | round_jiffies_up(jiffies + |
| 1478 | IEEE80211_CONNECTION_IDLE_TIME)); | 1493 | IEEE80211_CONNECTION_IDLE_TIME)); |
| 1479 | out: | 1494 | out: |
| 1480 | ieee80211_run_deferred_scan(local); | ||
| 1481 | mutex_unlock(&local->mtx); | 1495 | mutex_unlock(&local->mtx); |
| 1482 | } | 1496 | } |
| 1483 | 1497 | ||
| @@ -2160,15 +2174,13 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2160 | sdata->name, mgmt->sa, status_code); | 2174 | sdata->name, mgmt->sa, status_code); |
| 2161 | ieee80211_destroy_assoc_data(sdata, false); | 2175 | ieee80211_destroy_assoc_data(sdata, false); |
| 2162 | } else { | 2176 | } else { |
| 2163 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | ||
| 2164 | |||
| 2165 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2177 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
| 2166 | /* oops -- internal error -- send timeout for now */ | 2178 | /* oops -- internal error -- send timeout for now */ |
| 2167 | ieee80211_destroy_assoc_data(sdata, true); | 2179 | ieee80211_destroy_assoc_data(sdata, false); |
| 2168 | sta_info_destroy_addr(sdata, mgmt->bssid); | ||
| 2169 | cfg80211_put_bss(*bss); | 2180 | cfg80211_put_bss(*bss); |
| 2170 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; | 2181 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; |
| 2171 | } | 2182 | } |
| 2183 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | ||
| 2172 | 2184 | ||
| 2173 | /* | 2185 | /* |
| 2174 | * destroy assoc_data afterwards, as otherwise an idle | 2186 | * destroy assoc_data afterwards, as otherwise an idle |
| @@ -2408,7 +2420,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 2408 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", | 2420 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", |
| 2409 | sdata->name); | 2421 | sdata->name); |
| 2410 | #endif | 2422 | #endif |
| 2423 | mutex_lock(&local->mtx); | ||
| 2411 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; | 2424 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; |
| 2425 | ieee80211_run_deferred_scan(local); | ||
| 2426 | mutex_unlock(&local->mtx); | ||
| 2427 | |||
| 2412 | mutex_lock(&local->iflist_mtx); | 2428 | mutex_lock(&local->iflist_mtx); |
| 2413 | ieee80211_recalc_ps(local, -1); | 2429 | ieee80211_recalc_ps(local, -1); |
| 2414 | mutex_unlock(&local->iflist_mtx); | 2430 | mutex_unlock(&local->iflist_mtx); |
| @@ -2595,9 +2611,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
| 2595 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2611 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
| 2596 | u8 frame_buf[DEAUTH_DISASSOC_LEN]; | 2612 | u8 frame_buf[DEAUTH_DISASSOC_LEN]; |
| 2597 | 2613 | ||
| 2598 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | ||
| 2599 | IEEE80211_STA_BEACON_POLL); | ||
| 2600 | |||
| 2601 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 2614 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
| 2602 | false, frame_buf); | 2615 | false, frame_buf); |
| 2603 | mutex_unlock(&ifmgd->mtx); | 2616 | mutex_unlock(&ifmgd->mtx); |
| @@ -2874,8 +2887,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
| 2874 | u32 flags; | 2887 | u32 flags; |
| 2875 | 2888 | ||
| 2876 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 2889 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
| 2877 | sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | | 2890 | __ieee80211_stop_poll(sdata); |
| 2878 | IEEE80211_STA_CONNECTION_POLL); | ||
| 2879 | 2891 | ||
| 2880 | /* let's probe the connection once */ | 2892 | /* let's probe the connection once */ |
| 2881 | flags = sdata->local->hw.flags; | 2893 | flags = sdata->local->hw.flags; |
| @@ -2944,7 +2956,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
| 2944 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) | 2956 | if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) |
| 2945 | add_timer(&ifmgd->chswitch_timer); | 2957 | add_timer(&ifmgd->chswitch_timer); |
| 2946 | ieee80211_sta_reset_beacon_monitor(sdata); | 2958 | ieee80211_sta_reset_beacon_monitor(sdata); |
| 2959 | |||
| 2960 | mutex_lock(&sdata->local->mtx); | ||
| 2947 | ieee80211_restart_sta_timer(sdata); | 2961 | ieee80211_restart_sta_timer(sdata); |
| 2962 | mutex_unlock(&sdata->local->mtx); | ||
| 2948 | } | 2963 | } |
| 2949 | #endif | 2964 | #endif |
| 2950 | 2965 | ||
| @@ -3106,7 +3121,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
| 3106 | } | 3121 | } |
| 3107 | 3122 | ||
| 3108 | local->oper_channel = cbss->channel; | 3123 | local->oper_channel = cbss->channel; |
| 3109 | ieee80211_hw_config(local, 0); | 3124 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
| 3110 | 3125 | ||
| 3111 | if (!have_sta) { | 3126 | if (!have_sta) { |
| 3112 | u32 rates = 0, basic_rates = 0; | 3127 | u32 rates = 0, basic_rates = 0; |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index f054e94901a2..935aa4b6deee 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
| @@ -234,6 +234,22 @@ static void ieee80211_hw_roc_done(struct work_struct *work) | |||
| 234 | return; | 234 | return; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | /* was never transmitted */ | ||
| 238 | if (local->hw_roc_skb) { | ||
| 239 | u64 cookie; | ||
| 240 | |||
| 241 | cookie = local->hw_roc_cookie ^ 2; | ||
| 242 | |||
| 243 | cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie, | ||
| 244 | local->hw_roc_skb->data, | ||
| 245 | local->hw_roc_skb->len, false, | ||
| 246 | GFP_KERNEL); | ||
| 247 | |||
| 248 | kfree_skb(local->hw_roc_skb); | ||
| 249 | local->hw_roc_skb = NULL; | ||
| 250 | local->hw_roc_skb_for_status = NULL; | ||
| 251 | } | ||
| 252 | |||
| 237 | if (!local->hw_roc_for_tx) | 253 | if (!local->hw_roc_for_tx) |
| 238 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, | 254 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, |
| 239 | local->hw_roc_cookie, | 255 | local->hw_roc_cookie, |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 2d1acc6c5445..f9e51ef8dfa2 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
| @@ -809,7 +809,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
| 809 | max_rates = sband->n_bitrates; | 809 | max_rates = sband->n_bitrates; |
| 810 | } | 810 | } |
| 811 | 811 | ||
| 812 | msp = kzalloc(sizeof(struct minstrel_ht_sta), gfp); | 812 | msp = kzalloc(sizeof(*msp), gfp); |
| 813 | if (!msp) | 813 | if (!msp) |
| 814 | return NULL; | 814 | return NULL; |
| 815 | 815 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7bcecf73aafb..965e6ec0adb6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2455,7 +2455,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
| 2455 | * frames that we didn't handle, including returning unknown | 2455 | * frames that we didn't handle, including returning unknown |
| 2456 | * ones. For all other modes we will return them to the sender, | 2456 | * ones. For all other modes we will return them to the sender, |
| 2457 | * setting the 0x80 bit in the action category, as required by | 2457 | * setting the 0x80 bit in the action category, as required by |
| 2458 | * 802.11-2007 7.3.1.11. | 2458 | * 802.11-2012 9.24.4. |
| 2459 | * Newer versions of hostapd shall also use the management frame | 2459 | * Newer versions of hostapd shall also use the management frame |
| 2460 | * registration mechanisms, but older ones still use cooked | 2460 | * registration mechanisms, but older ones still use cooked |
| 2461 | * monitor interfaces so push all frames there. | 2461 | * monitor interfaces so push all frames there. |
| @@ -2465,6 +2465,9 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
| 2465 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | 2465 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) |
| 2466 | return RX_DROP_MONITOR; | 2466 | return RX_DROP_MONITOR; |
| 2467 | 2467 | ||
| 2468 | if (is_multicast_ether_addr(mgmt->da)) | ||
| 2469 | return RX_DROP_MONITOR; | ||
| 2470 | |||
| 2468 | /* do not return rejected action frames */ | 2471 | /* do not return rejected action frames */ |
| 2469 | if (mgmt->u.action.category & 0x80) | 2472 | if (mgmt->u.action.category & 0x80) |
| 2470 | return RX_DROP_UNUSABLE; | 2473 | return RX_DROP_UNUSABLE; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f5b1638fbf80..de455f8bbb91 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -378,7 +378,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
| 378 | /* make the station visible */ | 378 | /* make the station visible */ |
| 379 | sta_info_hash_add(local, sta); | 379 | sta_info_hash_add(local, sta); |
| 380 | 380 | ||
| 381 | list_add(&sta->list, &local->sta_list); | 381 | list_add_rcu(&sta->list, &local->sta_list); |
| 382 | 382 | ||
| 383 | set_sta_flag(sta, WLAN_STA_INSERTED); | 383 | set_sta_flag(sta, WLAN_STA_INSERTED); |
| 384 | 384 | ||
| @@ -688,7 +688,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
| 688 | if (ret) | 688 | if (ret) |
| 689 | return ret; | 689 | return ret; |
| 690 | 690 | ||
| 691 | list_del(&sta->list); | 691 | list_del_rcu(&sta->list); |
| 692 | 692 | ||
| 693 | mutex_lock(&local->key_mtx); | 693 | mutex_lock(&local->key_mtx); |
| 694 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) | 694 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 3bb24a121c95..a470e1123a55 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -271,6 +271,9 @@ struct sta_ampdu_mlme { | |||
| 271 | * @plink_timer: peer link watch timer | 271 | * @plink_timer: peer link watch timer |
| 272 | * @plink_timer_was_running: used by suspend/resume to restore timers | 272 | * @plink_timer_was_running: used by suspend/resume to restore timers |
| 273 | * @t_offset: timing offset relative to this host | 273 | * @t_offset: timing offset relative to this host |
| 274 | * @t_offset_setpoint: reference timing offset of this sta to be used when | ||
| 275 | * calculating clockdrift | ||
| 276 | * @ch_type: peer's channel type | ||
| 274 | * @debugfs: debug filesystem info | 277 | * @debugfs: debug filesystem info |
| 275 | * @dead: set to true when sta is unlinked | 278 | * @dead: set to true when sta is unlinked |
| 276 | * @uploaded: set to true when sta is uploaded to the driver | 279 | * @uploaded: set to true when sta is uploaded to the driver |
| @@ -278,6 +281,8 @@ struct sta_ampdu_mlme { | |||
| 278 | * @sta: station information we share with the driver | 281 | * @sta: station information we share with the driver |
| 279 | * @sta_state: duplicates information about station state (for debug) | 282 | * @sta_state: duplicates information about station state (for debug) |
| 280 | * @beacon_loss_count: number of times beacon loss has triggered | 283 | * @beacon_loss_count: number of times beacon loss has triggered |
| 284 | * @supports_40mhz: tracks whether the station advertised 40 MHz support | ||
| 285 | * as we overwrite its HT parameters with the currently used value | ||
| 281 | */ | 286 | */ |
| 282 | struct sta_info { | 287 | struct sta_info { |
| 283 | /* General information, mostly static */ | 288 | /* General information, mostly static */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 847215bb2a6f..e453212fa17f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1737,7 +1737,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1737 | __le16 fc; | 1737 | __le16 fc; |
| 1738 | struct ieee80211_hdr hdr; | 1738 | struct ieee80211_hdr hdr; |
| 1739 | struct ieee80211s_hdr mesh_hdr __maybe_unused; | 1739 | struct ieee80211s_hdr mesh_hdr __maybe_unused; |
| 1740 | struct mesh_path __maybe_unused *mppath = NULL; | 1740 | struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL; |
| 1741 | const u8 *encaps_data; | 1741 | const u8 *encaps_data; |
| 1742 | int encaps_len, skip_header_bytes; | 1742 | int encaps_len, skip_header_bytes; |
| 1743 | int nh_pos, h_pos; | 1743 | int nh_pos, h_pos; |
| @@ -1803,8 +1803,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1803 | goto fail; | 1803 | goto fail; |
| 1804 | } | 1804 | } |
| 1805 | rcu_read_lock(); | 1805 | rcu_read_lock(); |
| 1806 | if (!is_multicast_ether_addr(skb->data)) | 1806 | if (!is_multicast_ether_addr(skb->data)) { |
| 1807 | mppath = mpp_path_lookup(skb->data, sdata); | 1807 | mpath = mesh_path_lookup(skb->data, sdata); |
| 1808 | if (!mpath) | ||
| 1809 | mppath = mpp_path_lookup(skb->data, sdata); | ||
| 1810 | } | ||
| 1808 | 1811 | ||
| 1809 | /* | 1812 | /* |
| 1810 | * Use address extension if it is a packet from | 1813 | * Use address extension if it is a packet from |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a44c6807df01..8dd4712620ff 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -1271,7 +1271,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1271 | enum ieee80211_sta_state state; | 1271 | enum ieee80211_sta_state state; |
| 1272 | 1272 | ||
| 1273 | for (state = IEEE80211_STA_NOTEXIST; | 1273 | for (state = IEEE80211_STA_NOTEXIST; |
| 1274 | state < sta->sta_state - 1; state++) | 1274 | state < sta->sta_state; state++) |
| 1275 | WARN_ON(drv_sta_state(local, sta->sdata, sta, | 1275 | WARN_ON(drv_sta_state(local, sta->sdata, sta, |
| 1276 | state, state + 1)); | 1276 | state, state + 1)); |
| 1277 | } | 1277 | } |
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8781d8f904d9..434b6873b352 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c | |||
| @@ -83,9 +83,10 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, | |||
| 83 | { | 83 | { |
| 84 | struct xmit_work *work; | 84 | struct xmit_work *work; |
| 85 | 85 | ||
| 86 | if (!(priv->phy->channels_supported[page] & (1 << chan))) | 86 | if (!(priv->phy->channels_supported[page] & (1 << chan))) { |
| 87 | WARN_ON(1); | 87 | WARN_ON(1); |
| 88 | return NETDEV_TX_OK; | 88 | return NETDEV_TX_OK; |
| 89 | } | ||
| 89 | 90 | ||
| 90 | if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { | 91 | if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) { |
| 91 | u16 crc = crc_ccitt(0, skb->data, skb->len); | 92 | u16 crc = crc_ccitt(0, skb->data, skb->len); |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 819c342f5b30..9730882697aa 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
| @@ -640,6 +640,14 @@ find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set) | |||
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | static int | 642 | static int |
| 643 | ip_set_none(struct sock *ctnl, struct sk_buff *skb, | ||
| 644 | const struct nlmsghdr *nlh, | ||
| 645 | const struct nlattr * const attr[]) | ||
| 646 | { | ||
| 647 | return -EOPNOTSUPP; | ||
| 648 | } | ||
| 649 | |||
| 650 | static int | ||
| 643 | ip_set_create(struct sock *ctnl, struct sk_buff *skb, | 651 | ip_set_create(struct sock *ctnl, struct sk_buff *skb, |
| 644 | const struct nlmsghdr *nlh, | 652 | const struct nlmsghdr *nlh, |
| 645 | const struct nlattr * const attr[]) | 653 | const struct nlattr * const attr[]) |
| @@ -1539,6 +1547,10 @@ nlmsg_failure: | |||
| 1539 | } | 1547 | } |
| 1540 | 1548 | ||
| 1541 | static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { | 1549 | static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { |
| 1550 | [IPSET_CMD_NONE] = { | ||
| 1551 | .call = ip_set_none, | ||
| 1552 | .attr_count = IPSET_ATTR_CMD_MAX, | ||
| 1553 | }, | ||
| 1542 | [IPSET_CMD_CREATE] = { | 1554 | [IPSET_CMD_CREATE] = { |
| 1543 | .call = ip_set_create, | 1555 | .call = ip_set_create, |
| 1544 | .attr_count = IPSET_ATTR_CMD_MAX, | 1556 | .attr_count = IPSET_ATTR_CMD_MAX, |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index ee863943c826..d5d3607ae7bc 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
| @@ -38,30 +38,6 @@ struct iface_node { | |||
| 38 | 38 | ||
| 39 | #define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) | 39 | #define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) |
| 40 | 40 | ||
| 41 | static inline long | ||
| 42 | ifname_compare(const char *_a, const char *_b) | ||
| 43 | { | ||
| 44 | const long *a = (const long *)_a; | ||
| 45 | const long *b = (const long *)_b; | ||
| 46 | |||
| 47 | BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); | ||
| 48 | if (a[0] != b[0]) | ||
| 49 | return a[0] - b[0]; | ||
| 50 | if (IFNAMSIZ > sizeof(long)) { | ||
| 51 | if (a[1] != b[1]) | ||
| 52 | return a[1] - b[1]; | ||
| 53 | } | ||
| 54 | if (IFNAMSIZ > 2 * sizeof(long)) { | ||
| 55 | if (a[2] != b[2]) | ||
| 56 | return a[2] - b[2]; | ||
| 57 | } | ||
| 58 | if (IFNAMSIZ > 3 * sizeof(long)) { | ||
| 59 | if (a[3] != b[3]) | ||
| 60 | return a[3] - b[3]; | ||
| 61 | } | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static void | 41 | static void |
| 66 | rbtree_destroy(struct rb_root *root) | 42 | rbtree_destroy(struct rb_root *root) |
| 67 | { | 43 | { |
| @@ -99,7 +75,7 @@ iface_test(struct rb_root *root, const char **iface) | |||
| 99 | 75 | ||
| 100 | while (n) { | 76 | while (n) { |
| 101 | const char *d = iface_data(n); | 77 | const char *d = iface_data(n); |
| 102 | long res = ifname_compare(*iface, d); | 78 | int res = strcmp(*iface, d); |
| 103 | 79 | ||
| 104 | if (res < 0) | 80 | if (res < 0) |
| 105 | n = n->rb_left; | 81 | n = n->rb_left; |
| @@ -121,7 +97,7 @@ iface_add(struct rb_root *root, const char **iface) | |||
| 121 | 97 | ||
| 122 | while (*n) { | 98 | while (*n) { |
| 123 | char *ifname = iface_data(*n); | 99 | char *ifname = iface_data(*n); |
| 124 | long res = ifname_compare(*iface, ifname); | 100 | int res = strcmp(*iface, ifname); |
| 125 | 101 | ||
| 126 | p = *n; | 102 | p = *n; |
| 127 | if (res < 0) | 103 | if (res < 0) |
| @@ -366,7 +342,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 366 | struct hash_netiface4_elem data = { .cidr = HOST_MASK }; | 342 | struct hash_netiface4_elem data = { .cidr = HOST_MASK }; |
| 367 | u32 ip = 0, ip_to, last; | 343 | u32 ip = 0, ip_to, last; |
| 368 | u32 timeout = h->timeout; | 344 | u32 timeout = h->timeout; |
| 369 | char iface[IFNAMSIZ] = {}; | 345 | char iface[IFNAMSIZ]; |
| 370 | int ret; | 346 | int ret; |
| 371 | 347 | ||
| 372 | if (unlikely(!tb[IPSET_ATTR_IP] || | 348 | if (unlikely(!tb[IPSET_ATTR_IP] || |
| @@ -663,7 +639,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 663 | ipset_adtfn adtfn = set->variant->adt[adt]; | 639 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 664 | struct hash_netiface6_elem data = { .cidr = HOST_MASK }; | 640 | struct hash_netiface6_elem data = { .cidr = HOST_MASK }; |
| 665 | u32 timeout = h->timeout; | 641 | u32 timeout = h->timeout; |
| 666 | char iface[IFNAMSIZ] = {}; | 642 | char iface[IFNAMSIZ]; |
| 667 | int ret; | 643 | int ret; |
| 668 | 644 | ||
| 669 | if (unlikely(!tb[IPSET_ATTR_IP] || | 645 | if (unlikely(!tb[IPSET_ATTR_IP] || |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index dd811b8dd97c..84444dda194b 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
| @@ -76,19 +76,19 @@ static void __ip_vs_del_service(struct ip_vs_service *svc); | |||
| 76 | 76 | ||
| 77 | #ifdef CONFIG_IP_VS_IPV6 | 77 | #ifdef CONFIG_IP_VS_IPV6 |
| 78 | /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ | 78 | /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ |
| 79 | static int __ip_vs_addr_is_local_v6(struct net *net, | 79 | static bool __ip_vs_addr_is_local_v6(struct net *net, |
| 80 | const struct in6_addr *addr) | 80 | const struct in6_addr *addr) |
| 81 | { | 81 | { |
| 82 | struct rt6_info *rt; | ||
| 83 | struct flowi6 fl6 = { | 82 | struct flowi6 fl6 = { |
| 84 | .daddr = *addr, | 83 | .daddr = *addr, |
| 85 | }; | 84 | }; |
| 85 | struct dst_entry *dst = ip6_route_output(net, NULL, &fl6); | ||
| 86 | bool is_local; | ||
| 86 | 87 | ||
| 87 | rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); | 88 | is_local = !dst->error && dst->dev && (dst->dev->flags & IFF_LOOPBACK); |
| 88 | if (rt && rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) | ||
| 89 | return 1; | ||
| 90 | 89 | ||
| 91 | return 0; | 90 | dst_release(dst); |
| 91 | return is_local; | ||
| 92 | } | 92 | } |
| 93 | #endif | 93 | #endif |
| 94 | 94 | ||
| @@ -1521,11 +1521,12 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event, | |||
| 1521 | { | 1521 | { |
| 1522 | struct net_device *dev = ptr; | 1522 | struct net_device *dev = ptr; |
| 1523 | struct net *net = dev_net(dev); | 1523 | struct net *net = dev_net(dev); |
| 1524 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
| 1524 | struct ip_vs_service *svc; | 1525 | struct ip_vs_service *svc; |
| 1525 | struct ip_vs_dest *dest; | 1526 | struct ip_vs_dest *dest; |
| 1526 | unsigned int idx; | 1527 | unsigned int idx; |
| 1527 | 1528 | ||
| 1528 | if (event != NETDEV_UNREGISTER) | 1529 | if (event != NETDEV_UNREGISTER || !ipvs) |
| 1529 | return NOTIFY_DONE; | 1530 | return NOTIFY_DONE; |
| 1530 | IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name); | 1531 | IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name); |
| 1531 | EnterFunction(2); | 1532 | EnterFunction(2); |
| @@ -1551,7 +1552,7 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event, | |||
| 1551 | } | 1552 | } |
| 1552 | } | 1553 | } |
| 1553 | 1554 | ||
| 1554 | list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) { | 1555 | list_for_each_entry(dest, &ipvs->dest_trash, n_list) { |
| 1555 | __ip_vs_dev_reset(dest, dev); | 1556 | __ip_vs_dev_reset(dest, dev); |
| 1556 | } | 1557 | } |
| 1557 | mutex_unlock(&__ip_vs_mutex); | 1558 | mutex_unlock(&__ip_vs_mutex); |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 46d69d7f1bb4..31f50bc3a312 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
| @@ -270,9 +270,8 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, | |||
| 270 | return 0; | 270 | return 0; |
| 271 | 271 | ||
| 272 | /* RTP port is even */ | 272 | /* RTP port is even */ |
| 273 | port &= htons(~1); | 273 | rtp_port = port & ~htons(1); |
| 274 | rtp_port = port; | 274 | rtcp_port = port | htons(1); |
| 275 | rtcp_port = htons(ntohs(port) + 1); | ||
| 276 | 275 | ||
| 277 | /* Create expect for RTP */ | 276 | /* Create expect for RTP */ |
| 278 | if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL) | 277 | if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL) |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 3e797d1fcb94..791d56bbd74a 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
| @@ -169,8 +169,10 @@ replay: | |||
| 169 | 169 | ||
| 170 | err = nla_parse(cda, ss->cb[cb_id].attr_count, | 170 | err = nla_parse(cda, ss->cb[cb_id].attr_count, |
| 171 | attr, attrlen, ss->cb[cb_id].policy); | 171 | attr, attrlen, ss->cb[cb_id].policy); |
| 172 | if (err < 0) | 172 | if (err < 0) { |
| 173 | rcu_read_unlock(); | ||
| 173 | return err; | 174 | return err; |
| 175 | } | ||
| 174 | 176 | ||
| 175 | if (nc->call_rcu) { | 177 | if (nc->call_rcu) { |
| 176 | err = nc->call_rcu(net->nfnl, skb, nlh, | 178 | err = nc->call_rcu(net->nfnl, skb, nlh, |
diff --git a/net/netfilter/xt_HMARK.c b/net/netfilter/xt_HMARK.c index 0a96a43108ed..1686ca1b53a1 100644 --- a/net/netfilter/xt_HMARK.c +++ b/net/netfilter/xt_HMARK.c | |||
| @@ -32,13 +32,13 @@ MODULE_ALIAS("ipt_HMARK"); | |||
| 32 | MODULE_ALIAS("ip6t_HMARK"); | 32 | MODULE_ALIAS("ip6t_HMARK"); |
| 33 | 33 | ||
| 34 | struct hmark_tuple { | 34 | struct hmark_tuple { |
| 35 | u32 src; | 35 | __be32 src; |
| 36 | u32 dst; | 36 | __be32 dst; |
| 37 | union hmark_ports uports; | 37 | union hmark_ports uports; |
| 38 | uint8_t proto; | 38 | u8 proto; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static inline u32 hmark_addr6_mask(const __u32 *addr32, const __u32 *mask) | 41 | static inline __be32 hmark_addr6_mask(const __be32 *addr32, const __be32 *mask) |
| 42 | { | 42 | { |
| 43 | return (addr32[0] & mask[0]) ^ | 43 | return (addr32[0] & mask[0]) ^ |
| 44 | (addr32[1] & mask[1]) ^ | 44 | (addr32[1] & mask[1]) ^ |
| @@ -46,8 +46,8 @@ static inline u32 hmark_addr6_mask(const __u32 *addr32, const __u32 *mask) | |||
| 46 | (addr32[3] & mask[3]); | 46 | (addr32[3] & mask[3]); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static inline u32 | 49 | static inline __be32 |
| 50 | hmark_addr_mask(int l3num, const __u32 *addr32, const __u32 *mask) | 50 | hmark_addr_mask(int l3num, const __be32 *addr32, const __be32 *mask) |
| 51 | { | 51 | { |
| 52 | switch (l3num) { | 52 | switch (l3num) { |
| 53 | case AF_INET: | 53 | case AF_INET: |
| @@ -58,6 +58,22 @@ hmark_addr_mask(int l3num, const __u32 *addr32, const __u32 *mask) | |||
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | static inline void hmark_swap_ports(union hmark_ports *uports, | ||
| 62 | const struct xt_hmark_info *info) | ||
| 63 | { | ||
| 64 | union hmark_ports hp; | ||
| 65 | u16 src, dst; | ||
| 66 | |||
| 67 | hp.b32 = (uports->b32 & info->port_mask.b32) | info->port_set.b32; | ||
| 68 | src = ntohs(hp.b16.src); | ||
| 69 | dst = ntohs(hp.b16.dst); | ||
| 70 | |||
| 71 | if (dst > src) | ||
| 72 | uports->v32 = (dst << 16) | src; | ||
| 73 | else | ||
| 74 | uports->v32 = (src << 16) | dst; | ||
| 75 | } | ||
| 76 | |||
| 61 | static int | 77 | static int |
| 62 | hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, | 78 | hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, |
| 63 | const struct xt_hmark_info *info) | 79 | const struct xt_hmark_info *info) |
| @@ -74,22 +90,19 @@ hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, | |||
| 74 | otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; | 90 | otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; |
| 75 | rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; | 91 | rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
| 76 | 92 | ||
| 77 | t->src = hmark_addr_mask(otuple->src.l3num, otuple->src.u3.all, | 93 | t->src = hmark_addr_mask(otuple->src.l3num, otuple->src.u3.ip6, |
| 78 | info->src_mask.all); | 94 | info->src_mask.ip6); |
| 79 | t->dst = hmark_addr_mask(otuple->src.l3num, rtuple->src.u3.all, | 95 | t->dst = hmark_addr_mask(otuple->src.l3num, rtuple->src.u3.ip6, |
| 80 | info->dst_mask.all); | 96 | info->dst_mask.ip6); |
| 81 | 97 | ||
| 82 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) | 98 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) |
| 83 | return 0; | 99 | return 0; |
| 84 | 100 | ||
| 85 | t->proto = nf_ct_protonum(ct); | 101 | t->proto = nf_ct_protonum(ct); |
| 86 | if (t->proto != IPPROTO_ICMP) { | 102 | if (t->proto != IPPROTO_ICMP) { |
| 87 | t->uports.p16.src = otuple->src.u.all; | 103 | t->uports.b16.src = otuple->src.u.all; |
| 88 | t->uports.p16.dst = rtuple->src.u.all; | 104 | t->uports.b16.dst = rtuple->src.u.all; |
| 89 | t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | | 105 | hmark_swap_ports(&t->uports, info); |
| 90 | info->port_set.v32; | ||
| 91 | if (t->uports.p16.dst < t->uports.p16.src) | ||
| 92 | swap(t->uports.p16.dst, t->uports.p16.src); | ||
| 93 | } | 106 | } |
| 94 | 107 | ||
| 95 | return 0; | 108 | return 0; |
| @@ -98,15 +111,19 @@ hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, | |||
| 98 | #endif | 111 | #endif |
| 99 | } | 112 | } |
| 100 | 113 | ||
| 114 | /* This hash function is endian independent, to ensure consistent hashing if | ||
| 115 | * the cluster is composed of big and little endian systems. */ | ||
| 101 | static inline u32 | 116 | static inline u32 |
| 102 | hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info) | 117 | hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info) |
| 103 | { | 118 | { |
| 104 | u32 hash; | 119 | u32 hash; |
| 120 | u32 src = ntohl(t->src); | ||
| 121 | u32 dst = ntohl(t->dst); | ||
| 105 | 122 | ||
| 106 | if (t->dst < t->src) | 123 | if (dst < src) |
| 107 | swap(t->src, t->dst); | 124 | swap(src, dst); |
| 108 | 125 | ||
| 109 | hash = jhash_3words(t->src, t->dst, t->uports.v32, info->hashrnd); | 126 | hash = jhash_3words(src, dst, t->uports.v32, info->hashrnd); |
| 110 | hash = hash ^ (t->proto & info->proto_mask); | 127 | hash = hash ^ (t->proto & info->proto_mask); |
| 111 | 128 | ||
| 112 | return (((u64)hash * info->hmodulus) >> 32) + info->hoffset; | 129 | return (((u64)hash * info->hmodulus) >> 32) + info->hoffset; |
| @@ -126,11 +143,7 @@ hmark_set_tuple_ports(const struct sk_buff *skb, unsigned int nhoff, | |||
| 126 | if (skb_copy_bits(skb, nhoff, &t->uports, sizeof(t->uports)) < 0) | 143 | if (skb_copy_bits(skb, nhoff, &t->uports, sizeof(t->uports)) < 0) |
| 127 | return; | 144 | return; |
| 128 | 145 | ||
| 129 | t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | | 146 | hmark_swap_ports(&t->uports, info); |
| 130 | info->port_set.v32; | ||
| 131 | |||
| 132 | if (t->uports.p16.dst < t->uports.p16.src) | ||
| 133 | swap(t->uports.p16.dst, t->uports.p16.src); | ||
| 134 | } | 147 | } |
| 135 | 148 | ||
| 136 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | 149 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
| @@ -178,8 +191,8 @@ hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, | |||
| 178 | return -1; | 191 | return -1; |
| 179 | } | 192 | } |
| 180 | noicmp: | 193 | noicmp: |
| 181 | t->src = hmark_addr6_mask(ip6->saddr.s6_addr32, info->src_mask.all); | 194 | t->src = hmark_addr6_mask(ip6->saddr.s6_addr32, info->src_mask.ip6); |
| 182 | t->dst = hmark_addr6_mask(ip6->daddr.s6_addr32, info->dst_mask.all); | 195 | t->dst = hmark_addr6_mask(ip6->daddr.s6_addr32, info->dst_mask.ip6); |
| 183 | 196 | ||
| 184 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) | 197 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) |
| 185 | return 0; | 198 | return 0; |
| @@ -255,11 +268,8 @@ hmark_pkt_set_htuple_ipv4(const struct sk_buff *skb, struct hmark_tuple *t, | |||
| 255 | } | 268 | } |
| 256 | } | 269 | } |
| 257 | 270 | ||
| 258 | t->src = (__force u32) ip->saddr; | 271 | t->src = ip->saddr & info->src_mask.ip; |
| 259 | t->dst = (__force u32) ip->daddr; | 272 | t->dst = ip->daddr & info->dst_mask.ip; |
| 260 | |||
| 261 | t->src &= info->src_mask.ip; | ||
| 262 | t->dst &= info->dst_mask.ip; | ||
| 263 | 273 | ||
| 264 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) | 274 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) |
| 265 | return 0; | 275 | return 0; |
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 035960ec5cb9..c6f7db720d84 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/netfilter/x_tables.h> | 17 | #include <linux/netfilter/x_tables.h> |
| 18 | #include <linux/netfilter/xt_set.h> | 18 | #include <linux/netfilter/xt_set.h> |
| 19 | #include <linux/netfilter/ipset/ip_set_timeout.h> | ||
| 19 | 20 | ||
| 20 | MODULE_LICENSE("GPL"); | 21 | MODULE_LICENSE("GPL"); |
| 21 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); | 22 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); |
| @@ -310,7 +311,8 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 310 | info->del_set.flags, 0, UINT_MAX); | 311 | info->del_set.flags, 0, UINT_MAX); |
| 311 | 312 | ||
| 312 | /* Normalize to fit into jiffies */ | 313 | /* Normalize to fit into jiffies */ |
| 313 | if (add_opt.timeout > UINT_MAX/MSEC_PER_SEC) | 314 | if (add_opt.timeout != IPSET_NO_TIMEOUT && |
| 315 | add_opt.timeout > UINT_MAX/MSEC_PER_SEC) | ||
| 314 | add_opt.timeout = UINT_MAX/MSEC_PER_SEC; | 316 | add_opt.timeout = UINT_MAX/MSEC_PER_SEC; |
| 315 | if (info->add_set.index != IPSET_INVALID_ID) | 317 | if (info->add_set.index != IPSET_INVALID_ID) |
| 316 | ip_set_add(info->add_set.index, skb, par, &add_opt); | 318 | ip_set_add(info->add_set.index, skb, par, &add_opt); |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 3f339b19d140..e06d458fc719 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
| @@ -292,6 +292,9 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, | |||
| 292 | 292 | ||
| 293 | pr_debug("%p\n", sk); | 293 | pr_debug("%p\n", sk); |
| 294 | 294 | ||
| 295 | if (llcp_sock == NULL || llcp_sock->dev == NULL) | ||
| 296 | return -EBADFD; | ||
| 297 | |||
| 295 | addr->sa_family = AF_NFC; | 298 | addr->sa_family = AF_NFC; |
| 296 | *len = sizeof(struct sockaddr_nfc_llcp); | 299 | *len = sizeof(struct sockaddr_nfc_llcp); |
| 297 | 300 | ||
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index cb2646179e5f..2ab196a9f228 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
| @@ -106,7 +106,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, | |||
| 106 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); | 106 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); |
| 107 | data += 2; | 107 | data += 2; |
| 108 | 108 | ||
| 109 | nfca_poll->nfcid1_len = *data++; | 109 | nfca_poll->nfcid1_len = min_t(__u8, *data++, NFC_NFCID1_MAXSIZE); |
| 110 | 110 | ||
| 111 | pr_debug("sens_res 0x%x, nfcid1_len %d\n", | 111 | pr_debug("sens_res 0x%x, nfcid1_len %d\n", |
| 112 | nfca_poll->sens_res, nfca_poll->nfcid1_len); | 112 | nfca_poll->sens_res, nfca_poll->nfcid1_len); |
| @@ -130,7 +130,7 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, | |||
| 130 | struct rf_tech_specific_params_nfcb_poll *nfcb_poll, | 130 | struct rf_tech_specific_params_nfcb_poll *nfcb_poll, |
| 131 | __u8 *data) | 131 | __u8 *data) |
| 132 | { | 132 | { |
| 133 | nfcb_poll->sensb_res_len = *data++; | 133 | nfcb_poll->sensb_res_len = min_t(__u8, *data++, NFC_SENSB_RES_MAXSIZE); |
| 134 | 134 | ||
| 135 | pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); | 135 | pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); |
| 136 | 136 | ||
| @@ -145,7 +145,7 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, | |||
| 145 | __u8 *data) | 145 | __u8 *data) |
| 146 | { | 146 | { |
| 147 | nfcf_poll->bit_rate = *data++; | 147 | nfcf_poll->bit_rate = *data++; |
| 148 | nfcf_poll->sensf_res_len = *data++; | 148 | nfcf_poll->sensf_res_len = min_t(__u8, *data++, NFC_SENSF_RES_MAXSIZE); |
| 149 | 149 | ||
| 150 | pr_debug("bit_rate %d, sensf_res_len %d\n", | 150 | pr_debug("bit_rate %d, sensf_res_len %d\n", |
| 151 | nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); | 151 | nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); |
| @@ -331,7 +331,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, | |||
| 331 | switch (ntf->activation_rf_tech_and_mode) { | 331 | switch (ntf->activation_rf_tech_and_mode) { |
| 332 | case NCI_NFC_A_PASSIVE_POLL_MODE: | 332 | case NCI_NFC_A_PASSIVE_POLL_MODE: |
| 333 | nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; | 333 | nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; |
| 334 | nfca_poll->rats_res_len = *data++; | 334 | nfca_poll->rats_res_len = min_t(__u8, *data++, 20); |
| 335 | pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); | 335 | pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); |
| 336 | if (nfca_poll->rats_res_len > 0) { | 336 | if (nfca_poll->rats_res_len > 0) { |
| 337 | memcpy(nfca_poll->rats_res, | 337 | memcpy(nfca_poll->rats_res, |
| @@ -341,7 +341,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, | |||
| 341 | 341 | ||
| 342 | case NCI_NFC_B_PASSIVE_POLL_MODE: | 342 | case NCI_NFC_B_PASSIVE_POLL_MODE: |
| 343 | nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; | 343 | nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; |
| 344 | nfcb_poll->attrib_res_len = *data++; | 344 | nfcb_poll->attrib_res_len = min_t(__u8, *data++, 50); |
| 345 | pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); | 345 | pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); |
| 346 | if (nfcb_poll->attrib_res_len > 0) { | 346 | if (nfcb_poll->attrib_res_len > 0) { |
| 347 | memcpy(nfcb_poll->attrib_res, | 347 | memcpy(nfcb_poll->attrib_res, |
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index ec1134c9e07f..8b8a6a2b2bad 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c | |||
| @@ -54,7 +54,10 @@ static int rawsock_release(struct socket *sock) | |||
| 54 | { | 54 | { |
| 55 | struct sock *sk = sock->sk; | 55 | struct sock *sk = sock->sk; |
| 56 | 56 | ||
| 57 | pr_debug("sock=%p\n", sock); | 57 | pr_debug("sock=%p sk=%p\n", sock, sk); |
| 58 | |||
| 59 | if (!sk) | ||
| 60 | return 0; | ||
| 58 | 61 | ||
| 59 | sock_orphan(sk); | 62 | sock_orphan(sk); |
| 60 | sock_put(sk); | 63 | sock_put(sk); |
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 779ce4ff92ec..5a940dbd74a3 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Authors: Sakari Ailus <sakari.ailus@nokia.com> |
| 9 | * Original author: Sakari Ailus <sakari.ailus@nokia.com> | 9 | * Rémi Denis-Courmont |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index bf35b4e1a14c..12c30f3e643e 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Authors: Sakari Ailus <sakari.ailus@nokia.com> |
| 9 | * Original author: Sakari Ailus <sakari.ailus@nokia.com> | 9 | * Rémi Denis-Courmont |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c index d01208968c83..a2fba7edfd1f 100644 --- a/net/phonet/pep-gprs.c +++ b/net/phonet/pep-gprs.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Author: Rémi Denis-Courmont |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| 11 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 9dd4f926f7d1..576f22c9c76e 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Author: Rémi Denis-Courmont |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| 11 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 36f75a9e2c3d..5bf6341e2dd4 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Authors: Sakari Ailus <sakari.ailus@nokia.com> |
| 9 | * Original author: Sakari Ailus <sakari.ailus@nokia.com> | 9 | * Rémi Denis-Courmont |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index cfdf135fcd69..7dd762a464e5 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Authors: Sakari Ailus <sakari.ailus@nokia.com> |
| 9 | * Original author: Sakari Ailus <sakari.ailus@nokia.com> | 9 | * Remi Denis-Courmont |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 89cfa9ce4939..0acc943f713a 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Authors: Sakari Ailus <sakari.ailus@nokia.com> |
| 9 | * Original author: Sakari Ailus <sakari.ailus@nokia.com> | 9 | * Rémi Denis-Courmont |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c index 696348fd31a1..d6bbbbd0af18 100644 --- a/net/phonet/sysctl.c +++ b/net/phonet/sysctl.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2008 Nokia Corporation. | 6 | * Copyright (C) 2008 Nokia Corporation. |
| 7 | * | 7 | * |
| 8 | * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> | 8 | * Author: Rémi Denis-Courmont |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| 11 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index 2754f098d436..bebaa43484bc 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c | |||
| @@ -229,7 +229,7 @@ found_UDP_peer: | |||
| 229 | return peer; | 229 | return peer; |
| 230 | 230 | ||
| 231 | new_UDP_peer: | 231 | new_UDP_peer: |
| 232 | _net("Rx UDP DGRAM from NEW peer %d", peer->debug_id); | 232 | _net("Rx UDP DGRAM from NEW peer"); |
| 233 | read_unlock_bh(&rxrpc_peer_lock); | 233 | read_unlock_bh(&rxrpc_peer_lock); |
| 234 | _leave(" = -EBUSY [new]"); | 234 | _leave(" = -EBUSY [new]"); |
| 235 | return ERR_PTR(-EBUSY); | 235 | return ERR_PTR(-EBUSY); |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index a2a95aabf9c2..c412ad0d0308 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -331,29 +331,22 @@ static psched_time_t packet_len_2_sched_time(unsigned int len, struct netem_sche | |||
| 331 | return PSCHED_NS2TICKS(ticks); | 331 | return PSCHED_NS2TICKS(ticks); |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) | 334 | static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) |
| 335 | { | 335 | { |
| 336 | struct sk_buff_head *list = &sch->q; | 336 | struct sk_buff_head *list = &sch->q; |
| 337 | psched_time_t tnext = netem_skb_cb(nskb)->time_to_send; | 337 | psched_time_t tnext = netem_skb_cb(nskb)->time_to_send; |
| 338 | struct sk_buff *skb; | 338 | struct sk_buff *skb = skb_peek_tail(list); |
| 339 | |||
| 340 | if (likely(skb_queue_len(list) < sch->limit)) { | ||
| 341 | skb = skb_peek_tail(list); | ||
| 342 | /* Optimize for add at tail */ | ||
| 343 | if (likely(!skb || tnext >= netem_skb_cb(skb)->time_to_send)) | ||
| 344 | return qdisc_enqueue_tail(nskb, sch); | ||
| 345 | 339 | ||
| 346 | skb_queue_reverse_walk(list, skb) { | 340 | /* Optimize for add at tail */ |
| 347 | if (tnext >= netem_skb_cb(skb)->time_to_send) | 341 | if (likely(!skb || tnext >= netem_skb_cb(skb)->time_to_send)) |
| 348 | break; | 342 | return __skb_queue_tail(list, nskb); |
| 349 | } | ||
| 350 | 343 | ||
| 351 | __skb_queue_after(list, skb, nskb); | 344 | skb_queue_reverse_walk(list, skb) { |
| 352 | sch->qstats.backlog += qdisc_pkt_len(nskb); | 345 | if (tnext >= netem_skb_cb(skb)->time_to_send) |
| 353 | return NET_XMIT_SUCCESS; | 346 | break; |
| 354 | } | 347 | } |
| 355 | 348 | ||
| 356 | return qdisc_reshape_fail(nskb, sch); | 349 | __skb_queue_after(list, skb, nskb); |
| 357 | } | 350 | } |
| 358 | 351 | ||
| 359 | /* | 352 | /* |
| @@ -368,7 +361,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 368 | /* We don't fill cb now as skb_unshare() may invalidate it */ | 361 | /* We don't fill cb now as skb_unshare() may invalidate it */ |
| 369 | struct netem_skb_cb *cb; | 362 | struct netem_skb_cb *cb; |
| 370 | struct sk_buff *skb2; | 363 | struct sk_buff *skb2; |
| 371 | int ret; | ||
| 372 | int count = 1; | 364 | int count = 1; |
| 373 | 365 | ||
| 374 | /* Random duplication */ | 366 | /* Random duplication */ |
| @@ -419,6 +411,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 419 | skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); | 411 | skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); |
| 420 | } | 412 | } |
| 421 | 413 | ||
| 414 | if (unlikely(skb_queue_len(&sch->q) >= sch->limit)) | ||
| 415 | return qdisc_reshape_fail(skb, sch); | ||
| 416 | |||
| 417 | sch->qstats.backlog += qdisc_pkt_len(skb); | ||
| 418 | |||
| 422 | cb = netem_skb_cb(skb); | 419 | cb = netem_skb_cb(skb); |
| 423 | if (q->gap == 0 || /* not doing reordering */ | 420 | if (q->gap == 0 || /* not doing reordering */ |
| 424 | q->counter < q->gap - 1 || /* inside last reordering gap */ | 421 | q->counter < q->gap - 1 || /* inside last reordering gap */ |
| @@ -450,7 +447,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 450 | 447 | ||
| 451 | cb->time_to_send = now + delay; | 448 | cb->time_to_send = now + delay; |
| 452 | ++q->counter; | 449 | ++q->counter; |
| 453 | ret = tfifo_enqueue(skb, sch); | 450 | tfifo_enqueue(skb, sch); |
| 454 | } else { | 451 | } else { |
| 455 | /* | 452 | /* |
| 456 | * Do re-ordering by putting one out of N packets at the front | 453 | * Do re-ordering by putting one out of N packets at the front |
| @@ -460,16 +457,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 460 | q->counter = 0; | 457 | q->counter = 0; |
| 461 | 458 | ||
| 462 | __skb_queue_head(&sch->q, skb); | 459 | __skb_queue_head(&sch->q, skb); |
| 463 | sch->qstats.backlog += qdisc_pkt_len(skb); | ||
| 464 | sch->qstats.requeues++; | 460 | sch->qstats.requeues++; |
| 465 | ret = NET_XMIT_SUCCESS; | ||
| 466 | } | ||
| 467 | |||
| 468 | if (ret != NET_XMIT_SUCCESS) { | ||
| 469 | if (net_xmit_drop_count(ret)) { | ||
| 470 | sch->qstats.drops++; | ||
| 471 | return ret; | ||
| 472 | } | ||
| 473 | } | 461 | } |
| 474 | 462 | ||
| 475 | return NET_XMIT_SUCCESS; | 463 | return NET_XMIT_SUCCESS; |
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 74305c883bd3..30ea4674cabd 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c | |||
| @@ -570,6 +570,8 @@ static int sfb_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
| 570 | 570 | ||
| 571 | sch->qstats.backlog = q->qdisc->qstats.backlog; | 571 | sch->qstats.backlog = q->qdisc->qstats.backlog; |
| 572 | opts = nla_nest_start(skb, TCA_OPTIONS); | 572 | opts = nla_nest_start(skb, TCA_OPTIONS); |
| 573 | if (opts == NULL) | ||
| 574 | goto nla_put_failure; | ||
| 573 | if (nla_put(skb, TCA_SFB_PARMS, sizeof(opt), &opt)) | 575 | if (nla_put(skb, TCA_SFB_PARMS, sizeof(opt), &opt)) |
| 574 | goto nla_put_failure; | 576 | goto nla_put_failure; |
| 575 | return nla_nest_end(skb, opts); | 577 | return nla_nest_end(skb, opts); |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 5bc9ab161b37..b16517ee1aaf 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -271,6 +271,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 271 | */ | 271 | */ |
| 272 | asoc->peer.sack_needed = 1; | 272 | asoc->peer.sack_needed = 1; |
| 273 | asoc->peer.sack_cnt = 0; | 273 | asoc->peer.sack_cnt = 0; |
| 274 | asoc->peer.sack_generation = 1; | ||
| 274 | 275 | ||
| 275 | /* Assume that the peer will tell us if he recognizes ASCONF | 276 | /* Assume that the peer will tell us if he recognizes ASCONF |
| 276 | * as part of INIT exchange. | 277 | * as part of INIT exchange. |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 80564fe03024..8b9b6790a3df 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -736,15 +736,12 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) | |||
| 736 | 736 | ||
| 737 | epb = &ep->base; | 737 | epb = &ep->base; |
| 738 | 738 | ||
| 739 | if (hlist_unhashed(&epb->node)) | ||
| 740 | return; | ||
| 741 | |||
| 742 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); | 739 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); |
| 743 | 740 | ||
| 744 | head = &sctp_ep_hashtable[epb->hashent]; | 741 | head = &sctp_ep_hashtable[epb->hashent]; |
| 745 | 742 | ||
| 746 | sctp_write_lock(&head->lock); | 743 | sctp_write_lock(&head->lock); |
| 747 | __hlist_del(&epb->node); | 744 | hlist_del_init(&epb->node); |
| 748 | sctp_write_unlock(&head->lock); | 745 | sctp_write_unlock(&head->lock); |
| 749 | } | 746 | } |
| 750 | 747 | ||
| @@ -825,7 +822,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc) | |||
| 825 | head = &sctp_assoc_hashtable[epb->hashent]; | 822 | head = &sctp_assoc_hashtable[epb->hashent]; |
| 826 | 823 | ||
| 827 | sctp_write_lock(&head->lock); | 824 | sctp_write_lock(&head->lock); |
| 828 | __hlist_del(&epb->node); | 825 | hlist_del_init(&epb->node); |
| 829 | sctp_write_unlock(&head->lock); | 826 | sctp_write_unlock(&head->lock); |
| 830 | } | 827 | } |
| 831 | 828 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index f1b7d4bb591e..6ae47acaaec6 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -248,6 +248,11 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, | |||
| 248 | /* If the SACK timer is running, we have a pending SACK */ | 248 | /* If the SACK timer is running, we have a pending SACK */ |
| 249 | if (timer_pending(timer)) { | 249 | if (timer_pending(timer)) { |
| 250 | struct sctp_chunk *sack; | 250 | struct sctp_chunk *sack; |
| 251 | |||
| 252 | if (pkt->transport->sack_generation != | ||
| 253 | pkt->transport->asoc->peer.sack_generation) | ||
| 254 | return retval; | ||
| 255 | |||
| 251 | asoc->a_rwnd = asoc->rwnd; | 256 | asoc->a_rwnd = asoc->rwnd; |
| 252 | sack = sctp_make_sack(asoc); | 257 | sack = sctp_make_sack(asoc); |
| 253 | if (sack) { | 258 | if (sack) { |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5942d27b1444..9c90811d1134 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -673,7 +673,9 @@ void sctp_addr_wq_timeout_handler(unsigned long arg) | |||
| 673 | SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: sctp_asconf_mgmt failed\n"); | 673 | SCTP_DEBUG_PRINTK("sctp_addrwq_timo_handler: sctp_asconf_mgmt failed\n"); |
| 674 | sctp_bh_unlock_sock(sk); | 674 | sctp_bh_unlock_sock(sk); |
| 675 | } | 675 | } |
| 676 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 676 | free_next: | 677 | free_next: |
| 678 | #endif | ||
| 677 | list_del(&addrw->list); | 679 | list_del(&addrw->list); |
| 678 | kfree(addrw); | 680 | kfree(addrw); |
| 679 | } | 681 | } |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index a85eeeb55dd0..b6de71efb140 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -734,8 +734,10 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) | |||
| 734 | int len; | 734 | int len; |
| 735 | __u32 ctsn; | 735 | __u32 ctsn; |
| 736 | __u16 num_gabs, num_dup_tsns; | 736 | __u16 num_gabs, num_dup_tsns; |
| 737 | struct sctp_association *aptr = (struct sctp_association *)asoc; | ||
| 737 | struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; | 738 | struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; |
| 738 | struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; | 739 | struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; |
| 740 | struct sctp_transport *trans; | ||
| 739 | 741 | ||
| 740 | memset(gabs, 0, sizeof(gabs)); | 742 | memset(gabs, 0, sizeof(gabs)); |
| 741 | ctsn = sctp_tsnmap_get_ctsn(map); | 743 | ctsn = sctp_tsnmap_get_ctsn(map); |
| @@ -805,6 +807,20 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) | |||
| 805 | sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, | 807 | sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, |
| 806 | sctp_tsnmap_get_dups(map)); | 808 | sctp_tsnmap_get_dups(map)); |
| 807 | 809 | ||
| 810 | /* Once we have a sack generated, check to see what our sack | ||
| 811 | * generation is, if its 0, reset the transports to 0, and reset | ||
| 812 | * the association generation to 1 | ||
| 813 | * | ||
| 814 | * The idea is that zero is never used as a valid generation for the | ||
| 815 | * association so no transport will match after a wrap event like this, | ||
| 816 | * Until the next sack | ||
| 817 | */ | ||
| 818 | if (++aptr->peer.sack_generation == 0) { | ||
| 819 | list_for_each_entry(trans, &asoc->peer.transport_addr_list, | ||
| 820 | transports) | ||
| 821 | trans->sack_generation = 0; | ||
| 822 | aptr->peer.sack_generation = 1; | ||
| 823 | } | ||
| 808 | nodata: | 824 | nodata: |
| 809 | return retval; | 825 | return retval; |
| 810 | } | 826 | } |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index c96d1a81cf42..8716da1a8592 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -1268,7 +1268,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 1268 | case SCTP_CMD_REPORT_TSN: | 1268 | case SCTP_CMD_REPORT_TSN: |
| 1269 | /* Record the arrival of a TSN. */ | 1269 | /* Record the arrival of a TSN. */ |
| 1270 | error = sctp_tsnmap_mark(&asoc->peer.tsn_map, | 1270 | error = sctp_tsnmap_mark(&asoc->peer.tsn_map, |
| 1271 | cmd->obj.u32); | 1271 | cmd->obj.u32, NULL); |
| 1272 | break; | 1272 | break; |
| 1273 | 1273 | ||
| 1274 | case SCTP_CMD_REPORT_FWDTSN: | 1274 | case SCTP_CMD_REPORT_FWDTSN: |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b3b8a8d813eb..31c7bfcd9b58 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -1231,8 +1231,14 @@ out_free: | |||
| 1231 | SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p" | 1231 | SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p" |
| 1232 | " kaddrs: %p err: %d\n", | 1232 | " kaddrs: %p err: %d\n", |
| 1233 | asoc, kaddrs, err); | 1233 | asoc, kaddrs, err); |
| 1234 | if (asoc) | 1234 | if (asoc) { |
| 1235 | /* sctp_primitive_ASSOCIATE may have added this association | ||
| 1236 | * To the hash table, try to unhash it, just in case, its a noop | ||
| 1237 | * if it wasn't hashed so we're safe | ||
| 1238 | */ | ||
| 1239 | sctp_unhash_established(asoc); | ||
| 1235 | sctp_association_free(asoc); | 1240 | sctp_association_free(asoc); |
| 1241 | } | ||
| 1236 | return err; | 1242 | return err; |
| 1237 | } | 1243 | } |
| 1238 | 1244 | ||
| @@ -1942,8 +1948,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1942 | goto out_unlock; | 1948 | goto out_unlock; |
| 1943 | 1949 | ||
| 1944 | out_free: | 1950 | out_free: |
| 1945 | if (new_asoc) | 1951 | if (new_asoc) { |
| 1952 | sctp_unhash_established(asoc); | ||
| 1946 | sctp_association_free(asoc); | 1953 | sctp_association_free(asoc); |
| 1954 | } | ||
| 1947 | out_unlock: | 1955 | out_unlock: |
| 1948 | sctp_release_sock(sk); | 1956 | sctp_release_sock(sk); |
| 1949 | 1957 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index b026ba0c6992..1dcceb6e0ce6 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -68,6 +68,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
| 68 | peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); | 68 | peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); |
| 69 | memset(&peer->saddr, 0, sizeof(union sctp_addr)); | 69 | memset(&peer->saddr, 0, sizeof(union sctp_addr)); |
| 70 | 70 | ||
| 71 | peer->sack_generation = 0; | ||
| 72 | |||
| 71 | /* From 6.3.1 RTO Calculation: | 73 | /* From 6.3.1 RTO Calculation: |
| 72 | * | 74 | * |
| 73 | * C1) Until an RTT measurement has been made for a packet sent to the | 75 | * C1) Until an RTT measurement has been made for a packet sent to the |
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c index f1e40cebc981..b5fb7c409023 100644 --- a/net/sctp/tsnmap.c +++ b/net/sctp/tsnmap.c | |||
| @@ -114,7 +114,8 @@ int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn) | |||
| 114 | 114 | ||
| 115 | 115 | ||
| 116 | /* Mark this TSN as seen. */ | 116 | /* Mark this TSN as seen. */ |
| 117 | int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) | 117 | int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn, |
| 118 | struct sctp_transport *trans) | ||
| 118 | { | 119 | { |
| 119 | u16 gap; | 120 | u16 gap; |
| 120 | 121 | ||
| @@ -133,6 +134,9 @@ int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) | |||
| 133 | */ | 134 | */ |
| 134 | map->max_tsn_seen++; | 135 | map->max_tsn_seen++; |
| 135 | map->cumulative_tsn_ack_point++; | 136 | map->cumulative_tsn_ack_point++; |
| 137 | if (trans) | ||
| 138 | trans->sack_generation = | ||
| 139 | trans->asoc->peer.sack_generation; | ||
| 136 | map->base_tsn++; | 140 | map->base_tsn++; |
| 137 | } else { | 141 | } else { |
| 138 | /* Either we already have a gap, or about to record a gap, so | 142 | /* Either we already have a gap, or about to record a gap, so |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 8a84017834c2..33d894776192 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -715,7 +715,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | |||
| 715 | * can mark it as received so the tsn_map is updated correctly. | 715 | * can mark it as received so the tsn_map is updated correctly. |
| 716 | */ | 716 | */ |
| 717 | if (sctp_tsnmap_mark(&asoc->peer.tsn_map, | 717 | if (sctp_tsnmap_mark(&asoc->peer.tsn_map, |
| 718 | ntohl(chunk->subh.data_hdr->tsn))) | 718 | ntohl(chunk->subh.data_hdr->tsn), |
| 719 | chunk->transport)) | ||
| 719 | goto fail_mark; | 720 | goto fail_mark; |
| 720 | 721 | ||
| 721 | /* First calculate the padding, so we don't inadvertently | 722 | /* First calculate the padding, so we don't inadvertently |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index f2d1de7f2ffb..f5a6a4f4faf7 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
| @@ -1051,7 +1051,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | |||
| 1051 | if (chunk && (freed >= needed)) { | 1051 | if (chunk && (freed >= needed)) { |
| 1052 | __u32 tsn; | 1052 | __u32 tsn; |
| 1053 | tsn = ntohl(chunk->subh.data_hdr->tsn); | 1053 | tsn = ntohl(chunk->subh.data_hdr->tsn); |
| 1054 | sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn); | 1054 | sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport); |
| 1055 | sctp_ulpq_tail_data(ulpq, chunk, gfp); | 1055 | sctp_ulpq_tail_data(ulpq, chunk, gfp); |
| 1056 | 1056 | ||
| 1057 | sctp_ulpq_partial_delivery(ulpq, chunk, gfp); | 1057 | sctp_ulpq_partial_delivery(ulpq, chunk, gfp); |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 04040476082e..21fde99e5c56 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -71,7 +71,9 @@ static void rpc_purge_list(wait_queue_head_t *waitq, struct list_head *head, | |||
| 71 | msg->errno = err; | 71 | msg->errno = err; |
| 72 | destroy_msg(msg); | 72 | destroy_msg(msg); |
| 73 | } while (!list_empty(head)); | 73 | } while (!list_empty(head)); |
| 74 | wake_up(waitq); | 74 | |
| 75 | if (waitq) | ||
| 76 | wake_up(waitq); | ||
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | static void | 79 | static void |
| @@ -91,11 +93,9 @@ rpc_timeout_upcall_queue(struct work_struct *work) | |||
| 91 | } | 93 | } |
| 92 | dentry = dget(pipe->dentry); | 94 | dentry = dget(pipe->dentry); |
| 93 | spin_unlock(&pipe->lock); | 95 | spin_unlock(&pipe->lock); |
| 94 | if (dentry) { | 96 | rpc_purge_list(dentry ? &RPC_I(dentry->d_inode)->waitq : NULL, |
| 95 | rpc_purge_list(&RPC_I(dentry->d_inode)->waitq, | 97 | &free_list, destroy_msg, -ETIMEDOUT); |
| 96 | &free_list, destroy_msg, -ETIMEDOUT); | 98 | dput(dentry); |
| 97 | dput(dentry); | ||
| 98 | } | ||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg, | 101 | ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg, |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 7e9baaa1e543..3ee7461926d8 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -1374,7 +1374,8 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
| 1374 | sizeof(req->rq_snd_buf)); | 1374 | sizeof(req->rq_snd_buf)); |
| 1375 | return bc_send(req); | 1375 | return bc_send(req); |
| 1376 | } else { | 1376 | } else { |
| 1377 | /* Nothing to do to drop request */ | 1377 | /* drop request */ |
| 1378 | xprt_free_bc_request(req); | ||
| 1378 | return 0; | 1379 | return 0; |
| 1379 | } | 1380 | } |
| 1380 | } | 1381 | } |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index d2a19b0ff71f..89baa3328411 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
| @@ -42,6 +42,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) | |||
| 42 | cfg80211_hold_bss(bss_from_pub(bss)); | 42 | cfg80211_hold_bss(bss_from_pub(bss)); |
| 43 | wdev->current_bss = bss_from_pub(bss); | 43 | wdev->current_bss = bss_from_pub(bss); |
| 44 | 44 | ||
| 45 | wdev->sme_state = CFG80211_SME_CONNECTED; | ||
| 45 | cfg80211_upload_connect_keys(wdev); | 46 | cfg80211_upload_connect_keys(wdev); |
| 46 | 47 | ||
| 47 | nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, | 48 | nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, |
| @@ -60,7 +61,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) | |||
| 60 | struct cfg80211_event *ev; | 61 | struct cfg80211_event *ev; |
| 61 | unsigned long flags; | 62 | unsigned long flags; |
| 62 | 63 | ||
| 63 | CFG80211_DEV_WARN_ON(!wdev->ssid_len); | 64 | CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING); |
| 64 | 65 | ||
| 65 | ev = kzalloc(sizeof(*ev), gfp); | 66 | ev = kzalloc(sizeof(*ev), gfp); |
| 66 | if (!ev) | 67 | if (!ev) |
| @@ -115,9 +116,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
| 115 | #ifdef CONFIG_CFG80211_WEXT | 116 | #ifdef CONFIG_CFG80211_WEXT |
| 116 | wdev->wext.ibss.channel = params->channel; | 117 | wdev->wext.ibss.channel = params->channel; |
| 117 | #endif | 118 | #endif |
| 119 | wdev->sme_state = CFG80211_SME_CONNECTING; | ||
| 118 | err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); | 120 | err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); |
| 119 | if (err) { | 121 | if (err) { |
| 120 | wdev->connect_keys = NULL; | 122 | wdev->connect_keys = NULL; |
| 123 | wdev->sme_state = CFG80211_SME_IDLE; | ||
| 121 | return err; | 124 | return err; |
| 122 | } | 125 | } |
| 123 | 126 | ||
| @@ -169,6 +172,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | |||
| 169 | } | 172 | } |
| 170 | 173 | ||
| 171 | wdev->current_bss = NULL; | 174 | wdev->current_bss = NULL; |
| 175 | wdev->sme_state = CFG80211_SME_IDLE; | ||
| 172 | wdev->ssid_len = 0; | 176 | wdev->ssid_len = 0; |
| 173 | #ifdef CONFIG_CFG80211_WEXT | 177 | #ifdef CONFIG_CFG80211_WEXT |
| 174 | if (!nowext) | 178 | if (!nowext) |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 15f347477a99..baf5704740ee 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -1389,7 +1389,7 @@ static void reg_set_request_processed(void) | |||
| 1389 | spin_unlock(®_requests_lock); | 1389 | spin_unlock(®_requests_lock); |
| 1390 | 1390 | ||
| 1391 | if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) | 1391 | if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) |
| 1392 | cancel_delayed_work_sync(®_timeout); | 1392 | cancel_delayed_work(®_timeout); |
| 1393 | 1393 | ||
| 1394 | if (need_more_processing) | 1394 | if (need_more_processing) |
| 1395 | schedule_work(®_work); | 1395 | schedule_work(®_work); |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 55d99466babb..316cfd00914f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -804,7 +804,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
| 804 | ntype == NL80211_IFTYPE_P2P_CLIENT)) | 804 | ntype == NL80211_IFTYPE_P2P_CLIENT)) |
| 805 | return -EBUSY; | 805 | return -EBUSY; |
| 806 | 806 | ||
| 807 | if (ntype != otype) { | 807 | if (ntype != otype && netif_running(dev)) { |
| 808 | err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, | 808 | err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, |
| 809 | ntype); | 809 | ntype); |
| 810 | if (err) | 810 | if (err) |
| @@ -935,6 +935,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | |||
| 935 | enum nl80211_iftype iftype) | 935 | enum nl80211_iftype iftype) |
| 936 | { | 936 | { |
| 937 | struct wireless_dev *wdev_iter; | 937 | struct wireless_dev *wdev_iter; |
| 938 | u32 used_iftypes = BIT(iftype); | ||
| 938 | int num[NUM_NL80211_IFTYPES]; | 939 | int num[NUM_NL80211_IFTYPES]; |
| 939 | int total = 1; | 940 | int total = 1; |
| 940 | int i, j; | 941 | int i, j; |
| @@ -961,6 +962,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | |||
| 961 | 962 | ||
| 962 | num[wdev_iter->iftype]++; | 963 | num[wdev_iter->iftype]++; |
| 963 | total++; | 964 | total++; |
| 965 | used_iftypes |= BIT(wdev_iter->iftype); | ||
| 964 | } | 966 | } |
| 965 | mutex_unlock(&rdev->devlist_mtx); | 967 | mutex_unlock(&rdev->devlist_mtx); |
| 966 | 968 | ||
| @@ -970,6 +972,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | |||
| 970 | for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { | 972 | for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { |
| 971 | const struct ieee80211_iface_combination *c; | 973 | const struct ieee80211_iface_combination *c; |
| 972 | struct ieee80211_iface_limit *limits; | 974 | struct ieee80211_iface_limit *limits; |
| 975 | u32 all_iftypes = 0; | ||
| 973 | 976 | ||
| 974 | c = &rdev->wiphy.iface_combinations[i]; | 977 | c = &rdev->wiphy.iface_combinations[i]; |
| 975 | 978 | ||
| @@ -984,6 +987,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | |||
| 984 | if (rdev->wiphy.software_iftypes & BIT(iftype)) | 987 | if (rdev->wiphy.software_iftypes & BIT(iftype)) |
| 985 | continue; | 988 | continue; |
| 986 | for (j = 0; j < c->n_limits; j++) { | 989 | for (j = 0; j < c->n_limits; j++) { |
| 990 | all_iftypes |= limits[j].types; | ||
| 987 | if (!(limits[j].types & BIT(iftype))) | 991 | if (!(limits[j].types & BIT(iftype))) |
| 988 | continue; | 992 | continue; |
| 989 | if (limits[j].max < num[iftype]) | 993 | if (limits[j].max < num[iftype]) |
| @@ -991,7 +995,20 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | |||
| 991 | limits[j].max -= num[iftype]; | 995 | limits[j].max -= num[iftype]; |
| 992 | } | 996 | } |
| 993 | } | 997 | } |
| 994 | /* yay, it fits */ | 998 | |
| 999 | /* | ||
| 1000 | * Finally check that all iftypes that we're currently | ||
| 1001 | * using are actually part of this combination. If they | ||
| 1002 | * aren't then we can't use this combination and have | ||
| 1003 | * to continue to the next. | ||
| 1004 | */ | ||
| 1005 | if ((all_iftypes & used_iftypes) != used_iftypes) | ||
| 1006 | goto cont; | ||
| 1007 | |||
| 1008 | /* | ||
| 1009 | * This combination covered all interface types and | ||
| 1010 | * supported the requested numbers, so we're good. | ||
| 1011 | */ | ||
| 995 | kfree(limits); | 1012 | kfree(limits); |
| 996 | return 0; | 1013 | return 0; |
| 997 | cont: | 1014 | cont: |
