diff options
Diffstat (limited to 'net')
50 files changed, 479 insertions, 268 deletions
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index fc1835c6bb40..00f9e144cc97 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb) | |||
251 | kfree(entry); | 251 | kfree(entry); |
252 | 252 | ||
253 | /* Make room for the rest of the fragments. */ | 253 | /* Make room for the rest of the fragments. */ |
254 | if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) { | 254 | if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { |
255 | kfree_skb(skb_out); | 255 | kfree_skb(skb_out); |
256 | skb_out = NULL; | 256 | skb_out = NULL; |
257 | goto free; | 257 | goto free; |
@@ -434,7 +434,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb, | |||
434 | * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE | 434 | * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE |
435 | */ | 435 | */ |
436 | mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE); | 436 | mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE); |
437 | max_fragment_size = (mtu - header_size - ETH_HLEN); | 437 | max_fragment_size = mtu - header_size; |
438 | max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; | 438 | max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; |
439 | 439 | ||
440 | /* Don't even try to fragment, if we need more than 16 fragments */ | 440 | /* Don't even try to fragment, if we need more than 16 fragments */ |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 90cff585b37d..e0bcf9e84273 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -810,7 +810,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, | |||
810 | goto out; | 810 | goto out; |
811 | 811 | ||
812 | gw_node = batadv_gw_node_get(bat_priv, orig_dst_node); | 812 | gw_node = batadv_gw_node_get(bat_priv, orig_dst_node); |
813 | if (!gw_node->bandwidth_down == 0) | 813 | if (!gw_node) |
814 | goto out; | 814 | goto out; |
815 | 815 | ||
816 | switch (atomic_read(&bat_priv->gw_mode)) { | 816 | switch (atomic_read(&bat_priv->gw_mode)) { |
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index ab6bb2af1d45..b24e4bb64fb5 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c | |||
@@ -685,11 +685,13 @@ static void batadv_mcast_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, | |||
685 | if (orig_initialized) | 685 | if (orig_initialized) |
686 | atomic_dec(&bat_priv->mcast.num_disabled); | 686 | atomic_dec(&bat_priv->mcast.num_disabled); |
687 | orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST; | 687 | orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST; |
688 | /* If mcast support is being switched off increase the disabled | 688 | /* If mcast support is being switched off or if this is an initial |
689 | * mcast node counter. | 689 | * OGM without mcast support then increase the disabled mcast |
690 | * node counter. | ||
690 | */ | 691 | */ |
691 | } else if (!orig_mcast_enabled && | 692 | } else if (!orig_mcast_enabled && |
692 | orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) { | 693 | (orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST || |
694 | !orig_initialized)) { | ||
693 | atomic_inc(&bat_priv->mcast.num_disabled); | 695 | atomic_inc(&bat_priv->mcast.num_disabled); |
694 | orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST; | 696 | orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST; |
695 | } | 697 | } |
@@ -738,7 +740,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig) | |||
738 | { | 740 | { |
739 | struct batadv_priv *bat_priv = orig->bat_priv; | 741 | struct batadv_priv *bat_priv = orig->bat_priv; |
740 | 742 | ||
741 | if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) | 743 | if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) && |
744 | orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST) | ||
742 | atomic_dec(&bat_priv->mcast.num_disabled); | 745 | atomic_dec(&bat_priv->mcast.num_disabled); |
743 | 746 | ||
744 | batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); | 747 | batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 8d04d174669e..fab47f1f3ef9 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -133,7 +133,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv) | |||
133 | if (!bat_priv->nc.decoding_hash) | 133 | if (!bat_priv->nc.decoding_hash) |
134 | goto err; | 134 | goto err; |
135 | 135 | ||
136 | batadv_hash_set_lock_class(bat_priv->nc.coding_hash, | 136 | batadv_hash_set_lock_class(bat_priv->nc.decoding_hash, |
137 | &batadv_nc_decoding_hash_lock_class_key); | 137 | &batadv_nc_decoding_hash_lock_class_key); |
138 | 138 | ||
139 | INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); | 139 | INIT_DELAYED_WORK(&bat_priv->nc.work, batadv_nc_worker); |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 6a484514cd3e..bea8198d0198 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -570,9 +570,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) | |||
570 | 570 | ||
571 | batadv_frag_purge_orig(orig_node, NULL); | 571 | batadv_frag_purge_orig(orig_node, NULL); |
572 | 572 | ||
573 | batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1, | ||
574 | "originator timed out"); | ||
575 | |||
576 | if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) | 573 | if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) |
577 | orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); | 574 | orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); |
578 | 575 | ||
@@ -678,6 +675,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, | |||
678 | atomic_set(&orig_node->last_ttvn, 0); | 675 | atomic_set(&orig_node->last_ttvn, 0); |
679 | orig_node->tt_buff = NULL; | 676 | orig_node->tt_buff = NULL; |
680 | orig_node->tt_buff_len = 0; | 677 | orig_node->tt_buff_len = 0; |
678 | orig_node->last_seen = jiffies; | ||
681 | reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); | 679 | reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); |
682 | orig_node->bcast_seqno_reset = reset_time; | 680 | orig_node->bcast_seqno_reset = reset_time; |
683 | #ifdef CONFIG_BATMAN_ADV_MCAST | 681 | #ifdef CONFIG_BATMAN_ADV_MCAST |
@@ -977,6 +975,9 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv) | |||
977 | if (batadv_purge_orig_node(bat_priv, orig_node)) { | 975 | if (batadv_purge_orig_node(bat_priv, orig_node)) { |
978 | batadv_gw_node_delete(bat_priv, orig_node); | 976 | batadv_gw_node_delete(bat_priv, orig_node); |
979 | hlist_del_rcu(&orig_node->hash_entry); | 977 | hlist_del_rcu(&orig_node->hash_entry); |
978 | batadv_tt_global_del_orig(orig_node->bat_priv, | ||
979 | orig_node, -1, | ||
980 | "originator timed out"); | ||
980 | batadv_orig_node_free_ref(orig_node); | 981 | batadv_orig_node_free_ref(orig_node); |
981 | continue; | 982 | continue; |
982 | } | 983 | } |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 35f76f2f7824..6648f321864d 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -443,11 +443,13 @@ batadv_find_router(struct batadv_priv *bat_priv, | |||
443 | 443 | ||
444 | router = batadv_orig_router_get(orig_node, recv_if); | 444 | router = batadv_orig_router_get(orig_node, recv_if); |
445 | 445 | ||
446 | if (!router) | ||
447 | return router; | ||
448 | |||
446 | /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop) | 449 | /* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop) |
447 | * and if activated. | 450 | * and if activated. |
448 | */ | 451 | */ |
449 | if (recv_if == BATADV_IF_DEFAULT || !atomic_read(&bat_priv->bonding) || | 452 | if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding))) |
450 | !router) | ||
451 | return router; | 453 | return router; |
452 | 454 | ||
453 | /* bonding: loop through the list of possible routers found | 455 | /* bonding: loop through the list of possible routers found |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 76617be1e797..c989253737f0 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -390,7 +390,6 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, | |||
390 | 390 | ||
391 | drop: | 391 | drop: |
392 | dev->stats.rx_dropped++; | 392 | dev->stats.rx_dropped++; |
393 | kfree_skb(skb); | ||
394 | return NET_RX_DROP; | 393 | return NET_RX_DROP; |
395 | } | 394 | } |
396 | 395 | ||
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 85bcc21e84d2..ce82722d049b 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -533,6 +533,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | |||
533 | 533 | ||
534 | BT_DBG(""); | 534 | BT_DBG(""); |
535 | 535 | ||
536 | if (!l2cap_is_socket(sock)) | ||
537 | return -EBADFD; | ||
538 | |||
536 | baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); | 539 | baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); |
537 | baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); | 540 | baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); |
538 | 541 | ||
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 67fe5e84e68f..278a194e6af4 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -334,6 +334,9 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
334 | 334 | ||
335 | BT_DBG(""); | 335 | BT_DBG(""); |
336 | 336 | ||
337 | if (!l2cap_is_socket(sock)) | ||
338 | return -EBADFD; | ||
339 | |||
337 | session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); | 340 | session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); |
338 | if (!session) | 341 | if (!session) |
339 | return -ENOMEM; | 342 | return -ENOMEM; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 39a5c8a01726..3f2e8b830cbd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -242,7 +242,8 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
242 | if (rp->status) | 242 | if (rp->status) |
243 | return; | 243 | return; |
244 | 244 | ||
245 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) | 245 | if (test_bit(HCI_SETUP, &hdev->dev_flags) || |
246 | test_bit(HCI_CONFIG, &hdev->dev_flags)) | ||
246 | memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); | 247 | memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); |
247 | } | 248 | } |
248 | 249 | ||
@@ -509,7 +510,8 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
509 | if (rp->status) | 510 | if (rp->status) |
510 | return; | 511 | return; |
511 | 512 | ||
512 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) { | 513 | if (test_bit(HCI_SETUP, &hdev->dev_flags) || |
514 | test_bit(HCI_CONFIG, &hdev->dev_flags)) { | ||
513 | hdev->hci_ver = rp->hci_ver; | 515 | hdev->hci_ver = rp->hci_ver; |
514 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); | 516 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); |
515 | hdev->lmp_ver = rp->lmp_ver; | 517 | hdev->lmp_ver = rp->lmp_ver; |
@@ -528,7 +530,8 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, | |||
528 | if (rp->status) | 530 | if (rp->status) |
529 | return; | 531 | return; |
530 | 532 | ||
531 | if (test_bit(HCI_SETUP, &hdev->dev_flags)) | 533 | if (test_bit(HCI_SETUP, &hdev->dev_flags) || |
534 | test_bit(HCI_CONFIG, &hdev->dev_flags)) | ||
532 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); | 535 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); |
533 | } | 536 | } |
534 | 537 | ||
@@ -2194,7 +2197,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2194 | return; | 2197 | return; |
2195 | } | 2198 | } |
2196 | 2199 | ||
2197 | if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && | 2200 | /* Require HCI_CONNECTABLE or a whitelist entry to accept the |
2201 | * connection. These features are only touched through mgmt so | ||
2202 | * only do the checks if HCI_MGMT is set. | ||
2203 | */ | ||
2204 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | ||
2205 | !test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && | ||
2198 | !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, | 2206 | !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, |
2199 | BDADDR_BREDR)) { | 2207 | BDADDR_BREDR)) { |
2200 | hci_reject_conn(hdev, &ev->bdaddr); | 2208 | hci_reject_conn(hdev, &ev->bdaddr); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index cc25d0b74b36..07348e142f16 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -1314,13 +1314,14 @@ int hidp_connection_add(struct hidp_connadd_req *req, | |||
1314 | { | 1314 | { |
1315 | struct hidp_session *session; | 1315 | struct hidp_session *session; |
1316 | struct l2cap_conn *conn; | 1316 | struct l2cap_conn *conn; |
1317 | struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan; | 1317 | struct l2cap_chan *chan; |
1318 | int ret; | 1318 | int ret; |
1319 | 1319 | ||
1320 | ret = hidp_verify_sockets(ctrl_sock, intr_sock); | 1320 | ret = hidp_verify_sockets(ctrl_sock, intr_sock); |
1321 | if (ret) | 1321 | if (ret) |
1322 | return ret; | 1322 | return ret; |
1323 | 1323 | ||
1324 | chan = l2cap_pi(ctrl_sock->sk)->chan; | ||
1324 | conn = NULL; | 1325 | conn = NULL; |
1325 | l2cap_chan_lock(chan); | 1326 | l2cap_chan_lock(chan); |
1326 | if (chan->conn) | 1327 | if (chan->conn) |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 1f1de715197c..e2aa7be3a847 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -154,7 +154,8 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
154 | dst = NULL; | 154 | dst = NULL; |
155 | 155 | ||
156 | if (is_broadcast_ether_addr(dest)) { | 156 | if (is_broadcast_ether_addr(dest)) { |
157 | if (p->flags & BR_PROXYARP && | 157 | if (IS_ENABLED(CONFIG_INET) && |
158 | p->flags & BR_PROXYARP && | ||
158 | skb->protocol == htons(ETH_P_ARP)) | 159 | skb->protocol == htons(ETH_P_ARP)) |
159 | br_do_proxy_arp(skb, br, vid); | 160 | br_do_proxy_arp(skb, br, vid); |
160 | 161 | ||
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 15845814a0f2..ba6eb17226da 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c | |||
@@ -676,7 +676,7 @@ static int calcu_signature(struct ceph_x_authorizer *au, | |||
676 | int ret; | 676 | int ret; |
677 | char tmp_enc[40]; | 677 | char tmp_enc[40]; |
678 | __le32 tmp[5] = { | 678 | __le32 tmp[5] = { |
679 | 16u, msg->hdr.crc, msg->footer.front_crc, | 679 | cpu_to_le32(16), msg->hdr.crc, msg->footer.front_crc, |
680 | msg->footer.middle_crc, msg->footer.data_crc, | 680 | msg->footer.middle_crc, msg->footer.data_crc, |
681 | }; | 681 | }; |
682 | ret = ceph_x_encrypt(&au->session_key, &tmp, sizeof(tmp), | 682 | ret = ceph_x_encrypt(&au->session_key, &tmp, sizeof(tmp), |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index a83062ceeec9..f2148e22b148 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
@@ -717,7 +717,7 @@ static int get_poolop_reply_buf(const char *src, size_t src_len, | |||
717 | if (src_len != sizeof(u32) + dst_len) | 717 | if (src_len != sizeof(u32) + dst_len) |
718 | return -EINVAL; | 718 | return -EINVAL; |
719 | 719 | ||
720 | buf_len = le32_to_cpu(*(u32 *)src); | 720 | buf_len = le32_to_cpu(*(__le32 *)src); |
721 | if (buf_len != dst_len) | 721 | if (buf_len != dst_len) |
722 | return -EINVAL; | 722 | return -EINVAL; |
723 | 723 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index f411c28d0a66..171420e75b03 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1694,6 +1694,7 @@ int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
1694 | 1694 | ||
1695 | skb_scrub_packet(skb, true); | 1695 | skb_scrub_packet(skb, true); |
1696 | skb->protocol = eth_type_trans(skb, dev); | 1696 | skb->protocol = eth_type_trans(skb, dev); |
1697 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | ||
1697 | 1698 | ||
1698 | return 0; | 1699 | return 0; |
1699 | } | 1700 | } |
@@ -2522,7 +2523,7 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) | |||
2522 | /* If MPLS offload request, verify we are testing hardware MPLS features | 2523 | /* If MPLS offload request, verify we are testing hardware MPLS features |
2523 | * instead of standard features for the netdev. | 2524 | * instead of standard features for the netdev. |
2524 | */ | 2525 | */ |
2525 | #ifdef CONFIG_NET_MPLS_GSO | 2526 | #if IS_ENABLED(CONFIG_NET_MPLS_GSO) |
2526 | static netdev_features_t net_mpls_features(struct sk_buff *skb, | 2527 | static netdev_features_t net_mpls_features(struct sk_buff *skb, |
2527 | netdev_features_t features, | 2528 | netdev_features_t features, |
2528 | __be16 type) | 2529 | __be16 type) |
@@ -2562,7 +2563,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, | |||
2562 | 2563 | ||
2563 | netdev_features_t netif_skb_features(struct sk_buff *skb) | 2564 | netdev_features_t netif_skb_features(struct sk_buff *skb) |
2564 | { | 2565 | { |
2565 | const struct net_device *dev = skb->dev; | 2566 | struct net_device *dev = skb->dev; |
2566 | netdev_features_t features = dev->features; | 2567 | netdev_features_t features = dev->features; |
2567 | u16 gso_segs = skb_shinfo(skb)->gso_segs; | 2568 | u16 gso_segs = skb_shinfo(skb)->gso_segs; |
2568 | __be16 protocol = skb->protocol; | 2569 | __be16 protocol = skb->protocol; |
@@ -2570,11 +2571,21 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2570 | if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs) | 2571 | if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs) |
2571 | features &= ~NETIF_F_GSO_MASK; | 2572 | features &= ~NETIF_F_GSO_MASK; |
2572 | 2573 | ||
2573 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { | 2574 | /* If encapsulation offload request, verify we are testing |
2574 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2575 | * hardware encapsulation features instead of standard |
2575 | protocol = veh->h_vlan_encapsulated_proto; | 2576 | * features for the netdev |
2576 | } else if (!vlan_tx_tag_present(skb)) { | 2577 | */ |
2577 | return harmonize_features(skb, features); | 2578 | if (skb->encapsulation) |
2579 | features &= dev->hw_enc_features; | ||
2580 | |||
2581 | if (!vlan_tx_tag_present(skb)) { | ||
2582 | if (unlikely(protocol == htons(ETH_P_8021Q) || | ||
2583 | protocol == htons(ETH_P_8021AD))) { | ||
2584 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
2585 | protocol = veh->h_vlan_encapsulated_proto; | ||
2586 | } else { | ||
2587 | goto finalize; | ||
2588 | } | ||
2578 | } | 2589 | } |
2579 | 2590 | ||
2580 | features = netdev_intersect_features(features, | 2591 | features = netdev_intersect_features(features, |
@@ -2591,6 +2602,11 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2591 | NETIF_F_HW_VLAN_CTAG_TX | | 2602 | NETIF_F_HW_VLAN_CTAG_TX | |
2592 | NETIF_F_HW_VLAN_STAG_TX); | 2603 | NETIF_F_HW_VLAN_STAG_TX); |
2593 | 2604 | ||
2605 | finalize: | ||
2606 | if (dev->netdev_ops->ndo_features_check) | ||
2607 | features &= dev->netdev_ops->ndo_features_check(skb, dev, | ||
2608 | features); | ||
2609 | |||
2594 | return harmonize_features(skb, features); | 2610 | return harmonize_features(skb, features); |
2595 | } | 2611 | } |
2596 | EXPORT_SYMBOL(netif_skb_features); | 2612 | EXPORT_SYMBOL(netif_skb_features); |
@@ -2661,19 +2677,12 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device | |||
2661 | if (unlikely(!skb)) | 2677 | if (unlikely(!skb)) |
2662 | goto out_null; | 2678 | goto out_null; |
2663 | 2679 | ||
2664 | /* If encapsulation offload request, verify we are testing | ||
2665 | * hardware encapsulation features instead of standard | ||
2666 | * features for the netdev | ||
2667 | */ | ||
2668 | if (skb->encapsulation) | ||
2669 | features &= dev->hw_enc_features; | ||
2670 | |||
2671 | if (netif_needs_gso(dev, skb, features)) { | 2680 | if (netif_needs_gso(dev, skb, features)) { |
2672 | struct sk_buff *segs; | 2681 | struct sk_buff *segs; |
2673 | 2682 | ||
2674 | segs = skb_gso_segment(skb, features); | 2683 | segs = skb_gso_segment(skb, features); |
2675 | if (IS_ERR(segs)) { | 2684 | if (IS_ERR(segs)) { |
2676 | segs = NULL; | 2685 | goto out_kfree_skb; |
2677 | } else if (segs) { | 2686 | } else if (segs) { |
2678 | consume_skb(skb); | 2687 | consume_skb(skb); |
2679 | skb = segs; | 2688 | skb = segs; |
@@ -4557,6 +4566,68 @@ void netif_napi_del(struct napi_struct *napi) | |||
4557 | } | 4566 | } |
4558 | EXPORT_SYMBOL(netif_napi_del); | 4567 | EXPORT_SYMBOL(netif_napi_del); |
4559 | 4568 | ||
4569 | static int napi_poll(struct napi_struct *n, struct list_head *repoll) | ||
4570 | { | ||
4571 | void *have; | ||
4572 | int work, weight; | ||
4573 | |||
4574 | list_del_init(&n->poll_list); | ||
4575 | |||
4576 | have = netpoll_poll_lock(n); | ||
4577 | |||
4578 | weight = n->weight; | ||
4579 | |||
4580 | /* This NAPI_STATE_SCHED test is for avoiding a race | ||
4581 | * with netpoll's poll_napi(). Only the entity which | ||
4582 | * obtains the lock and sees NAPI_STATE_SCHED set will | ||
4583 | * actually make the ->poll() call. Therefore we avoid | ||
4584 | * accidentally calling ->poll() when NAPI is not scheduled. | ||
4585 | */ | ||
4586 | work = 0; | ||
4587 | if (test_bit(NAPI_STATE_SCHED, &n->state)) { | ||
4588 | work = n->poll(n, weight); | ||
4589 | trace_napi_poll(n); | ||
4590 | } | ||
4591 | |||
4592 | WARN_ON_ONCE(work > weight); | ||
4593 | |||
4594 | if (likely(work < weight)) | ||
4595 | goto out_unlock; | ||
4596 | |||
4597 | /* Drivers must not modify the NAPI state if they | ||
4598 | * consume the entire weight. In such cases this code | ||
4599 | * still "owns" the NAPI instance and therefore can | ||
4600 | * move the instance around on the list at-will. | ||
4601 | */ | ||
4602 | if (unlikely(napi_disable_pending(n))) { | ||
4603 | napi_complete(n); | ||
4604 | goto out_unlock; | ||
4605 | } | ||
4606 | |||
4607 | if (n->gro_list) { | ||
4608 | /* flush too old packets | ||
4609 | * If HZ < 1000, flush all packets. | ||
4610 | */ | ||
4611 | napi_gro_flush(n, HZ >= 1000); | ||
4612 | } | ||
4613 | |||
4614 | /* Some drivers may have called napi_schedule | ||
4615 | * prior to exhausting their budget. | ||
4616 | */ | ||
4617 | if (unlikely(!list_empty(&n->poll_list))) { | ||
4618 | pr_warn_once("%s: Budget exhausted after napi rescheduled\n", | ||
4619 | n->dev ? n->dev->name : "backlog"); | ||
4620 | goto out_unlock; | ||
4621 | } | ||
4622 | |||
4623 | list_add_tail(&n->poll_list, repoll); | ||
4624 | |||
4625 | out_unlock: | ||
4626 | netpoll_poll_unlock(have); | ||
4627 | |||
4628 | return work; | ||
4629 | } | ||
4630 | |||
4560 | static void net_rx_action(struct softirq_action *h) | 4631 | static void net_rx_action(struct softirq_action *h) |
4561 | { | 4632 | { |
4562 | struct softnet_data *sd = this_cpu_ptr(&softnet_data); | 4633 | struct softnet_data *sd = this_cpu_ptr(&softnet_data); |
@@ -4564,74 +4635,34 @@ static void net_rx_action(struct softirq_action *h) | |||
4564 | int budget = netdev_budget; | 4635 | int budget = netdev_budget; |
4565 | LIST_HEAD(list); | 4636 | LIST_HEAD(list); |
4566 | LIST_HEAD(repoll); | 4637 | LIST_HEAD(repoll); |
4567 | void *have; | ||
4568 | 4638 | ||
4569 | local_irq_disable(); | 4639 | local_irq_disable(); |
4570 | list_splice_init(&sd->poll_list, &list); | 4640 | list_splice_init(&sd->poll_list, &list); |
4571 | local_irq_enable(); | 4641 | local_irq_enable(); |
4572 | 4642 | ||
4573 | while (!list_empty(&list)) { | 4643 | for (;;) { |
4574 | struct napi_struct *n; | 4644 | struct napi_struct *n; |
4575 | int work, weight; | ||
4576 | |||
4577 | /* If softirq window is exhausted then punt. | ||
4578 | * Allow this to run for 2 jiffies since which will allow | ||
4579 | * an average latency of 1.5/HZ. | ||
4580 | */ | ||
4581 | if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit))) | ||
4582 | goto softnet_break; | ||
4583 | |||
4584 | 4645 | ||
4585 | n = list_first_entry(&list, struct napi_struct, poll_list); | 4646 | if (list_empty(&list)) { |
4586 | list_del_init(&n->poll_list); | 4647 | if (!sd_has_rps_ipi_waiting(sd) && list_empty(&repoll)) |
4587 | 4648 | return; | |
4588 | have = netpoll_poll_lock(n); | 4649 | break; |
4589 | |||
4590 | weight = n->weight; | ||
4591 | |||
4592 | /* This NAPI_STATE_SCHED test is for avoiding a race | ||
4593 | * with netpoll's poll_napi(). Only the entity which | ||
4594 | * obtains the lock and sees NAPI_STATE_SCHED set will | ||
4595 | * actually make the ->poll() call. Therefore we avoid | ||
4596 | * accidentally calling ->poll() when NAPI is not scheduled. | ||
4597 | */ | ||
4598 | work = 0; | ||
4599 | if (test_bit(NAPI_STATE_SCHED, &n->state)) { | ||
4600 | work = n->poll(n, weight); | ||
4601 | trace_napi_poll(n); | ||
4602 | } | 4650 | } |
4603 | 4651 | ||
4604 | WARN_ON_ONCE(work > weight); | 4652 | n = list_first_entry(&list, struct napi_struct, poll_list); |
4605 | 4653 | budget -= napi_poll(n, &repoll); | |
4606 | budget -= work; | ||
4607 | 4654 | ||
4608 | /* Drivers must not modify the NAPI state if they | 4655 | /* If softirq window is exhausted then punt. |
4609 | * consume the entire weight. In such cases this code | 4656 | * Allow this to run for 2 jiffies since which will allow |
4610 | * still "owns" the NAPI instance and therefore can | 4657 | * an average latency of 1.5/HZ. |
4611 | * move the instance around on the list at-will. | ||
4612 | */ | 4658 | */ |
4613 | if (unlikely(work == weight)) { | 4659 | if (unlikely(budget <= 0 || |
4614 | if (unlikely(napi_disable_pending(n))) { | 4660 | time_after_eq(jiffies, time_limit))) { |
4615 | napi_complete(n); | 4661 | sd->time_squeeze++; |
4616 | } else { | 4662 | break; |
4617 | if (n->gro_list) { | ||
4618 | /* flush too old packets | ||
4619 | * If HZ < 1000, flush all packets. | ||
4620 | */ | ||
4621 | napi_gro_flush(n, HZ >= 1000); | ||
4622 | } | ||
4623 | list_add_tail(&n->poll_list, &repoll); | ||
4624 | } | ||
4625 | } | 4663 | } |
4626 | |||
4627 | netpoll_poll_unlock(have); | ||
4628 | } | 4664 | } |
4629 | 4665 | ||
4630 | if (!sd_has_rps_ipi_waiting(sd) && | ||
4631 | list_empty(&list) && | ||
4632 | list_empty(&repoll)) | ||
4633 | return; | ||
4634 | out: | ||
4635 | local_irq_disable(); | 4666 | local_irq_disable(); |
4636 | 4667 | ||
4637 | list_splice_tail_init(&sd->poll_list, &list); | 4668 | list_splice_tail_init(&sd->poll_list, &list); |
@@ -4641,12 +4672,6 @@ out: | |||
4641 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | 4672 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); |
4642 | 4673 | ||
4643 | net_rps_action_and_irq_enable(sd); | 4674 | net_rps_action_and_irq_enable(sd); |
4644 | |||
4645 | return; | ||
4646 | |||
4647 | softnet_break: | ||
4648 | sd->time_squeeze++; | ||
4649 | goto out; | ||
4650 | } | 4675 | } |
4651 | 4676 | ||
4652 | struct netdev_adjacent { | 4677 | struct netdev_adjacent { |
@@ -7047,10 +7072,20 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
7047 | oldsd->output_queue = NULL; | 7072 | oldsd->output_queue = NULL; |
7048 | oldsd->output_queue_tailp = &oldsd->output_queue; | 7073 | oldsd->output_queue_tailp = &oldsd->output_queue; |
7049 | } | 7074 | } |
7050 | /* Append NAPI poll list from offline CPU. */ | 7075 | /* Append NAPI poll list from offline CPU, with one exception : |
7051 | if (!list_empty(&oldsd->poll_list)) { | 7076 | * process_backlog() must be called by cpu owning percpu backlog. |
7052 | list_splice_init(&oldsd->poll_list, &sd->poll_list); | 7077 | * We properly handle process_queue & input_pkt_queue later. |
7053 | raise_softirq_irqoff(NET_RX_SOFTIRQ); | 7078 | */ |
7079 | while (!list_empty(&oldsd->poll_list)) { | ||
7080 | struct napi_struct *napi = list_first_entry(&oldsd->poll_list, | ||
7081 | struct napi_struct, | ||
7082 | poll_list); | ||
7083 | |||
7084 | list_del_init(&napi->poll_list); | ||
7085 | if (napi->poll == process_backlog) | ||
7086 | napi->state = 0; | ||
7087 | else | ||
7088 | ____napi_schedule(sd, napi); | ||
7054 | } | 7089 | } |
7055 | 7090 | ||
7056 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 7091 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
@@ -7061,7 +7096,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
7061 | netif_rx_internal(skb); | 7096 | netif_rx_internal(skb); |
7062 | input_queue_head_incr(oldsd); | 7097 | input_queue_head_incr(oldsd); |
7063 | } | 7098 | } |
7064 | while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { | 7099 | while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { |
7065 | netif_rx_internal(skb); | 7100 | netif_rx_internal(skb); |
7066 | input_queue_head_incr(oldsd); | 7101 | input_queue_head_incr(oldsd); |
7067 | } | 7102 | } |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8e38f17288d3..8d614c93f86a 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -2043,6 +2043,12 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2043 | case NDTPA_BASE_REACHABLE_TIME: | 2043 | case NDTPA_BASE_REACHABLE_TIME: |
2044 | NEIGH_VAR_SET(p, BASE_REACHABLE_TIME, | 2044 | NEIGH_VAR_SET(p, BASE_REACHABLE_TIME, |
2045 | nla_get_msecs(tbp[i])); | 2045 | nla_get_msecs(tbp[i])); |
2046 | /* update reachable_time as well, otherwise, the change will | ||
2047 | * only be effective after the next time neigh_periodic_work | ||
2048 | * decides to recompute it (can be multiple minutes) | ||
2049 | */ | ||
2050 | p->reachable_time = | ||
2051 | neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); | ||
2046 | break; | 2052 | break; |
2047 | case NDTPA_GC_STALETIME: | 2053 | case NDTPA_GC_STALETIME: |
2048 | NEIGH_VAR_SET(p, GC_STALETIME, | 2054 | NEIGH_VAR_SET(p, GC_STALETIME, |
@@ -2921,6 +2927,31 @@ static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write, | |||
2921 | return ret; | 2927 | return ret; |
2922 | } | 2928 | } |
2923 | 2929 | ||
2930 | static int neigh_proc_base_reachable_time(struct ctl_table *ctl, int write, | ||
2931 | void __user *buffer, | ||
2932 | size_t *lenp, loff_t *ppos) | ||
2933 | { | ||
2934 | struct neigh_parms *p = ctl->extra2; | ||
2935 | int ret; | ||
2936 | |||
2937 | if (strcmp(ctl->procname, "base_reachable_time") == 0) | ||
2938 | ret = neigh_proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); | ||
2939 | else if (strcmp(ctl->procname, "base_reachable_time_ms") == 0) | ||
2940 | ret = neigh_proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos); | ||
2941 | else | ||
2942 | ret = -1; | ||
2943 | |||
2944 | if (write && ret == 0) { | ||
2945 | /* update reachable_time as well, otherwise, the change will | ||
2946 | * only be effective after the next time neigh_periodic_work | ||
2947 | * decides to recompute it | ||
2948 | */ | ||
2949 | p->reachable_time = | ||
2950 | neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); | ||
2951 | } | ||
2952 | return ret; | ||
2953 | } | ||
2954 | |||
2924 | #define NEIGH_PARMS_DATA_OFFSET(index) \ | 2955 | #define NEIGH_PARMS_DATA_OFFSET(index) \ |
2925 | (&((struct neigh_parms *) 0)->data[index]) | 2956 | (&((struct neigh_parms *) 0)->data[index]) |
2926 | 2957 | ||
@@ -3047,6 +3078,19 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
3047 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler; | 3078 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler; |
3048 | /* ReachableTime (in milliseconds) */ | 3079 | /* ReachableTime (in milliseconds) */ |
3049 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler; | 3080 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler; |
3081 | } else { | ||
3082 | /* Those handlers will update p->reachable_time after | ||
3083 | * base_reachable_time(_ms) is set to ensure the new timer starts being | ||
3084 | * applied after the next neighbour update instead of waiting for | ||
3085 | * neigh_periodic_work to update its value (can be multiple minutes) | ||
3086 | * So any handler that replaces them should do this as well | ||
3087 | */ | ||
3088 | /* ReachableTime */ | ||
3089 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = | ||
3090 | neigh_proc_base_reachable_time; | ||
3091 | /* ReachableTime (in milliseconds) */ | ||
3092 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = | ||
3093 | neigh_proc_base_reachable_time; | ||
3050 | } | 3094 | } |
3051 | 3095 | ||
3052 | /* Don't export sysctls to unprivileged users */ | 3096 | /* Don't export sysctls to unprivileged users */ |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index ae13ef6b3ea7..395c15b82087 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -4148,6 +4148,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
4148 | skb->ignore_df = 0; | 4148 | skb->ignore_df = 0; |
4149 | skb_dst_drop(skb); | 4149 | skb_dst_drop(skb); |
4150 | skb->mark = 0; | 4150 | skb->mark = 0; |
4151 | skb_init_secmark(skb); | ||
4151 | secpath_reset(skb); | 4152 | secpath_reset(skb); |
4152 | nf_reset(skb); | 4153 | nf_reset(skb); |
4153 | nf_reset_trace(skb); | 4154 | nf_reset_trace(skb); |
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 95e47c97585e..394a200f93c1 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
@@ -122,14 +122,18 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
122 | int err; | 122 | int err; |
123 | 123 | ||
124 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); | 124 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); |
125 | if (IS_ERR(skb)) | ||
126 | return PTR_ERR(skb); | ||
125 | 127 | ||
126 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 128 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
127 | + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) | 129 | + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) |
128 | + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); | 130 | + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); |
129 | 131 | ||
130 | err = skb_cow_head(skb, min_headroom); | 132 | err = skb_cow_head(skb, min_headroom); |
131 | if (unlikely(err)) | 133 | if (unlikely(err)) { |
134 | kfree_skb(skb); | ||
132 | return err; | 135 | return err; |
136 | } | ||
133 | 137 | ||
134 | skb = vlan_hwaccel_push_inside(skb); | 138 | skb = vlan_hwaccel_push_inside(skb); |
135 | if (unlikely(!skb)) | 139 | if (unlikely(!skb)) |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 8a89c738b7a3..6b85adb05003 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -461,17 +461,13 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
461 | 461 | ||
462 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); | 462 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
463 | sin = &errhdr.offender; | 463 | sin = &errhdr.offender; |
464 | sin->sin_family = AF_UNSPEC; | 464 | memset(sin, 0, sizeof(*sin)); |
465 | 465 | ||
466 | if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || | 466 | if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || |
467 | ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin)) { | 467 | ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin)) { |
468 | struct inet_sock *inet = inet_sk(sk); | ||
469 | |||
470 | sin->sin_family = AF_INET; | 468 | sin->sin_family = AF_INET; |
471 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 469 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
472 | sin->sin_port = 0; | 470 | if (inet_sk(sk)->cmsg_flags) |
473 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); | ||
474 | if (inet->cmsg_flags) | ||
475 | ip_cmsg_recv(msg, skb); | 471 | ip_cmsg_recv(msg, skb); |
476 | } | 472 | } |
477 | 473 | ||
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c index ff2d23d8c87a..6ecfce63201a 100644 --- a/net/ipv4/netfilter/nft_redir_ipv4.c +++ b/net/ipv4/netfilter/nft_redir_ipv4.c | |||
@@ -27,10 +27,10 @@ static void nft_redir_ipv4_eval(const struct nft_expr *expr, | |||
27 | 27 | ||
28 | memset(&mr, 0, sizeof(mr)); | 28 | memset(&mr, 0, sizeof(mr)); |
29 | if (priv->sreg_proto_min) { | 29 | if (priv->sreg_proto_min) { |
30 | mr.range[0].min.all = (__force __be16) | 30 | mr.range[0].min.all = |
31 | data[priv->sreg_proto_min].data[0]; | 31 | *(__be16 *)&data[priv->sreg_proto_min].data[0]; |
32 | mr.range[0].max.all = (__force __be16) | 32 | mr.range[0].max.all = |
33 | data[priv->sreg_proto_max].data[0]; | 33 | *(__be16 *)&data[priv->sreg_proto_max].data[0]; |
34 | mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; | 34 | mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; |
35 | } | 35 | } |
36 | 36 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7f18262e2326..65caf8b95e17 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2019,7 +2019,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
2019 | if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) | 2019 | if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) |
2020 | break; | 2020 | break; |
2021 | 2021 | ||
2022 | if (tso_segs == 1) { | 2022 | if (tso_segs == 1 || !max_segs) { |
2023 | if (unlikely(!tcp_nagle_test(tp, skb, mss_now, | 2023 | if (unlikely(!tcp_nagle_test(tp, skb, mss_now, |
2024 | (tcp_skb_is_last(sk, skb) ? | 2024 | (tcp_skb_is_last(sk, skb) ? |
2025 | nonagle : TCP_NAGLE_PUSH)))) | 2025 | nonagle : TCP_NAGLE_PUSH)))) |
@@ -2032,7 +2032,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
2032 | } | 2032 | } |
2033 | 2033 | ||
2034 | limit = mss_now; | 2034 | limit = mss_now; |
2035 | if (tso_segs > 1 && !tcp_urg_mode(tp)) | 2035 | if (tso_segs > 1 && max_segs && !tcp_urg_mode(tp)) |
2036 | limit = tcp_mss_split_point(sk, skb, mss_now, | 2036 | limit = tcp_mss_split_point(sk, skb, mss_now, |
2037 | min_t(unsigned int, | 2037 | min_t(unsigned int, |
2038 | cwnd_quota, | 2038 | cwnd_quota, |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 100c589a2a6c..49f5e73db122 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -393,11 +393,10 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
393 | 393 | ||
394 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); | 394 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
395 | sin = &errhdr.offender; | 395 | sin = &errhdr.offender; |
396 | sin->sin6_family = AF_UNSPEC; | 396 | memset(sin, 0, sizeof(*sin)); |
397 | |||
397 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { | 398 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { |
398 | sin->sin6_family = AF_INET6; | 399 | sin->sin6_family = AF_INET6; |
399 | sin->sin6_flowinfo = 0; | ||
400 | sin->sin6_port = 0; | ||
401 | if (np->rxopt.all) { | 400 | if (np->rxopt.all) { |
402 | if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && | 401 | if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && |
403 | serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) | 402 | serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) |
@@ -412,12 +411,9 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
412 | ipv6_iface_scope_id(&sin->sin6_addr, | 411 | ipv6_iface_scope_id(&sin->sin6_addr, |
413 | IP6CB(skb)->iif); | 412 | IP6CB(skb)->iif); |
414 | } else { | 413 | } else { |
415 | struct inet_sock *inet = inet_sk(sk); | ||
416 | |||
417 | ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, | 414 | ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, |
418 | &sin->sin6_addr); | 415 | &sin->sin6_addr); |
419 | sin->sin6_scope_id = 0; | 416 | if (inet_sk(sk)->cmsg_flags) |
420 | if (inet->cmsg_flags) | ||
421 | ip_cmsg_recv(msg, skb); | 417 | ip_cmsg_recv(msg, skb); |
422 | } | 418 | } |
423 | } | 419 | } |
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c index 2433a6bfb191..11820b6b3613 100644 --- a/net/ipv6/netfilter/nft_redir_ipv6.c +++ b/net/ipv6/netfilter/nft_redir_ipv6.c | |||
@@ -27,10 +27,10 @@ static void nft_redir_ipv6_eval(const struct nft_expr *expr, | |||
27 | 27 | ||
28 | memset(&range, 0, sizeof(range)); | 28 | memset(&range, 0, sizeof(range)); |
29 | if (priv->sreg_proto_min) { | 29 | if (priv->sreg_proto_min) { |
30 | range.min_proto.all = (__force __be16) | 30 | range.min_proto.all = |
31 | data[priv->sreg_proto_min].data[0]; | 31 | *(__be16 *)&data[priv->sreg_proto_min].data[0]; |
32 | range.max_proto.all = (__force __be16) | 32 | range.max_proto.all = |
33 | data[priv->sreg_proto_max].data[0]; | 33 | *(__be16 *)&data[priv->sreg_proto_max].data[0]; |
34 | range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; | 34 | range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; |
35 | } | 35 | } |
36 | 36 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c91083156edb..166e33bed222 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1160,12 +1160,9 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | |||
1160 | struct net *net = dev_net(dst->dev); | 1160 | struct net *net = dev_net(dst->dev); |
1161 | 1161 | ||
1162 | rt6->rt6i_flags |= RTF_MODIFIED; | 1162 | rt6->rt6i_flags |= RTF_MODIFIED; |
1163 | if (mtu < IPV6_MIN_MTU) { | 1163 | if (mtu < IPV6_MIN_MTU) |
1164 | u32 features = dst_metric(dst, RTAX_FEATURES); | ||
1165 | mtu = IPV6_MIN_MTU; | 1164 | mtu = IPV6_MIN_MTU; |
1166 | features |= RTAX_FEATURE_ALLFRAG; | 1165 | |
1167 | dst_metric_set(dst, RTAX_FEATURES, features); | ||
1168 | } | ||
1169 | dst_metric_set(dst, RTAX_MTU, mtu); | 1166 | dst_metric_set(dst, RTAX_MTU, mtu); |
1170 | rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); | 1167 | rt6_update_expires(rt6, net->ipv6.sysctl.ip6_rt_mtu_expires); |
1171 | } | 1168 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5ff87805258e..9c0b54e87b47 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1387,6 +1387,28 @@ ipv6_pktoptions: | |||
1387 | return 0; | 1387 | return 0; |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, | ||
1391 | const struct tcphdr *th) | ||
1392 | { | ||
1393 | /* This is tricky: we move IP6CB at its correct location into | ||
1394 | * TCP_SKB_CB(). It must be done after xfrm6_policy_check(), because | ||
1395 | * _decode_session6() uses IP6CB(). | ||
1396 | * barrier() makes sure compiler won't play aliasing games. | ||
1397 | */ | ||
1398 | memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb), | ||
1399 | sizeof(struct inet6_skb_parm)); | ||
1400 | barrier(); | ||
1401 | |||
1402 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
1403 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
1404 | skb->len - th->doff*4); | ||
1405 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
1406 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
1407 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
1408 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); | ||
1409 | TCP_SKB_CB(skb)->sacked = 0; | ||
1410 | } | ||
1411 | |||
1390 | static int tcp_v6_rcv(struct sk_buff *skb) | 1412 | static int tcp_v6_rcv(struct sk_buff *skb) |
1391 | { | 1413 | { |
1392 | const struct tcphdr *th; | 1414 | const struct tcphdr *th; |
@@ -1418,24 +1440,9 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
1418 | 1440 | ||
1419 | th = tcp_hdr(skb); | 1441 | th = tcp_hdr(skb); |
1420 | hdr = ipv6_hdr(skb); | 1442 | hdr = ipv6_hdr(skb); |
1421 | /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB() | ||
1422 | * barrier() makes sure compiler wont play fool^Waliasing games. | ||
1423 | */ | ||
1424 | memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb), | ||
1425 | sizeof(struct inet6_skb_parm)); | ||
1426 | barrier(); | ||
1427 | |||
1428 | TCP_SKB_CB(skb)->seq = ntohl(th->seq); | ||
1429 | TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + | ||
1430 | skb->len - th->doff*4); | ||
1431 | TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); | ||
1432 | TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); | ||
1433 | TCP_SKB_CB(skb)->tcp_tw_isn = 0; | ||
1434 | TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); | ||
1435 | TCP_SKB_CB(skb)->sacked = 0; | ||
1436 | 1443 | ||
1437 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, | 1444 | sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest, |
1438 | tcp_v6_iif(skb)); | 1445 | inet6_iif(skb)); |
1439 | if (!sk) | 1446 | if (!sk) |
1440 | goto no_tcp_socket; | 1447 | goto no_tcp_socket; |
1441 | 1448 | ||
@@ -1451,6 +1458,8 @@ process: | |||
1451 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1458 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
1452 | goto discard_and_relse; | 1459 | goto discard_and_relse; |
1453 | 1460 | ||
1461 | tcp_v6_fill_cb(skb, hdr, th); | ||
1462 | |||
1454 | #ifdef CONFIG_TCP_MD5SIG | 1463 | #ifdef CONFIG_TCP_MD5SIG |
1455 | if (tcp_v6_inbound_md5_hash(sk, skb)) | 1464 | if (tcp_v6_inbound_md5_hash(sk, skb)) |
1456 | goto discard_and_relse; | 1465 | goto discard_and_relse; |
@@ -1482,6 +1491,8 @@ no_tcp_socket: | |||
1482 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | 1491 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
1483 | goto discard_it; | 1492 | goto discard_it; |
1484 | 1493 | ||
1494 | tcp_v6_fill_cb(skb, hdr, th); | ||
1495 | |||
1485 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1496 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
1486 | csum_error: | 1497 | csum_error: |
1487 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); | 1498 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); |
@@ -1505,6 +1516,8 @@ do_time_wait: | |||
1505 | goto discard_it; | 1516 | goto discard_it; |
1506 | } | 1517 | } |
1507 | 1518 | ||
1519 | tcp_v6_fill_cb(skb, hdr, th); | ||
1520 | |||
1508 | if (skb->len < (th->doff<<2)) { | 1521 | if (skb->len < (th->doff<<2)) { |
1509 | inet_twsk_put(inet_twsk(sk)); | 1522 | inet_twsk_put(inet_twsk(sk)); |
1510 | goto bad_packet; | 1523 | goto bad_packet; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 0bb7038121ac..bd4e46ec32bd 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -140,7 +140,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
140 | if (!ret) { | 140 | if (!ret) { |
141 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 141 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
142 | 142 | ||
143 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | 143 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
144 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
145 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
144 | sdata->crypto_tx_tailroom_needed_cnt--; | 146 | sdata->crypto_tx_tailroom_needed_cnt--; |
145 | 147 | ||
146 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && | 148 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && |
@@ -188,7 +190,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
188 | sta = key->sta; | 190 | sta = key->sta; |
189 | sdata = key->sdata; | 191 | sdata = key->sdata; |
190 | 192 | ||
191 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | 193 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
194 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
195 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
192 | increment_tailroom_need_count(sdata); | 196 | increment_tailroom_need_count(sdata); |
193 | 197 | ||
194 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, | 198 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, |
@@ -884,7 +888,9 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) | |||
884 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 888 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
885 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 889 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
886 | 890 | ||
887 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) | 891 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
892 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
893 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
888 | increment_tailroom_need_count(key->sdata); | 894 | increment_tailroom_need_count(key->sdata); |
889 | } | 895 | } |
890 | 896 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2c36c4765f47..837a406a9dd6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1643,7 +1643,7 @@ __ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) | |||
1643 | { | 1643 | { |
1644 | struct ieee80211_local *local = sdata->local; | 1644 | struct ieee80211_local *local = sdata->local; |
1645 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1645 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1646 | bool ret; | 1646 | bool ret = false; |
1647 | int ac; | 1647 | int ac; |
1648 | 1648 | ||
1649 | if (local->hw.queues < IEEE80211_NUM_ACS) | 1649 | if (local->hw.queues < IEEE80211_NUM_ACS) |
diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c index ca27837974fe..349295d21946 100644 --- a/net/mpls/mpls_gso.c +++ b/net/mpls/mpls_gso.c | |||
@@ -31,10 +31,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, | |||
31 | SKB_GSO_TCPV6 | | 31 | SKB_GSO_TCPV6 | |
32 | SKB_GSO_UDP | | 32 | SKB_GSO_UDP | |
33 | SKB_GSO_DODGY | | 33 | SKB_GSO_DODGY | |
34 | SKB_GSO_TCP_ECN | | 34 | SKB_GSO_TCP_ECN))) |
35 | SKB_GSO_GRE | | ||
36 | SKB_GSO_GRE_CSUM | | ||
37 | SKB_GSO_IPIP))) | ||
38 | goto out; | 35 | goto out; |
39 | 36 | ||
40 | /* Setup inner SKB. */ | 37 | /* Setup inner SKB. */ |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 1d5341f3761d..5d3daae98bf0 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -183,6 +183,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
183 | struct nf_conn *ct; | 183 | struct nf_conn *ct; |
184 | struct net *net; | 184 | struct net *net; |
185 | 185 | ||
186 | *diff = 0; | ||
187 | |||
186 | #ifdef CONFIG_IP_VS_IPV6 | 188 | #ifdef CONFIG_IP_VS_IPV6 |
187 | /* This application helper doesn't work with IPv6 yet, | 189 | /* This application helper doesn't work with IPv6 yet, |
188 | * so turn this into a no-op for IPv6 packets | 190 | * so turn this into a no-op for IPv6 packets |
@@ -191,8 +193,6 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
191 | return 1; | 193 | return 1; |
192 | #endif | 194 | #endif |
193 | 195 | ||
194 | *diff = 0; | ||
195 | |||
196 | /* Only useful for established sessions */ | 196 | /* Only useful for established sessions */ |
197 | if (cp->state != IP_VS_TCP_S_ESTABLISHED) | 197 | if (cp->state != IP_VS_TCP_S_ESTABLISHED) |
198 | return 1; | 198 | return 1; |
@@ -322,6 +322,9 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
322 | struct ip_vs_conn *n_cp; | 322 | struct ip_vs_conn *n_cp; |
323 | struct net *net; | 323 | struct net *net; |
324 | 324 | ||
325 | /* no diff required for incoming packets */ | ||
326 | *diff = 0; | ||
327 | |||
325 | #ifdef CONFIG_IP_VS_IPV6 | 328 | #ifdef CONFIG_IP_VS_IPV6 |
326 | /* This application helper doesn't work with IPv6 yet, | 329 | /* This application helper doesn't work with IPv6 yet, |
327 | * so turn this into a no-op for IPv6 packets | 330 | * so turn this into a no-op for IPv6 packets |
@@ -330,9 +333,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
330 | return 1; | 333 | return 1; |
331 | #endif | 334 | #endif |
332 | 335 | ||
333 | /* no diff required for incoming packets */ | ||
334 | *diff = 0; | ||
335 | |||
336 | /* Only useful for established sessions */ | 336 | /* Only useful for established sessions */ |
337 | if (cp->state != IP_VS_TCP_S_ESTABLISHED) | 337 | if (cp->state != IP_VS_TCP_S_ESTABLISHED) |
338 | return 1; | 338 | return 1; |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index a11674806707..46d1b26a468e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -611,16 +611,15 @@ __nf_conntrack_confirm(struct sk_buff *skb) | |||
611 | */ | 611 | */ |
612 | NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); | 612 | NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); |
613 | pr_debug("Confirming conntrack %p\n", ct); | 613 | pr_debug("Confirming conntrack %p\n", ct); |
614 | /* We have to check the DYING flag inside the lock to prevent | 614 | /* We have to check the DYING flag after unlink to prevent |
615 | a race against nf_ct_get_next_corpse() possibly called from | 615 | * a race against nf_ct_get_next_corpse() possibly called from |
616 | user context, else we insert an already 'dead' hash, blocking | 616 | * user context, else we insert an already 'dead' hash, blocking |
617 | further use of that particular connection -JM */ | 617 | * further use of that particular connection -JM. |
618 | */ | ||
619 | nf_ct_del_from_dying_or_unconfirmed_list(ct); | ||
618 | 620 | ||
619 | if (unlikely(nf_ct_is_dying(ct))) { | 621 | if (unlikely(nf_ct_is_dying(ct))) |
620 | nf_conntrack_double_unlock(hash, reply_hash); | 622 | goto out; |
621 | local_bh_enable(); | ||
622 | return NF_ACCEPT; | ||
623 | } | ||
624 | 623 | ||
625 | /* See if there's one in the list already, including reverse: | 624 | /* See if there's one in the list already, including reverse: |
626 | NAT could have grabbed it without realizing, since we're | 625 | NAT could have grabbed it without realizing, since we're |
@@ -636,8 +635,6 @@ __nf_conntrack_confirm(struct sk_buff *skb) | |||
636 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) | 635 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) |
637 | goto out; | 636 | goto out; |
638 | 637 | ||
639 | nf_ct_del_from_dying_or_unconfirmed_list(ct); | ||
640 | |||
641 | /* Timer relative to confirmation time, not original | 638 | /* Timer relative to confirmation time, not original |
642 | setting time, otherwise we'd get timer wrap in | 639 | setting time, otherwise we'd get timer wrap in |
643 | weird delay cases. */ | 640 | weird delay cases. */ |
@@ -673,6 +670,7 @@ __nf_conntrack_confirm(struct sk_buff *skb) | |||
673 | return NF_ACCEPT; | 670 | return NF_ACCEPT; |
674 | 671 | ||
675 | out: | 672 | out: |
673 | nf_ct_add_to_dying_list(ct); | ||
676 | nf_conntrack_double_unlock(hash, reply_hash); | 674 | nf_conntrack_double_unlock(hash, reply_hash); |
677 | NF_CT_STAT_INC(net, insert_failed); | 675 | NF_CT_STAT_INC(net, insert_failed); |
678 | local_bh_enable(); | 676 | local_bh_enable(); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 129a8daa4abf..3b3ddb4fb9ee 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -713,16 +713,12 @@ static int nft_flush_table(struct nft_ctx *ctx) | |||
713 | struct nft_chain *chain, *nc; | 713 | struct nft_chain *chain, *nc; |
714 | struct nft_set *set, *ns; | 714 | struct nft_set *set, *ns; |
715 | 715 | ||
716 | list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) { | 716 | list_for_each_entry(chain, &ctx->table->chains, list) { |
717 | ctx->chain = chain; | 717 | ctx->chain = chain; |
718 | 718 | ||
719 | err = nft_delrule_by_chain(ctx); | 719 | err = nft_delrule_by_chain(ctx); |
720 | if (err < 0) | 720 | if (err < 0) |
721 | goto out; | 721 | goto out; |
722 | |||
723 | err = nft_delchain(ctx); | ||
724 | if (err < 0) | ||
725 | goto out; | ||
726 | } | 722 | } |
727 | 723 | ||
728 | list_for_each_entry_safe(set, ns, &ctx->table->sets, list) { | 724 | list_for_each_entry_safe(set, ns, &ctx->table->sets, list) { |
@@ -735,6 +731,14 @@ static int nft_flush_table(struct nft_ctx *ctx) | |||
735 | goto out; | 731 | goto out; |
736 | } | 732 | } |
737 | 733 | ||
734 | list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) { | ||
735 | ctx->chain = chain; | ||
736 | |||
737 | err = nft_delchain(ctx); | ||
738 | if (err < 0) | ||
739 | goto out; | ||
740 | } | ||
741 | |||
738 | err = nft_deltable(ctx); | 742 | err = nft_deltable(ctx); |
739 | out: | 743 | out: |
740 | return err; | 744 | return err; |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 13c2e17bbe27..c421d94c4652 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -321,7 +321,8 @@ replay: | |||
321 | nlh = nlmsg_hdr(skb); | 321 | nlh = nlmsg_hdr(skb); |
322 | err = 0; | 322 | err = 0; |
323 | 323 | ||
324 | if (nlh->nlmsg_len < NLMSG_HDRLEN) { | 324 | if (nlmsg_len(nlh) < sizeof(struct nfgenmsg) || |
325 | skb->len < nlh->nlmsg_len) { | ||
325 | err = -EINVAL; | 326 | err = -EINVAL; |
326 | goto ack; | 327 | goto ack; |
327 | } | 328 | } |
@@ -463,13 +464,13 @@ static void nfnetlink_rcv(struct sk_buff *skb) | |||
463 | } | 464 | } |
464 | 465 | ||
465 | #ifdef CONFIG_MODULES | 466 | #ifdef CONFIG_MODULES |
466 | static int nfnetlink_bind(int group) | 467 | static int nfnetlink_bind(struct net *net, int group) |
467 | { | 468 | { |
468 | const struct nfnetlink_subsystem *ss; | 469 | const struct nfnetlink_subsystem *ss; |
469 | int type; | 470 | int type; |
470 | 471 | ||
471 | if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX) | 472 | if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX) |
472 | return -EINVAL; | 473 | return 0; |
473 | 474 | ||
474 | type = nfnl_group2type[group]; | 475 | type = nfnl_group2type[group]; |
475 | 476 | ||
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index afe2b0b45ec4..aff54fb1c8a0 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c | |||
@@ -65,10 +65,10 @@ static void nft_nat_eval(const struct nft_expr *expr, | |||
65 | } | 65 | } |
66 | 66 | ||
67 | if (priv->sreg_proto_min) { | 67 | if (priv->sreg_proto_min) { |
68 | range.min_proto.all = (__force __be16) | 68 | range.min_proto.all = |
69 | data[priv->sreg_proto_min].data[0]; | 69 | *(__be16 *)&data[priv->sreg_proto_min].data[0]; |
70 | range.max_proto.all = (__force __be16) | 70 | range.max_proto.all = |
71 | data[priv->sreg_proto_max].data[0]; | 71 | *(__be16 *)&data[priv->sreg_proto_max].data[0]; |
72 | range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; | 72 | range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 074cf3e91c6f..02fdde28dada 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <linux/rhashtable.h> | 61 | #include <linux/rhashtable.h> |
62 | #include <asm/cacheflush.h> | 62 | #include <asm/cacheflush.h> |
63 | #include <linux/hash.h> | 63 | #include <linux/hash.h> |
64 | #include <linux/genetlink.h> | ||
64 | 65 | ||
65 | #include <net/net_namespace.h> | 66 | #include <net/net_namespace.h> |
66 | #include <net/sock.h> | 67 | #include <net/sock.h> |
@@ -1091,8 +1092,12 @@ static void netlink_remove(struct sock *sk) | |||
1091 | mutex_unlock(&nl_sk_hash_lock); | 1092 | mutex_unlock(&nl_sk_hash_lock); |
1092 | 1093 | ||
1093 | netlink_table_grab(); | 1094 | netlink_table_grab(); |
1094 | if (nlk_sk(sk)->subscriptions) | 1095 | if (nlk_sk(sk)->subscriptions) { |
1095 | __sk_del_bind_node(sk); | 1096 | __sk_del_bind_node(sk); |
1097 | netlink_update_listeners(sk); | ||
1098 | } | ||
1099 | if (sk->sk_protocol == NETLINK_GENERIC) | ||
1100 | atomic_inc(&genl_sk_destructing_cnt); | ||
1096 | netlink_table_ungrab(); | 1101 | netlink_table_ungrab(); |
1097 | } | 1102 | } |
1098 | 1103 | ||
@@ -1139,8 +1144,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, | |||
1139 | struct module *module = NULL; | 1144 | struct module *module = NULL; |
1140 | struct mutex *cb_mutex; | 1145 | struct mutex *cb_mutex; |
1141 | struct netlink_sock *nlk; | 1146 | struct netlink_sock *nlk; |
1142 | int (*bind)(int group); | 1147 | int (*bind)(struct net *net, int group); |
1143 | void (*unbind)(int group); | 1148 | void (*unbind)(struct net *net, int group); |
1144 | int err = 0; | 1149 | int err = 0; |
1145 | 1150 | ||
1146 | sock->state = SS_UNCONNECTED; | 1151 | sock->state = SS_UNCONNECTED; |
@@ -1209,6 +1214,20 @@ static int netlink_release(struct socket *sock) | |||
1209 | * will be purged. | 1214 | * will be purged. |
1210 | */ | 1215 | */ |
1211 | 1216 | ||
1217 | /* must not acquire netlink_table_lock in any way again before unbind | ||
1218 | * and notifying genetlink is done as otherwise it might deadlock | ||
1219 | */ | ||
1220 | if (nlk->netlink_unbind) { | ||
1221 | int i; | ||
1222 | |||
1223 | for (i = 0; i < nlk->ngroups; i++) | ||
1224 | if (test_bit(i, nlk->groups)) | ||
1225 | nlk->netlink_unbind(sock_net(sk), i + 1); | ||
1226 | } | ||
1227 | if (sk->sk_protocol == NETLINK_GENERIC && | ||
1228 | atomic_dec_return(&genl_sk_destructing_cnt) == 0) | ||
1229 | wake_up(&genl_sk_destructing_waitq); | ||
1230 | |||
1212 | sock->sk = NULL; | 1231 | sock->sk = NULL; |
1213 | wake_up_interruptible_all(&nlk->wait); | 1232 | wake_up_interruptible_all(&nlk->wait); |
1214 | 1233 | ||
@@ -1226,8 +1245,8 @@ static int netlink_release(struct socket *sock) | |||
1226 | 1245 | ||
1227 | module_put(nlk->module); | 1246 | module_put(nlk->module); |
1228 | 1247 | ||
1229 | netlink_table_grab(); | ||
1230 | if (netlink_is_kernel(sk)) { | 1248 | if (netlink_is_kernel(sk)) { |
1249 | netlink_table_grab(); | ||
1231 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); | 1250 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); |
1232 | if (--nl_table[sk->sk_protocol].registered == 0) { | 1251 | if (--nl_table[sk->sk_protocol].registered == 0) { |
1233 | struct listeners *old; | 1252 | struct listeners *old; |
@@ -1241,10 +1260,8 @@ static int netlink_release(struct socket *sock) | |||
1241 | nl_table[sk->sk_protocol].flags = 0; | 1260 | nl_table[sk->sk_protocol].flags = 0; |
1242 | nl_table[sk->sk_protocol].registered = 0; | 1261 | nl_table[sk->sk_protocol].registered = 0; |
1243 | } | 1262 | } |
1244 | } else if (nlk->subscriptions) { | 1263 | netlink_table_ungrab(); |
1245 | netlink_update_listeners(sk); | ||
1246 | } | 1264 | } |
1247 | netlink_table_ungrab(); | ||
1248 | 1265 | ||
1249 | kfree(nlk->groups); | 1266 | kfree(nlk->groups); |
1250 | nlk->groups = NULL; | 1267 | nlk->groups = NULL; |
@@ -1410,9 +1427,10 @@ static int netlink_realloc_groups(struct sock *sk) | |||
1410 | return err; | 1427 | return err; |
1411 | } | 1428 | } |
1412 | 1429 | ||
1413 | static void netlink_unbind(int group, long unsigned int groups, | 1430 | static void netlink_undo_bind(int group, long unsigned int groups, |
1414 | struct netlink_sock *nlk) | 1431 | struct sock *sk) |
1415 | { | 1432 | { |
1433 | struct netlink_sock *nlk = nlk_sk(sk); | ||
1416 | int undo; | 1434 | int undo; |
1417 | 1435 | ||
1418 | if (!nlk->netlink_unbind) | 1436 | if (!nlk->netlink_unbind) |
@@ -1420,7 +1438,7 @@ static void netlink_unbind(int group, long unsigned int groups, | |||
1420 | 1438 | ||
1421 | for (undo = 0; undo < group; undo++) | 1439 | for (undo = 0; undo < group; undo++) |
1422 | if (test_bit(undo, &groups)) | 1440 | if (test_bit(undo, &groups)) |
1423 | nlk->netlink_unbind(undo); | 1441 | nlk->netlink_unbind(sock_net(sk), undo); |
1424 | } | 1442 | } |
1425 | 1443 | ||
1426 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, | 1444 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, |
@@ -1458,10 +1476,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
1458 | for (group = 0; group < nlk->ngroups; group++) { | 1476 | for (group = 0; group < nlk->ngroups; group++) { |
1459 | if (!test_bit(group, &groups)) | 1477 | if (!test_bit(group, &groups)) |
1460 | continue; | 1478 | continue; |
1461 | err = nlk->netlink_bind(group); | 1479 | err = nlk->netlink_bind(net, group); |
1462 | if (!err) | 1480 | if (!err) |
1463 | continue; | 1481 | continue; |
1464 | netlink_unbind(group, groups, nlk); | 1482 | netlink_undo_bind(group, groups, sk); |
1465 | return err; | 1483 | return err; |
1466 | } | 1484 | } |
1467 | } | 1485 | } |
@@ -1471,7 +1489,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
1471 | netlink_insert(sk, net, nladdr->nl_pid) : | 1489 | netlink_insert(sk, net, nladdr->nl_pid) : |
1472 | netlink_autobind(sock); | 1490 | netlink_autobind(sock); |
1473 | if (err) { | 1491 | if (err) { |
1474 | netlink_unbind(nlk->ngroups, groups, nlk); | 1492 | netlink_undo_bind(nlk->ngroups, groups, sk); |
1475 | return err; | 1493 | return err; |
1476 | } | 1494 | } |
1477 | } | 1495 | } |
@@ -2122,7 +2140,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
2122 | if (!val || val - 1 >= nlk->ngroups) | 2140 | if (!val || val - 1 >= nlk->ngroups) |
2123 | return -EINVAL; | 2141 | return -EINVAL; |
2124 | if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) { | 2142 | if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) { |
2125 | err = nlk->netlink_bind(val); | 2143 | err = nlk->netlink_bind(sock_net(sk), val); |
2126 | if (err) | 2144 | if (err) |
2127 | return err; | 2145 | return err; |
2128 | } | 2146 | } |
@@ -2131,7 +2149,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
2131 | optname == NETLINK_ADD_MEMBERSHIP); | 2149 | optname == NETLINK_ADD_MEMBERSHIP); |
2132 | netlink_table_ungrab(); | 2150 | netlink_table_ungrab(); |
2133 | if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) | 2151 | if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) |
2134 | nlk->netlink_unbind(val); | 2152 | nlk->netlink_unbind(sock_net(sk), val); |
2135 | 2153 | ||
2136 | err = 0; | 2154 | err = 0; |
2137 | break; | 2155 | break; |
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h index b20a1731759b..f1c31b39aa3e 100644 --- a/net/netlink/af_netlink.h +++ b/net/netlink/af_netlink.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _AF_NETLINK_H | 2 | #define _AF_NETLINK_H |
3 | 3 | ||
4 | #include <linux/rhashtable.h> | 4 | #include <linux/rhashtable.h> |
5 | #include <linux/atomic.h> | ||
5 | #include <net/sock.h> | 6 | #include <net/sock.h> |
6 | 7 | ||
7 | #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) | 8 | #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) |
@@ -39,8 +40,8 @@ struct netlink_sock { | |||
39 | struct mutex *cb_mutex; | 40 | struct mutex *cb_mutex; |
40 | struct mutex cb_def_mutex; | 41 | struct mutex cb_def_mutex; |
41 | void (*netlink_rcv)(struct sk_buff *skb); | 42 | void (*netlink_rcv)(struct sk_buff *skb); |
42 | int (*netlink_bind)(int group); | 43 | int (*netlink_bind)(struct net *net, int group); |
43 | void (*netlink_unbind)(int group); | 44 | void (*netlink_unbind)(struct net *net, int group); |
44 | struct module *module; | 45 | struct module *module; |
45 | #ifdef CONFIG_NETLINK_MMAP | 46 | #ifdef CONFIG_NETLINK_MMAP |
46 | struct mutex pg_vec_lock; | 47 | struct mutex pg_vec_lock; |
@@ -65,8 +66,8 @@ struct netlink_table { | |||
65 | unsigned int groups; | 66 | unsigned int groups; |
66 | struct mutex *cb_mutex; | 67 | struct mutex *cb_mutex; |
67 | struct module *module; | 68 | struct module *module; |
68 | int (*bind)(int group); | 69 | int (*bind)(struct net *net, int group); |
69 | void (*unbind)(int group); | 70 | void (*unbind)(struct net *net, int group); |
70 | bool (*compare)(struct net *net, struct sock *sock); | 71 | bool (*compare)(struct net *net, struct sock *sock); |
71 | int registered; | 72 | int registered; |
72 | }; | 73 | }; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 76393f2f4b22..ee57459fc258 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -23,6 +23,9 @@ | |||
23 | static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ | 23 | static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ |
24 | static DECLARE_RWSEM(cb_lock); | 24 | static DECLARE_RWSEM(cb_lock); |
25 | 25 | ||
26 | atomic_t genl_sk_destructing_cnt = ATOMIC_INIT(0); | ||
27 | DECLARE_WAIT_QUEUE_HEAD(genl_sk_destructing_waitq); | ||
28 | |||
26 | void genl_lock(void) | 29 | void genl_lock(void) |
27 | { | 30 | { |
28 | mutex_lock(&genl_mutex); | 31 | mutex_lock(&genl_mutex); |
@@ -435,15 +438,18 @@ int genl_unregister_family(struct genl_family *family) | |||
435 | 438 | ||
436 | genl_lock_all(); | 439 | genl_lock_all(); |
437 | 440 | ||
438 | genl_unregister_mc_groups(family); | ||
439 | |||
440 | list_for_each_entry(rc, genl_family_chain(family->id), family_list) { | 441 | list_for_each_entry(rc, genl_family_chain(family->id), family_list) { |
441 | if (family->id != rc->id || strcmp(rc->name, family->name)) | 442 | if (family->id != rc->id || strcmp(rc->name, family->name)) |
442 | continue; | 443 | continue; |
443 | 444 | ||
445 | genl_unregister_mc_groups(family); | ||
446 | |||
444 | list_del(&rc->family_list); | 447 | list_del(&rc->family_list); |
445 | family->n_ops = 0; | 448 | family->n_ops = 0; |
446 | genl_unlock_all(); | 449 | up_write(&cb_lock); |
450 | wait_event(genl_sk_destructing_waitq, | ||
451 | atomic_read(&genl_sk_destructing_cnt) == 0); | ||
452 | genl_unlock(); | ||
447 | 453 | ||
448 | kfree(family->attrbuf); | 454 | kfree(family->attrbuf); |
449 | genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0); | 455 | genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0); |
@@ -983,11 +989,63 @@ static struct genl_multicast_group genl_ctrl_groups[] = { | |||
983 | { .name = "notify", }, | 989 | { .name = "notify", }, |
984 | }; | 990 | }; |
985 | 991 | ||
992 | static int genl_bind(struct net *net, int group) | ||
993 | { | ||
994 | int i, err = -ENOENT; | ||
995 | |||
996 | down_read(&cb_lock); | ||
997 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { | ||
998 | struct genl_family *f; | ||
999 | |||
1000 | list_for_each_entry(f, genl_family_chain(i), family_list) { | ||
1001 | if (group >= f->mcgrp_offset && | ||
1002 | group < f->mcgrp_offset + f->n_mcgrps) { | ||
1003 | int fam_grp = group - f->mcgrp_offset; | ||
1004 | |||
1005 | if (!f->netnsok && net != &init_net) | ||
1006 | err = -ENOENT; | ||
1007 | else if (f->mcast_bind) | ||
1008 | err = f->mcast_bind(net, fam_grp); | ||
1009 | else | ||
1010 | err = 0; | ||
1011 | break; | ||
1012 | } | ||
1013 | } | ||
1014 | } | ||
1015 | up_read(&cb_lock); | ||
1016 | |||
1017 | return err; | ||
1018 | } | ||
1019 | |||
1020 | static void genl_unbind(struct net *net, int group) | ||
1021 | { | ||
1022 | int i; | ||
1023 | |||
1024 | down_read(&cb_lock); | ||
1025 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { | ||
1026 | struct genl_family *f; | ||
1027 | |||
1028 | list_for_each_entry(f, genl_family_chain(i), family_list) { | ||
1029 | if (group >= f->mcgrp_offset && | ||
1030 | group < f->mcgrp_offset + f->n_mcgrps) { | ||
1031 | int fam_grp = group - f->mcgrp_offset; | ||
1032 | |||
1033 | if (f->mcast_unbind) | ||
1034 | f->mcast_unbind(net, fam_grp); | ||
1035 | break; | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | up_read(&cb_lock); | ||
1040 | } | ||
1041 | |||
986 | static int __net_init genl_pernet_init(struct net *net) | 1042 | static int __net_init genl_pernet_init(struct net *net) |
987 | { | 1043 | { |
988 | struct netlink_kernel_cfg cfg = { | 1044 | struct netlink_kernel_cfg cfg = { |
989 | .input = genl_rcv, | 1045 | .input = genl_rcv, |
990 | .flags = NL_CFG_F_NONROOT_RECV, | 1046 | .flags = NL_CFG_F_NONROOT_RECV, |
1047 | .bind = genl_bind, | ||
1048 | .unbind = genl_unbind, | ||
991 | }; | 1049 | }; |
992 | 1050 | ||
993 | /* we'll bump the group number right afterwards */ | 1051 | /* we'll bump the group number right afterwards */ |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 764fdc39c63b..770064c83711 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -147,7 +147,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, | |||
147 | hdr = eth_hdr(skb); | 147 | hdr = eth_hdr(skb); |
148 | hdr->h_proto = mpls->mpls_ethertype; | 148 | hdr->h_proto = mpls->mpls_ethertype; |
149 | 149 | ||
150 | skb_set_inner_protocol(skb, skb->protocol); | 150 | if (!skb->inner_protocol) |
151 | skb_set_inner_protocol(skb, skb->protocol); | ||
151 | skb->protocol = mpls->mpls_ethertype; | 152 | skb->protocol = mpls->mpls_ethertype; |
152 | 153 | ||
153 | invalidate_flow_key(key); | 154 | invalidate_flow_key(key); |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 332b5a031739..b07349e82d78 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -83,8 +83,7 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info, | |||
83 | unsigned int group) | 83 | unsigned int group) |
84 | { | 84 | { |
85 | return info->nlhdr->nlmsg_flags & NLM_F_ECHO || | 85 | return info->nlhdr->nlmsg_flags & NLM_F_ECHO || |
86 | genl_has_listeners(family, genl_info_net(info)->genl_sock, | 86 | genl_has_listeners(family, genl_info_net(info), group); |
87 | group); | ||
88 | } | 87 | } |
89 | 88 | ||
90 | static void ovs_notify(struct genl_family *family, | 89 | static void ovs_notify(struct genl_family *family, |
@@ -525,7 +524,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) | |||
525 | struct vport *input_vport; | 524 | struct vport *input_vport; |
526 | int len; | 525 | int len; |
527 | int err; | 526 | int err; |
528 | bool log = !a[OVS_FLOW_ATTR_PROBE]; | 527 | bool log = !a[OVS_PACKET_ATTR_PROBE]; |
529 | 528 | ||
530 | err = -EINVAL; | 529 | err = -EINVAL; |
531 | if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] || | 530 | if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] || |
@@ -611,6 +610,7 @@ static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = { | |||
611 | [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN }, | 610 | [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN }, |
612 | [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED }, | 611 | [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED }, |
613 | [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED }, | 612 | [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED }, |
613 | [OVS_PACKET_ATTR_PROBE] = { .type = NLA_FLAG }, | ||
614 | }; | 614 | }; |
615 | 615 | ||
616 | static const struct genl_ops dp_packet_genl_ops[] = { | 616 | static const struct genl_ops dp_packet_genl_ops[] = { |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 70bef2ab7f2b..da2fae0873a5 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -70,6 +70,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, | |||
70 | { | 70 | { |
71 | struct flow_stats *stats; | 71 | struct flow_stats *stats; |
72 | int node = numa_node_id(); | 72 | int node = numa_node_id(); |
73 | int len = skb->len + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); | ||
73 | 74 | ||
74 | stats = rcu_dereference(flow->stats[node]); | 75 | stats = rcu_dereference(flow->stats[node]); |
75 | 76 | ||
@@ -105,7 +106,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, | |||
105 | if (likely(new_stats)) { | 106 | if (likely(new_stats)) { |
106 | new_stats->used = jiffies; | 107 | new_stats->used = jiffies; |
107 | new_stats->packet_count = 1; | 108 | new_stats->packet_count = 1; |
108 | new_stats->byte_count = skb->len; | 109 | new_stats->byte_count = len; |
109 | new_stats->tcp_flags = tcp_flags; | 110 | new_stats->tcp_flags = tcp_flags; |
110 | spin_lock_init(&new_stats->lock); | 111 | spin_lock_init(&new_stats->lock); |
111 | 112 | ||
@@ -120,7 +121,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags, | |||
120 | 121 | ||
121 | stats->used = jiffies; | 122 | stats->used = jiffies; |
122 | stats->packet_count++; | 123 | stats->packet_count++; |
123 | stats->byte_count += skb->len; | 124 | stats->byte_count += len; |
124 | stats->tcp_flags |= tcp_flags; | 125 | stats->tcp_flags |= tcp_flags; |
125 | unlock: | 126 | unlock: |
126 | spin_unlock(&stats->lock); | 127 | spin_unlock(&stats->lock); |
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 9645a21d9eaa..d1eecf707613 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -1753,7 +1753,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1753 | __be16 eth_type, __be16 vlan_tci, bool log) | 1753 | __be16 eth_type, __be16 vlan_tci, bool log) |
1754 | { | 1754 | { |
1755 | const struct nlattr *a; | 1755 | const struct nlattr *a; |
1756 | bool out_tnl_port = false; | ||
1757 | int rem, err; | 1756 | int rem, err; |
1758 | 1757 | ||
1759 | if (depth >= SAMPLE_ACTION_DEPTH) | 1758 | if (depth >= SAMPLE_ACTION_DEPTH) |
@@ -1796,8 +1795,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1796 | case OVS_ACTION_ATTR_OUTPUT: | 1795 | case OVS_ACTION_ATTR_OUTPUT: |
1797 | if (nla_get_u32(a) >= DP_MAX_PORTS) | 1796 | if (nla_get_u32(a) >= DP_MAX_PORTS) |
1798 | return -EINVAL; | 1797 | return -EINVAL; |
1799 | out_tnl_port = false; | ||
1800 | |||
1801 | break; | 1798 | break; |
1802 | 1799 | ||
1803 | case OVS_ACTION_ATTR_HASH: { | 1800 | case OVS_ACTION_ATTR_HASH: { |
@@ -1832,12 +1829,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1832 | case OVS_ACTION_ATTR_PUSH_MPLS: { | 1829 | case OVS_ACTION_ATTR_PUSH_MPLS: { |
1833 | const struct ovs_action_push_mpls *mpls = nla_data(a); | 1830 | const struct ovs_action_push_mpls *mpls = nla_data(a); |
1834 | 1831 | ||
1835 | /* Networking stack do not allow simultaneous Tunnel | ||
1836 | * and MPLS GSO. | ||
1837 | */ | ||
1838 | if (out_tnl_port) | ||
1839 | return -EINVAL; | ||
1840 | |||
1841 | if (!eth_p_mpls(mpls->mpls_ethertype)) | 1832 | if (!eth_p_mpls(mpls->mpls_ethertype)) |
1842 | return -EINVAL; | 1833 | return -EINVAL; |
1843 | /* Prohibit push MPLS other than to a white list | 1834 | /* Prohibit push MPLS other than to a white list |
@@ -1873,11 +1864,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1873 | 1864 | ||
1874 | case OVS_ACTION_ATTR_SET: | 1865 | case OVS_ACTION_ATTR_SET: |
1875 | err = validate_set(a, key, sfa, | 1866 | err = validate_set(a, key, sfa, |
1876 | &out_tnl_port, eth_type, log); | 1867 | &skip_copy, eth_type, log); |
1877 | if (err) | 1868 | if (err) |
1878 | return err; | 1869 | return err; |
1879 | |||
1880 | skip_copy = out_tnl_port; | ||
1881 | break; | 1870 | break; |
1882 | 1871 | ||
1883 | case OVS_ACTION_ATTR_SAMPLE: | 1872 | case OVS_ACTION_ATTR_SAMPLE: |
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 347fa2325b22..484864dd0e68 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c | |||
@@ -219,7 +219,10 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
219 | false); | 219 | false); |
220 | if (err < 0) | 220 | if (err < 0) |
221 | ip_rt_put(rt); | 221 | ip_rt_put(rt); |
222 | return err; | ||
223 | |||
222 | error: | 224 | error: |
225 | kfree_skb(skb); | ||
223 | return err; | 226 | return err; |
224 | } | 227 | } |
225 | 228 | ||
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 6b69df545b1d..d4168c442db5 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
@@ -73,7 +73,7 @@ static struct sk_buff *__build_header(struct sk_buff *skb, | |||
73 | 73 | ||
74 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); | 74 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); |
75 | if (IS_ERR(skb)) | 75 | if (IS_ERR(skb)) |
76 | return NULL; | 76 | return skb; |
77 | 77 | ||
78 | tpi.flags = filter_tnl_flags(tun_key->tun_flags); | 78 | tpi.flags = filter_tnl_flags(tun_key->tun_flags); |
79 | tpi.proto = htons(ETH_P_TEB); | 79 | tpi.proto = htons(ETH_P_TEB); |
@@ -144,7 +144,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
144 | 144 | ||
145 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { | 145 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { |
146 | err = -EINVAL; | 146 | err = -EINVAL; |
147 | goto error; | 147 | goto err_free_skb; |
148 | } | 148 | } |
149 | 149 | ||
150 | tun_key = &OVS_CB(skb)->egress_tun_info->tunnel; | 150 | tun_key = &OVS_CB(skb)->egress_tun_info->tunnel; |
@@ -157,8 +157,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
157 | fl.flowi4_proto = IPPROTO_GRE; | 157 | fl.flowi4_proto = IPPROTO_GRE; |
158 | 158 | ||
159 | rt = ip_route_output_key(net, &fl); | 159 | rt = ip_route_output_key(net, &fl); |
160 | if (IS_ERR(rt)) | 160 | if (IS_ERR(rt)) { |
161 | return PTR_ERR(rt); | 161 | err = PTR_ERR(rt); |
162 | goto err_free_skb; | ||
163 | } | ||
162 | 164 | ||
163 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); | 165 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); |
164 | 166 | ||
@@ -183,8 +185,9 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
183 | 185 | ||
184 | /* Push Tunnel header. */ | 186 | /* Push Tunnel header. */ |
185 | skb = __build_header(skb, tunnel_hlen); | 187 | skb = __build_header(skb, tunnel_hlen); |
186 | if (unlikely(!skb)) { | 188 | if (IS_ERR(skb)) { |
187 | err = 0; | 189 | err = PTR_ERR(skb); |
190 | skb = NULL; | ||
188 | goto err_free_rt; | 191 | goto err_free_rt; |
189 | } | 192 | } |
190 | 193 | ||
@@ -198,7 +201,8 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
198 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); | 201 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); |
199 | err_free_rt: | 202 | err_free_rt: |
200 | ip_rt_put(rt); | 203 | ip_rt_put(rt); |
201 | error: | 204 | err_free_skb: |
205 | kfree_skb(skb); | ||
202 | return err; | 206 | return err; |
203 | } | 207 | } |
204 | 208 | ||
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 38f95a52241b..d7c46b301024 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c | |||
@@ -187,7 +187,9 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
187 | false); | 187 | false); |
188 | if (err < 0) | 188 | if (err < 0) |
189 | ip_rt_put(rt); | 189 | ip_rt_put(rt); |
190 | return err; | ||
190 | error: | 191 | error: |
192 | kfree_skb(skb); | ||
191 | return err; | 193 | return err; |
192 | } | 194 | } |
193 | 195 | ||
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 9584526c0778..2034c6d9cb5a 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -480,7 +480,7 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, | |||
480 | stats = this_cpu_ptr(vport->percpu_stats); | 480 | stats = this_cpu_ptr(vport->percpu_stats); |
481 | u64_stats_update_begin(&stats->syncp); | 481 | u64_stats_update_begin(&stats->syncp); |
482 | stats->rx_packets++; | 482 | stats->rx_packets++; |
483 | stats->rx_bytes += skb->len; | 483 | stats->rx_bytes += skb->len + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); |
484 | u64_stats_update_end(&stats->syncp); | 484 | u64_stats_update_end(&stats->syncp); |
485 | 485 | ||
486 | OVS_CB(skb)->input_vport = vport; | 486 | OVS_CB(skb)->input_vport = vport; |
@@ -519,10 +519,9 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb) | |||
519 | u64_stats_update_end(&stats->syncp); | 519 | u64_stats_update_end(&stats->syncp); |
520 | } else if (sent < 0) { | 520 | } else if (sent < 0) { |
521 | ovs_vport_record_error(vport, VPORT_E_TX_ERROR); | 521 | ovs_vport_record_error(vport, VPORT_E_TX_ERROR); |
522 | kfree_skb(skb); | 522 | } else { |
523 | } else | ||
524 | ovs_vport_record_error(vport, VPORT_E_TX_DROPPED); | 523 | ovs_vport_record_error(vport, VPORT_E_TX_DROPPED); |
525 | 524 | } | |
526 | return sent; | 525 | return sent; |
527 | } | 526 | } |
528 | 527 | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e52a44785681..9cfe2e1dd8b5 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -785,6 +785,7 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1, | |||
785 | 785 | ||
786 | struct tpacket3_hdr *last_pkt; | 786 | struct tpacket3_hdr *last_pkt; |
787 | struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1; | 787 | struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1; |
788 | struct sock *sk = &po->sk; | ||
788 | 789 | ||
789 | if (po->stats.stats3.tp_drops) | 790 | if (po->stats.stats3.tp_drops) |
790 | status |= TP_STATUS_LOSING; | 791 | status |= TP_STATUS_LOSING; |
@@ -809,6 +810,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1, | |||
809 | /* Flush the block */ | 810 | /* Flush the block */ |
810 | prb_flush_block(pkc1, pbd1, status); | 811 | prb_flush_block(pkc1, pbd1, status); |
811 | 812 | ||
813 | sk->sk_data_ready(sk); | ||
814 | |||
812 | pkc1->kactive_blk_num = GET_NEXT_PRB_BLK_NUM(pkc1); | 815 | pkc1->kactive_blk_num = GET_NEXT_PRB_BLK_NUM(pkc1); |
813 | } | 816 | } |
814 | 817 | ||
@@ -2052,12 +2055,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
2052 | smp_wmb(); | 2055 | smp_wmb(); |
2053 | #endif | 2056 | #endif |
2054 | 2057 | ||
2055 | if (po->tp_version <= TPACKET_V2) | 2058 | if (po->tp_version <= TPACKET_V2) { |
2056 | __packet_set_status(po, h.raw, status); | 2059 | __packet_set_status(po, h.raw, status); |
2057 | else | 2060 | sk->sk_data_ready(sk); |
2061 | } else { | ||
2058 | prb_clear_blk_fill_status(&po->rx_ring); | 2062 | prb_clear_blk_fill_status(&po->rx_ring); |
2059 | 2063 | } | |
2060 | sk->sk_data_ready(sk); | ||
2061 | 2064 | ||
2062 | drop_n_restore: | 2065 | drop_n_restore: |
2063 | if (skb_head != skb->data && skb_shared(skb)) { | 2066 | if (skb_head != skb->data && skb_shared(skb)) { |
@@ -2514,7 +2517,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2514 | err = -EINVAL; | 2517 | err = -EINVAL; |
2515 | if (sock->type == SOCK_DGRAM) { | 2518 | if (sock->type == SOCK_DGRAM) { |
2516 | offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len); | 2519 | offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len); |
2517 | if (unlikely(offset) < 0) | 2520 | if (unlikely(offset < 0)) |
2518 | goto out_free; | 2521 | goto out_free; |
2519 | } else { | 2522 | } else { |
2520 | if (ll_header_truncated(dev, len)) | 2523 | if (ll_header_truncated(dev, len)) |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2625eccb77d5..aafe94bf292e 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1603,7 +1603,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1603 | sctp_assoc_t associd = 0; | 1603 | sctp_assoc_t associd = 0; |
1604 | sctp_cmsgs_t cmsgs = { NULL }; | 1604 | sctp_cmsgs_t cmsgs = { NULL }; |
1605 | sctp_scope_t scope; | 1605 | sctp_scope_t scope; |
1606 | bool fill_sinfo_ttl = false; | 1606 | bool fill_sinfo_ttl = false, wait_connect = false; |
1607 | struct sctp_datamsg *datamsg; | 1607 | struct sctp_datamsg *datamsg; |
1608 | int msg_flags = msg->msg_flags; | 1608 | int msg_flags = msg->msg_flags; |
1609 | __u16 sinfo_flags = 0; | 1609 | __u16 sinfo_flags = 0; |
@@ -1943,6 +1943,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1943 | if (err < 0) | 1943 | if (err < 0) |
1944 | goto out_free; | 1944 | goto out_free; |
1945 | 1945 | ||
1946 | wait_connect = true; | ||
1946 | pr_debug("%s: we associated primitively\n", __func__); | 1947 | pr_debug("%s: we associated primitively\n", __func__); |
1947 | } | 1948 | } |
1948 | 1949 | ||
@@ -1980,6 +1981,11 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1980 | sctp_datamsg_put(datamsg); | 1981 | sctp_datamsg_put(datamsg); |
1981 | err = msg_len; | 1982 | err = msg_len; |
1982 | 1983 | ||
1984 | if (unlikely(wait_connect)) { | ||
1985 | timeo = sock_sndtimeo(sk, msg_flags & MSG_DONTWAIT); | ||
1986 | sctp_wait_for_connect(asoc, &timeo); | ||
1987 | } | ||
1988 | |||
1983 | /* If we are already past ASSOCIATE, the lower | 1989 | /* If we are already past ASSOCIATE, the lower |
1984 | * layers are responsible for association cleanup. | 1990 | * layers are responsible for association cleanup. |
1985 | */ | 1991 | */ |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 1cb61242e55e..4439ac4c1b53 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -606,7 +606,7 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) | |||
606 | struct kvec *head = buf->head; | 606 | struct kvec *head = buf->head; |
607 | struct kvec *tail = buf->tail; | 607 | struct kvec *tail = buf->tail; |
608 | int fraglen; | 608 | int fraglen; |
609 | int new, old; | 609 | int new; |
610 | 610 | ||
611 | if (len > buf->len) { | 611 | if (len > buf->len) { |
612 | WARN_ON_ONCE(1); | 612 | WARN_ON_ONCE(1); |
@@ -629,8 +629,8 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len) | |||
629 | buf->len -= fraglen; | 629 | buf->len -= fraglen; |
630 | 630 | ||
631 | new = buf->page_base + buf->page_len; | 631 | new = buf->page_base + buf->page_len; |
632 | old = new + fraglen; | 632 | |
633 | xdr->page_ptr -= (old >> PAGE_SHIFT) - (new >> PAGE_SHIFT); | 633 | xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT); |
634 | 634 | ||
635 | if (buf->page_len) { | 635 | if (buf->page_len) { |
636 | xdr->p = page_address(*xdr->page_ptr); | 636 | xdr->p = page_address(*xdr->page_ptr); |
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 96ceefeb9daf..a9e174fc0f91 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -220,10 +220,11 @@ static void bclink_retransmit_pkt(u32 after, u32 to) | |||
220 | struct sk_buff *skb; | 220 | struct sk_buff *skb; |
221 | 221 | ||
222 | skb_queue_walk(&bcl->outqueue, skb) { | 222 | skb_queue_walk(&bcl->outqueue, skb) { |
223 | if (more(buf_seqno(skb), after)) | 223 | if (more(buf_seqno(skb), after)) { |
224 | tipc_link_retransmit(bcl, skb, mod(to - after)); | ||
224 | break; | 225 | break; |
226 | } | ||
225 | } | 227 | } |
226 | tipc_link_retransmit(bcl, skb, mod(to - after)); | ||
227 | } | 228 | } |
228 | 229 | ||
229 | /** | 230 | /** |
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 22ba971741e5..29c8675f9a11 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -175,7 +175,7 @@ config CFG80211_INTERNAL_REGDB | |||
175 | Most distributions have a CRDA package. So if unsure, say N. | 175 | Most distributions have a CRDA package. So if unsure, say N. |
176 | 176 | ||
177 | config CFG80211_WEXT | 177 | config CFG80211_WEXT |
178 | bool | 178 | bool "cfg80211 wireless extensions compatibility" |
179 | depends on CFG80211 | 179 | depends on CFG80211 |
180 | select WEXT_CORE | 180 | select WEXT_CORE |
181 | help | 181 | help |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7b8309840d4e..d39d1cbc86b1 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1530,45 +1530,40 @@ static void reg_call_notifier(struct wiphy *wiphy, | |||
1530 | 1530 | ||
1531 | static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) | 1531 | static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) |
1532 | { | 1532 | { |
1533 | struct ieee80211_channel *ch; | ||
1534 | struct cfg80211_chan_def chandef; | 1533 | struct cfg80211_chan_def chandef; |
1535 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | 1534 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
1536 | bool ret = true; | 1535 | enum nl80211_iftype iftype; |
1537 | 1536 | ||
1538 | wdev_lock(wdev); | 1537 | wdev_lock(wdev); |
1538 | iftype = wdev->iftype; | ||
1539 | 1539 | ||
1540 | /* make sure the interface is active */ | ||
1540 | if (!wdev->netdev || !netif_running(wdev->netdev)) | 1541 | if (!wdev->netdev || !netif_running(wdev->netdev)) |
1541 | goto out; | 1542 | goto wdev_inactive_unlock; |
1542 | 1543 | ||
1543 | switch (wdev->iftype) { | 1544 | switch (iftype) { |
1544 | case NL80211_IFTYPE_AP: | 1545 | case NL80211_IFTYPE_AP: |
1545 | case NL80211_IFTYPE_P2P_GO: | 1546 | case NL80211_IFTYPE_P2P_GO: |
1546 | if (!wdev->beacon_interval) | 1547 | if (!wdev->beacon_interval) |
1547 | goto out; | 1548 | goto wdev_inactive_unlock; |
1548 | 1549 | chandef = wdev->chandef; | |
1549 | ret = cfg80211_reg_can_beacon(wiphy, | ||
1550 | &wdev->chandef, wdev->iftype); | ||
1551 | break; | 1550 | break; |
1552 | case NL80211_IFTYPE_ADHOC: | 1551 | case NL80211_IFTYPE_ADHOC: |
1553 | if (!wdev->ssid_len) | 1552 | if (!wdev->ssid_len) |
1554 | goto out; | 1553 | goto wdev_inactive_unlock; |
1555 | 1554 | chandef = wdev->chandef; | |
1556 | ret = cfg80211_reg_can_beacon(wiphy, | ||
1557 | &wdev->chandef, wdev->iftype); | ||
1558 | break; | 1555 | break; |
1559 | case NL80211_IFTYPE_STATION: | 1556 | case NL80211_IFTYPE_STATION: |
1560 | case NL80211_IFTYPE_P2P_CLIENT: | 1557 | case NL80211_IFTYPE_P2P_CLIENT: |
1561 | if (!wdev->current_bss || | 1558 | if (!wdev->current_bss || |
1562 | !wdev->current_bss->pub.channel) | 1559 | !wdev->current_bss->pub.channel) |
1563 | goto out; | 1560 | goto wdev_inactive_unlock; |
1564 | 1561 | ||
1565 | ch = wdev->current_bss->pub.channel; | 1562 | if (!rdev->ops->get_channel || |
1566 | if (rdev->ops->get_channel && | 1563 | rdev_get_channel(rdev, wdev, &chandef)) |
1567 | !rdev_get_channel(rdev, wdev, &chandef)) | 1564 | cfg80211_chandef_create(&chandef, |
1568 | ret = cfg80211_chandef_usable(wiphy, &chandef, | 1565 | wdev->current_bss->pub.channel, |
1569 | IEEE80211_CHAN_DISABLED); | 1566 | NL80211_CHAN_NO_HT); |
1570 | else | ||
1571 | ret = !(ch->flags & IEEE80211_CHAN_DISABLED); | ||
1572 | break; | 1567 | break; |
1573 | case NL80211_IFTYPE_MONITOR: | 1568 | case NL80211_IFTYPE_MONITOR: |
1574 | case NL80211_IFTYPE_AP_VLAN: | 1569 | case NL80211_IFTYPE_AP_VLAN: |
@@ -1581,9 +1576,26 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) | |||
1581 | break; | 1576 | break; |
1582 | } | 1577 | } |
1583 | 1578 | ||
1584 | out: | ||
1585 | wdev_unlock(wdev); | 1579 | wdev_unlock(wdev); |
1586 | return ret; | 1580 | |
1581 | switch (iftype) { | ||
1582 | case NL80211_IFTYPE_AP: | ||
1583 | case NL80211_IFTYPE_P2P_GO: | ||
1584 | case NL80211_IFTYPE_ADHOC: | ||
1585 | return cfg80211_reg_can_beacon(wiphy, &chandef, iftype); | ||
1586 | case NL80211_IFTYPE_STATION: | ||
1587 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1588 | return cfg80211_chandef_usable(wiphy, &chandef, | ||
1589 | IEEE80211_CHAN_DISABLED); | ||
1590 | default: | ||
1591 | break; | ||
1592 | } | ||
1593 | |||
1594 | return true; | ||
1595 | |||
1596 | wdev_inactive_unlock: | ||
1597 | wdev_unlock(wdev); | ||
1598 | return true; | ||
1587 | } | 1599 | } |
1588 | 1600 | ||
1589 | static void reg_leave_invalid_chans(struct wiphy *wiphy) | 1601 | static void reg_leave_invalid_chans(struct wiphy *wiphy) |