Pull networking fixes from Jakub Kicinski: "Including fixes from netfilter, wireless and bluetooth. Kalle Valo steps down after serving as the WiFi driver maintainer for over a decade. Current release - fix to a fix: - vsock: orphan socket after transport release, avoid null-deref - Bluetooth: L2CAP: fix corrupted list in hci_chan_del Current release - regressions: - eth: - stmmac: correct Rx buffer layout when SPH is enabled - iavf: fix a locking bug in an error path - rxrpc: fix alteration of headers whilst zerocopy pending - s390/qeth: move netif_napi_add_tx() and napi_enable() from under BH - Revert "netfilter: flowtable: teardown flow if cached mtu is stale" Current release - new code bugs: - rxrpc: fix ipv6 path MTU discovery, only ipv4 worked - pse-pd: fix deadlock in current limit functions Previous releases - regressions: - rtnetlink: fix netns refleak with rtnl_setlink() - wifi: brcmfmac: use random seed flag for BCM4355 and BCM4364 firmware Previous releases - always broken: - add missing RCU protection of struct net throughout the stack - can: rockchip: bail out if skb cannot be allocated - eth: ti: am65-cpsw: base XDP support fixes Misc: - ethtool: tsconfig: update the format of hwtstamp flags, changes the uAPI but this uAPI was not in any release yet" * tag 'net-6.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (72 commits) net: pse-pd: Fix deadlock in current limit functions rxrpc: Fix ipv6 path MTU discovery Reapply "net: skb: introduce and use a single page frag cache" s390/qeth: move netif_napi_add_tx() and napi_enable() from under BH mlxsw: Add return value check for mlxsw_sp_port_get_stats_raw() ipv6: mcast: add RCU protection to mld_newpack() team: better TEAM_OPTION_TYPE_STRING validation Bluetooth: L2CAP: Fix corrupted list in hci_chan_del Bluetooth: btintel_pcie: Fix a potential race condition Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd net: ethernet: ti: am65_cpsw: fix tx_cleanup for XDP case net: ethernet: ti: am65-cpsw: fix RX & TX statistics for XDP_TX case net: ethernet: ti: am65-cpsw: fix memleak in certain XDP cases vsock/test: Add test for SO_LINGER null ptr deref vsock: Orphan socket after transport release MAINTAINERS: Add sctp headers to the general netdev entry Revert "netfilter: flowtable: teardown flow if cached mtu is stale" iavf: Fix a locking bug in an error path rxrpc: Fix alteration of headers whilst zerocopy pending net: phylink: make configuring clock-stop dependent on MAC support ...
Unified · Split
| @@ -376,6 +376,7 @@ Juha Yrjola <juha.yrjola@solidboot.com> · 375 unmodified lines | |||
| 376 | Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com> | 376 | Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com> |
| 377 | Iskren Chernev <me@iskren.info> <iskren.chernev@gmail.com> | 377 | Iskren Chernev <me@iskren.info> <iskren.chernev@gmail.com> |
| 378 | Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org> | 378 | Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org> |
| 379 | Kalle Valo <kvalo@kernel.org> <quic_kvalo@quicinc.com> | ||
| 379 | Kalyan Thota <quic_kalyant@quicinc.com> <kalyan_t@codeaurora.org> | 380 | Kalyan Thota <quic_kalyant@quicinc.com> <kalyan_t@codeaurora.org> |
| 380 | Karthikeyan Periyasamy <quic_periyasa@quicinc.com> <periyasa@codeaurora.org> | 381 | Karthikeyan Periyasamy <quic_periyasa@quicinc.com> <periyasa@codeaurora.org> |
| 381 | Kathiravan T <quic_kathirav@quicinc.com> <kathirav@codeaurora.org> | 382 | Kathiravan T <quic_kathirav@quicinc.com> <kathirav@codeaurora.org> |
| @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Qualcomm Technologies ath10k wireless devices | 7 | title: Qualcomm Technologies ath10k wireless devices |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Kalle Valo <kvalo@kernel.org> | ||
| 11 | - Jeff Johnson <jjohnson@kernel.org> | 10 | - Jeff Johnson <jjohnson@kernel.org> |
| 12 | 11 | ||
| 13 | description: | 12 | description: |
| @@ -8,7 +8,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 7 unmodified lines | |||
| 8 | title: Qualcomm Technologies ath11k wireless devices (PCIe) | 8 | title: Qualcomm Technologies ath11k wireless devices (PCIe) |
| 9 | 9 | ||
| 10 | maintainers: | 10 | maintainers: |
| 11 | - Kalle Valo <kvalo@kernel.org> | ||
| 12 | - Jeff Johnson <jjohnson@kernel.org> | 11 | - Jeff Johnson <jjohnson@kernel.org> |
| 13 | 12 | ||
| 14 | description: | | 13 | description: | |
| @@ -8,7 +8,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 7 unmodified lines | |||
| 8 | title: Qualcomm Technologies ath11k wireless devices | 8 | title: Qualcomm Technologies ath11k wireless devices |
| 9 | 9 | ||
| 10 | maintainers: | 10 | maintainers: |
| 11 | - Kalle Valo <kvalo@kernel.org> | ||
| 12 | - Jeff Johnson <jjohnson@kernel.org> | 11 | - Jeff Johnson <jjohnson@kernel.org> |
| 13 | 12 | ||
| 14 | description: | | 13 | description: | |
| @@ -9,7 +9,6 @@ title: Qualcomm Technologies ath12k wireless devices (PCIe) with WSI interface · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | maintainers: | 10 | maintainers: |
| 11 | - Jeff Johnson <jjohnson@kernel.org> | 11 | - Jeff Johnson <jjohnson@kernel.org> |
| 12 | - Kalle Valo <kvalo@kernel.org> | ||
| 13 | 12 | ||
| 14 | description: | | 13 | description: | |
| 15 | Qualcomm Technologies IEEE 802.11be PCIe devices with WSI interface. | 14 | Qualcomm Technologies IEEE 802.11be PCIe devices with WSI interface. |
| @@ -9,7 +9,6 @@ title: Qualcomm Technologies ath12k wireless devices (PCIe) · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | maintainers: | 10 | maintainers: |
| 11 | - Jeff Johnson <quic_jjohnson@quicinc.com> | 11 | - Jeff Johnson <quic_jjohnson@quicinc.com> |
| 12 | - Kalle Valo <kvalo@kernel.org> | ||
| 13 | 12 | ||
| 14 | description: | 13 | description: |
| 15 | Qualcomm Technologies IEEE 802.11be PCIe devices. | 14 | Qualcomm Technologies IEEE 802.11be PCIe devices. |
| @@ -1524,7 +1524,8 @@ attribute-sets: · 1523 unmodified lines | |||
| 1524 | nested-attributes: bitset | 1524 | nested-attributes: bitset |
| 1525 | - | 1525 | - |
| 1526 | name: hwtstamp-flags | 1526 | name: hwtstamp-flags |
| 1527 | type: u32 | 1527 | type: nest |
| 1528 | nested-attributes: bitset | ||
| 1528 | 1529 | ||
| 1529 | operations: | 1530 | operations: |
| 1530 | enum-model: directional | 1531 | enum-model: directional |
| @@ -369,8 +369,8 @@ to their default. · 368 unmodified lines | |||
| 369 | 369 | ||
| 370 | addr.can_family = AF_CAN; | 370 | addr.can_family = AF_CAN; |
| 371 | addr.can_ifindex = if_nametoindex("can0"); | 371 | addr.can_ifindex = if_nametoindex("can0"); |
| 372 | addr.tp.tx_id = 0x18DA42F1 | CAN_EFF_FLAG; | 372 | addr.can_addr.tp.tx_id = 0x18DA42F1 | CAN_EFF_FLAG; |
| 373 | addr.tp.rx_id = 0x18DAF142 | CAN_EFF_FLAG; | 373 | addr.can_addr.tp.rx_id = 0x18DAF142 | CAN_EFF_FLAG; |
| 374 | 374 | ||
| 375 | ret = bind(s, (struct sockaddr *)&addr, sizeof(addr)); | 375 | ret = bind(s, (struct sockaddr *)&addr, sizeof(addr)); |
| 376 | if (ret < 0) | 376 | if (ret < 0) |
| @@ -3654,7 +3654,6 @@ F: Documentation/devicetree/bindings/phy/phy-ath79-usb.txt · 3653 unmodified lines | |||
| 3654 | F: drivers/phy/qualcomm/phy-ath79-usb.c | 3654 | F: drivers/phy/qualcomm/phy-ath79-usb.c |
| 3655 | 3655 | ||
| 3656 | ATHEROS ATH GENERIC UTILITIES | 3656 | ATHEROS ATH GENERIC UTILITIES |
| 3657 | M: Kalle Valo <kvalo@kernel.org> | ||
| 3658 | M: Jeff Johnson <jjohnson@kernel.org> | 3657 | M: Jeff Johnson <jjohnson@kernel.org> |
| 3659 | L: linux-wireless@vger.kernel.org | 3658 | L: linux-wireless@vger.kernel.org |
| 3660 | S: Supported | 3659 | S: Supported |
| @@ -16438,7 +16437,7 @@ X: drivers/net/can/ · 12777 unmodified lines | |||
| 16438 | X: drivers/net/wireless/ | 16437 | X: drivers/net/wireless/ |
| 16439 | 16438 | ||
| 16440 | NETWORKING DRIVERS (WIRELESS) | 16439 | NETWORKING DRIVERS (WIRELESS) |
| 16441 | M: Kalle Valo <kvalo@kernel.org> | 16440 | M: Johannes Berg <johannes@sipsolutions.net> |
| 16442 | L: linux-wireless@vger.kernel.org | 16441 | L: linux-wireless@vger.kernel.org |
| 16443 | S: Maintained | 16442 | S: Maintained |
| 16444 | W: https://wireless.wiki.kernel.org/ | 16443 | W: https://wireless.wiki.kernel.org/ |
| @@ -16509,6 +16508,7 @@ F: include/linux/netdev* · 64 unmodified lines | |||
| 16509 | F: include/linux/netlink.h | 16508 | F: include/linux/netlink.h |
| 16510 | F: include/linux/netpoll.h | 16509 | F: include/linux/netpoll.h |
| 16511 | F: include/linux/rtnetlink.h | 16510 | F: include/linux/rtnetlink.h |
| 16511 | F: include/linux/sctp.h | ||
| 16512 | F: include/linux/seq_file_net.h | 16512 | F: include/linux/seq_file_net.h |
| 16513 | F: include/linux/skbuff* | 16513 | F: include/linux/skbuff* |
| 16514 | F: include/net/ | 16514 | F: include/net/ |
| @@ -16525,6 +16525,7 @@ F: include/uapi/linux/netdev* · 10 unmodified lines | |||
| 16525 | F: include/uapi/linux/netlink.h | 16525 | F: include/uapi/linux/netlink.h |
| 16526 | F: include/uapi/linux/netlink_diag.h | 16526 | F: include/uapi/linux/netlink_diag.h |
| 16527 | F: include/uapi/linux/rtnetlink.h | 16527 | F: include/uapi/linux/rtnetlink.h |
| 16528 | F: include/uapi/linux/sctp.h | ||
| 16528 | F: lib/net_utils.c | 16529 | F: lib/net_utils.c |
| 16529 | F: lib/random32.c | 16530 | F: lib/random32.c |
| 16530 | F: net/ | 16531 | F: net/ |
| @@ -19355,7 +19356,6 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ · 2824 unmodified lines | |||
| 19355 | F: drivers/media/tuners/qt1010* | 19356 | F: drivers/media/tuners/qt1010* |
| 19356 | 19357 | ||
| 19357 | QUALCOMM ATH12K WIRELESS DRIVER | 19358 | QUALCOMM ATH12K WIRELESS DRIVER |
| 19358 | M: Kalle Valo <kvalo@kernel.org> | ||
| 19359 | M: Jeff Johnson <jjohnson@kernel.org> | 19359 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19360 | L: ath12k@lists.infradead.org | 19360 | L: ath12k@lists.infradead.org |
| 19361 | S: Supported | 19361 | S: Supported |
| @@ -19365,7 +19365,6 @@ F: drivers/net/wireless/ath/ath12k/ · 3 unmodified lines | |||
| 19365 | N: ath12k | 19365 | N: ath12k |
| 19366 | 19366 | ||
| 19367 | QUALCOMM ATHEROS ATH10K WIRELESS DRIVER | 19367 | QUALCOMM ATHEROS ATH10K WIRELESS DRIVER |
| 19368 | M: Kalle Valo <kvalo@kernel.org> | ||
| 19369 | M: Jeff Johnson <jjohnson@kernel.org> | 19368 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19370 | L: ath10k@lists.infradead.org | 19369 | L: ath10k@lists.infradead.org |
| 19371 | S: Supported | 19370 | S: Supported |
| @@ -19375,7 +19374,6 @@ F: drivers/net/wireless/ath/ath10k/ · 3 unmodified lines | |||
| 19375 | N: ath10k | 19374 | N: ath10k |
| 19376 | 19375 | ||
| 19377 | QUALCOMM ATHEROS ATH11K WIRELESS DRIVER | 19376 | QUALCOMM ATHEROS ATH11K WIRELESS DRIVER |
| 19378 | M: Kalle Valo <kvalo@kernel.org> | ||
| 19379 | M: Jeff Johnson <jjohnson@kernel.org> | 19377 | M: Jeff Johnson <jjohnson@kernel.org> |
| 19380 | L: ath11k@lists.infradead.org | 19378 | L: ath11k@lists.infradead.org |
| 19381 | S: Supported | 19379 | S: Supported |
| @@ -1320,6 +1320,10 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev, · 1319 unmodified lines | |||
| 1320 | if (opcode == 0xfc01) | 1320 | if (opcode == 0xfc01) |
| 1321 | btintel_pcie_inject_cmd_complete(hdev, opcode); | 1321 | btintel_pcie_inject_cmd_complete(hdev, opcode); |
| 1322 | } | 1322 | } |
| 1323 | /* Firmware raises alive interrupt on HCI_OP_RESET */ | ||
| 1324 | if (opcode == HCI_OP_RESET) | ||
| 1325 | data->gp0_received = false; | ||
| 1326 | |||
| 1323 | hdev->stat.cmd_tx++; | 1327 | hdev->stat.cmd_tx++; |
| 1324 | break; | 1328 | break; |
| 1325 | case HCI_ACLDATA_PKT: | 1329 | case HCI_ACLDATA_PKT: |
| @@ -1357,7 +1361,6 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev, · 31 unmodified lines | |||
| 1357 | opcode, btintel_pcie_alivectxt_state2str(old_ctxt), | 1361 | opcode, btintel_pcie_alivectxt_state2str(old_ctxt), |
| 1358 | btintel_pcie_alivectxt_state2str(data->alive_intr_ctxt)); | 1362 | btintel_pcie_alivectxt_state2str(data->alive_intr_ctxt)); |
| 1359 | if (opcode == HCI_OP_RESET) { | 1363 | if (opcode == HCI_OP_RESET) { |
| 1360 | data->gp0_received = false; | ||
| 1361 | ret = wait_event_timeout(data->gp0_wait_q, | 1364 | ret = wait_event_timeout(data->gp0_wait_q, |
| 1362 | data->gp0_received, | 1365 | data->gp0_received, |
| 1363 | msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); | 1366 | msecs_to_jiffies(BTINTEL_DEFAULT_INTR_TIMEOUT_MS)); |
| @@ -385,15 +385,16 @@ static int c_can_plat_probe(struct platform_device *pdev) · 384 unmodified lines | |||
| 385 | if (ret) { | 385 | if (ret) { |
| 386 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", | 386 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", |
| 387 | KBUILD_MODNAME, ret); | 387 | KBUILD_MODNAME, ret); |
| 388 | goto exit_free_device; | 388 | goto exit_pm_runtime; |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", | 391 | dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", |
| 392 | KBUILD_MODNAME, priv->base, dev->irq); | 392 | KBUILD_MODNAME, priv->base, dev->irq); |
| 393 | return 0; | 393 | return 0; |
| 394 | 394 | ||
| 395 | exit_free_device: | 395 | exit_pm_runtime: |
| 396 | pm_runtime_disable(priv->device); | 396 | pm_runtime_disable(priv->device); |
| 397 | exit_free_device: | ||
| 397 | free_c_can_dev(dev); | 398 | free_c_can_dev(dev); |
| 398 | exit: | 399 | exit: |
| 399 | dev_err(&pdev->dev, "probe failed\n"); | 400 | dev_err(&pdev->dev, "probe failed\n"); |
| @@ -867,10 +867,12 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr) · 866 unmodified lines | |||
| 867 | } | 867 | } |
| 868 | break; | 868 | break; |
| 869 | case CAN_STATE_ERROR_ACTIVE: | 869 | case CAN_STATE_ERROR_ACTIVE: |
| 870 | cf->can_id |= CAN_ERR_CNT; | 870 | if (skb) { |
| 871 | cf->data[1] = CAN_ERR_CRTL_ACTIVE; | 871 | cf->can_id |= CAN_ERR_CNT; |
| 872 | cf->data[6] = bec.txerr; | 872 | cf->data[1] = CAN_ERR_CRTL_ACTIVE; |
| 873 | cf->data[7] = bec.rxerr; | 873 | cf->data[6] = bec.txerr; |
| 874 | cf->data[7] = bec.rxerr; | ||
| 875 | } | ||
| 874 | break; | 876 | break; |
| 875 | default: | 877 | default: |
| 876 | netdev_warn(ndev, "unhandled error state (%d:%s)!\n", | 878 | netdev_warn(ndev, "unhandled error state (%d:%s)!\n", |
| @@ -622,7 +622,7 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv) · 621 unmodified lines | |||
| 622 | netdev_dbg(priv->ndev, "RX-FIFO overflow\n"); | 622 | netdev_dbg(priv->ndev, "RX-FIFO overflow\n"); |
| 623 | 623 | ||
| 624 | skb = rkcanfd_alloc_can_err_skb(priv, &cf, ×tamp); | 624 | skb = rkcanfd_alloc_can_err_skb(priv, &cf, ×tamp); |
| 625 | if (skb) | 625 | if (!skb) |
| 626 | return 0; | 626 | return 0; |
| 627 | 627 | ||
| 628 | rkcanfd_get_berr_counter_corrected(priv, &bec); | 628 | rkcanfd_get_berr_counter_corrected(priv, &bec); |
| @@ -248,7 +248,11 @@ static int es58x_devlink_info_get(struct devlink *devlink, · 247 unmodified lines | |||
| 248 | return ret; | 248 | return ret; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | return devlink_info_serial_number_put(req, es58x_dev->udev->serial); | 251 | if (es58x_dev->udev->serial) |
| 252 | ret = devlink_info_serial_number_put(req, | ||
| 253 | es58x_dev->udev->serial); | ||
| 254 | |||
| 255 | return ret; | ||
| 252 | } | 256 | } |
| 253 | 257 | ||
| 254 | const struct devlink_ops es58x_dl_ops = { | 258 | const struct devlink_ops es58x_dl_ops = { |
| @@ -2903,8 +2903,8 @@ static void iavf_watchdog_task(struct work_struct *work) · 2902 unmodified lines | |||
| 2903 | } | 2903 | } |
| 2904 | 2904 | ||
| 2905 | mutex_unlock(&adapter->crit_lock); | 2905 | mutex_unlock(&adapter->crit_lock); |
| 2906 | netdev_unlock(netdev); | ||
| 2907 | restart_watchdog: | 2906 | restart_watchdog: |
| 2907 | netdev_unlock(netdev); | ||
| 2908 | if (adapter->state >= __IAVF_DOWN) | 2908 | if (adapter->state >= __IAVF_DOWN) |
| 2909 | queue_work(adapter->wq, &adapter->adminq_task); | 2909 | queue_work(adapter->wq, &adapter->adminq_task); |
| 2910 | if (adapter->aq_required) | 2910 | if (adapter->aq_required) |
| @@ -2159,8 +2159,13 @@ static int idpf_open(struct net_device *netdev) · 2158 unmodified lines | |||
| 2159 | idpf_vport_ctrl_lock(netdev); | 2159 | idpf_vport_ctrl_lock(netdev); |
| 2160 | vport = idpf_netdev_to_vport(netdev); | 2160 | vport = idpf_netdev_to_vport(netdev); |
| 2161 | 2161 | ||
| 2162 | err = idpf_set_real_num_queues(vport); | ||
| 2163 | if (err) | ||
| 2164 | goto unlock; | ||
| 2165 | |||
| 2162 | err = idpf_vport_open(vport); | 2166 | err = idpf_vport_open(vport); |
| 2163 | 2167 | ||
| 2168 | unlock: | ||
| 2164 | idpf_vport_ctrl_unlock(netdev); | 2169 | idpf_vport_ctrl_unlock(netdev); |
| 2165 | 2170 | ||
| 2166 | return err; | 2171 | return err; |
| @@ -3008,8 +3008,6 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb, · 3007 unmodified lines | |||
| 3008 | return -EINVAL; | 3008 | return -EINVAL; |
| 3009 | 3009 | ||
| 3010 | rsc_segments = DIV_ROUND_UP(skb->data_len, rsc_seg_len); | 3010 | rsc_segments = DIV_ROUND_UP(skb->data_len, rsc_seg_len); |
| 3011 | if (unlikely(rsc_segments == 1)) | ||
| 3012 | return 0; | ||
| 3013 | 3011 | ||
| 3014 | NAPI_GRO_CB(skb)->count = rsc_segments; | 3012 | NAPI_GRO_CB(skb)->count = rsc_segments; |
| 3015 | skb_shinfo(skb)->gso_size = rsc_seg_len; | 3013 | skb_shinfo(skb)->gso_size = rsc_seg_len; |
| @@ -3072,6 +3070,7 @@ idpf_rx_process_skb_fields(struct idpf_rx_queue *rxq, struct sk_buff *skb, · 56 unmodified lines | |||
| 3072 | idpf_rx_hash(rxq, skb, rx_desc, decoded); | 3070 | idpf_rx_hash(rxq, skb, rx_desc, decoded); |
| 3073 | 3071 | ||
| 3074 | skb->protocol = eth_type_trans(skb, rxq->netdev); | 3072 | skb->protocol = eth_type_trans(skb, rxq->netdev); |
| 3073 | skb_record_rx_queue(skb, rxq->idx); | ||
| 3075 | 3074 | ||
| 3076 | if (le16_get_bits(rx_desc->hdrlen_flags, | 3075 | if (le16_get_bits(rx_desc->hdrlen_flags, |
| 3077 | VIRTCHNL2_RX_FLEX_DESC_ADV_RSC_M)) | 3076 | VIRTCHNL2_RX_FLEX_DESC_ADV_RSC_M)) |
| @@ -3080,8 +3079,6 @@ idpf_rx_process_skb_fields(struct idpf_rx_queue *rxq, struct sk_buff *skb, · 2 unmodified lines | |||
| 3080 | csum_bits = idpf_rx_splitq_extract_csum_bits(rx_desc); | 3079 | csum_bits = idpf_rx_splitq_extract_csum_bits(rx_desc); |
| 3081 | idpf_rx_csum(rxq, skb, csum_bits, decoded); | 3080 | idpf_rx_csum(rxq, skb, csum_bits, decoded); |
| 3082 | 3081 | ||
| 3083 | skb_record_rx_queue(skb, rxq->idx); | ||
| 3084 | |||
| 3085 | return 0; | 3082 | return 0; |
| 3086 | } | 3083 | } |
| 3087 | 3084 | ||
| @@ -1096,6 +1096,7 @@ static int igc_init_empty_frame(struct igc_ring *ring, · 1095 unmodified lines | |||
| 1096 | return -ENOMEM; | 1096 | return -ENOMEM; |
| 1097 | } | 1097 | } |
| 1098 | 1098 | ||
| 1099 | buffer->type = IGC_TX_BUFFER_TYPE_SKB; | ||
| 1099 | buffer->skb = skb; | 1100 | buffer->skb = skb; |
| 1100 | buffer->protocol = 0; | 1101 | buffer->protocol = 0; |
| 1101 | buffer->bytecount = skb->len; | 1102 | buffer->bytecount = skb->len; |
| @@ -2701,8 +2702,9 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget) · 1599 unmodified lines | |||
| 2701 | } | 2702 | } |
| 2702 | 2703 | ||
| 2703 | static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring, | 2704 | static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring, |
| 2704 | struct xdp_buff *xdp) | 2705 | struct igc_xdp_buff *ctx) |
| 2705 | { | 2706 | { |
| 2707 | struct xdp_buff *xdp = &ctx->xdp; | ||
| 2706 | unsigned int totalsize = xdp->data_end - xdp->data_meta; | 2708 | unsigned int totalsize = xdp->data_end - xdp->data_meta; |
| 2707 | unsigned int metasize = xdp->data - xdp->data_meta; | 2709 | unsigned int metasize = xdp->data - xdp->data_meta; |
| 2708 | struct sk_buff *skb; | 2710 | struct sk_buff *skb; |
| @@ -2721,27 +2723,28 @@ static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring, · 12 unmodified lines | |||
| 2721 | __skb_pull(skb, metasize); | 2723 | __skb_pull(skb, metasize); |
| 2722 | } | 2724 | } |
| 2723 | 2725 | ||
| 2726 | if (ctx->rx_ts) { | ||
| 2727 | skb_shinfo(skb)->tx_flags |= SKBTX_HW_TSTAMP_NETDEV; | ||
| 2728 | skb_hwtstamps(skb)->netdev_data = ctx->rx_ts; | ||
| 2729 | } | ||
| 2730 | |||
| 2724 | return skb; | 2731 | return skb; |
| 2725 | } | 2732 | } |
| 2726 | 2733 | ||
| 2727 | static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector, | 2734 | static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector, |
| 2728 | union igc_adv_rx_desc *desc, | 2735 | union igc_adv_rx_desc *desc, |
| 2729 | struct xdp_buff *xdp, | 2736 | struct igc_xdp_buff *ctx) |
| 2730 | ktime_t timestamp) | ||
| 2731 | { | 2737 | { |
| 2732 | struct igc_ring *ring = q_vector->rx.ring; | 2738 | struct igc_ring *ring = q_vector->rx.ring; |
| 2733 | struct sk_buff *skb; | 2739 | struct sk_buff *skb; |
| 2734 | 2740 | ||
| 2735 | skb = igc_construct_skb_zc(ring, xdp); | 2741 | skb = igc_construct_skb_zc(ring, ctx); |
| 2736 | if (!skb) { | 2742 | if (!skb) { |
| 2737 | ring->rx_stats.alloc_failed++; | 2743 | ring->rx_stats.alloc_failed++; |
| 2738 | set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags); | 2744 | set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags); |
| 2739 | return; | 2745 | return; |
| 2740 | } | 2746 | } |
| 2741 | 2747 | ||
| 2742 | if (timestamp) | ||
| 2743 | skb_hwtstamps(skb)->hwtstamp = timestamp; | ||
| 2744 | |||
| 2745 | if (igc_cleanup_headers(ring, desc, skb)) | 2748 | if (igc_cleanup_headers(ring, desc, skb)) |
| 2746 | return; | 2749 | return; |
| 2747 | 2750 | ||
| @@ -2777,7 +2780,6 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget) · 29 unmodified lines | |||
| 2777 | union igc_adv_rx_desc *desc; | 2780 | union igc_adv_rx_desc *desc; |
| 2778 | struct igc_rx_buffer *bi; | 2781 | struct igc_rx_buffer *bi; |
| 2779 | struct igc_xdp_buff *ctx; | 2782 | struct igc_xdp_buff *ctx; |
| 2780 | ktime_t timestamp = 0; | ||
| 2781 | unsigned int size; | 2783 | unsigned int size; |
| 2782 | int res; | 2784 | int res; |
| 2783 | 2785 | ||
| @@ -2807,6 +2809,8 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget) · 23 unmodified lines | |||
| 2807 | */ | 2809 | */ |
| 2808 | bi->xdp->data_meta += IGC_TS_HDR_LEN; | 2810 | bi->xdp->data_meta += IGC_TS_HDR_LEN; |
| 2809 | size -= IGC_TS_HDR_LEN; | 2811 | size -= IGC_TS_HDR_LEN; |
| 2812 | } else { | ||
| 2813 | ctx->rx_ts = NULL; | ||
| 2810 | } | 2814 | } |
| 2811 | 2815 | ||
| 2812 | bi->xdp->data_end = bi->xdp->data + size; | 2816 | bi->xdp->data_end = bi->xdp->data + size; |
| @@ -2815,7 +2819,7 @@ static int igc_clean_rx_irq_zc(struct igc_q_vector *q_vector, const int budget) · 2 unmodified lines | |||
| 2815 | res = __igc_xdp_run_prog(adapter, prog, bi->xdp); | 2819 | res = __igc_xdp_run_prog(adapter, prog, bi->xdp); |
| 2816 | switch (res) { | 2820 | switch (res) { |
| 2817 | case IGC_XDP_PASS: | 2821 | case IGC_XDP_PASS: |
| 2818 | igc_dispatch_skb_zc(q_vector, desc, bi->xdp, timestamp); | 2822 | igc_dispatch_skb_zc(q_vector, desc, ctx); |
| 2819 | fallthrough; | 2823 | fallthrough; |
| 2820 | case IGC_XDP_CONSUMED: | 2824 | case IGC_XDP_CONSUMED: |
| 2821 | xsk_buff_free(bi->xdp); | 2825 | xsk_buff_free(bi->xdp); |
| @@ -2105,7 +2105,7 @@ static void ixgbe_put_rx_buffer(struct ixgbe_ring *rx_ring, · 2104 unmodified lines | |||
| 2105 | /* hand second half of page back to the ring */ | 2105 | /* hand second half of page back to the ring */ |
| 2106 | ixgbe_reuse_rx_page(rx_ring, rx_buffer); | 2106 | ixgbe_reuse_rx_page(rx_ring, rx_buffer); |
| 2107 | } else { | 2107 | } else { |
| 2108 | if (!IS_ERR(skb) && IXGBE_CB(skb)->dma == rx_buffer->dma) { | 2108 | if (skb && IXGBE_CB(skb)->dma == rx_buffer->dma) { |
| 2109 | /* the page has been released from the ring */ | 2109 | /* the page has been released from the ring */ |
| 2110 | IXGBE_CB(skb)->page_released = true; | 2110 | IXGBE_CB(skb)->page_released = true; |
| 2111 | } else { | 2111 | } else { |
| @@ -768,7 +768,9 @@ static void __mlxsw_sp_port_get_stats(struct net_device *dev, · 767 unmodified lines | |||
| 768 | err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp); | 768 | err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp); |
| 769 | if (err) | 769 | if (err) |
| 770 | return; | 770 | return; |
| 771 | mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); | 771 | err = mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); |
| 772 | if (err) | ||
| 773 | return; | ||
| 772 | for (i = 0; i < len; i++) { | 774 | for (i = 0; i < len; i++) { |
| 773 | data[data_index + i] = hw_stats[i].getter(ppcnt_pl); | 775 | data[data_index + i] = hw_stats[i].getter(ppcnt_pl); |
| 774 | if (!hw_stats[i].cells_bytes) | 776 | if (!hw_stats[i].cells_bytes) |
| @@ -2094,6 +2094,11 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, · 2093 unmodified lines | |||
| 2094 | pp_params.offset = stmmac_rx_offset(priv); | 2094 | pp_params.offset = stmmac_rx_offset(priv); |
| 2095 | pp_params.max_len = dma_conf->dma_buf_sz; | 2095 | pp_params.max_len = dma_conf->dma_buf_sz; |
| 2096 | 2096 | ||
| 2097 | if (priv->sph) { | ||
| 2098 | pp_params.offset = 0; | ||
| 2099 | pp_params.max_len += stmmac_rx_offset(priv); | ||
| 2100 | } | ||
| 2101 | |||
| 2097 | rx_q->page_pool = page_pool_create(&pp_params); | 2102 | rx_q->page_pool = page_pool_create(&pp_params); |
| 2098 | if (IS_ERR(rx_q->page_pool)) { | 2103 | if (IS_ERR(rx_q->page_pool)) { |
| 2099 | ret = PTR_ERR(rx_q->page_pool); | 2104 | ret = PTR_ERR(rx_q->page_pool); |
| @@ -828,21 +828,30 @@ static void am65_cpsw_nuss_xmit_free(struct am65_cpsw_tx_chn *tx_chn, · 827 unmodified lines | |||
| 828 | static void am65_cpsw_nuss_tx_cleanup(void *data, dma_addr_t desc_dma) | 828 | static void am65_cpsw_nuss_tx_cleanup(void *data, dma_addr_t desc_dma) |
| 829 | { | 829 | { |
| 830 | struct am65_cpsw_tx_chn *tx_chn = data; | 830 | struct am65_cpsw_tx_chn *tx_chn = data; |
| 831 | enum am65_cpsw_tx_buf_type buf_type; | ||
| 831 | struct cppi5_host_desc_t *desc_tx; | 832 | struct cppi5_host_desc_t *desc_tx; |
| 833 | struct xdp_frame *xdpf; | ||
| 832 | struct sk_buff *skb; | 834 | struct sk_buff *skb; |
| 833 | void **swdata; | 835 | void **swdata; |
| 834 | 836 | ||
| 835 | desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); | 837 | desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); |
| 836 | swdata = cppi5_hdesc_get_swdata(desc_tx); | 838 | swdata = cppi5_hdesc_get_swdata(desc_tx); |
| 837 | skb = *(swdata); | 839 | buf_type = am65_cpsw_nuss_buf_type(tx_chn, desc_dma); |
| 838 | am65_cpsw_nuss_xmit_free(tx_chn, desc_tx); | 840 | if (buf_type == AM65_CPSW_TX_BUF_TYPE_SKB) { |
| 841 | skb = *(swdata); | ||
| 842 | dev_kfree_skb_any(skb); | ||
| 843 | } else { | ||
| 844 | xdpf = *(swdata); | ||
| 845 | xdp_return_frame(xdpf); | ||
| 846 | } | ||
| 839 | 847 | ||
| 840 | dev_kfree_skb_any(skb); | 848 | am65_cpsw_nuss_xmit_free(tx_chn, desc_tx); |
| 841 | } | 849 | } |
| 842 | 850 | ||
| 843 | static struct sk_buff *am65_cpsw_build_skb(void *page_addr, | 851 | static struct sk_buff *am65_cpsw_build_skb(void *page_addr, |
| 844 | struct net_device *ndev, | 852 | struct net_device *ndev, |
| 845 | unsigned int len) | 853 | unsigned int len, |
| 854 | unsigned int headroom) | ||
| 846 | { | 855 | { |
| 847 | struct sk_buff *skb; | 856 | struct sk_buff *skb; |
| 848 | 857 | ||
| @@ -852,7 +861,7 @@ static struct sk_buff *am65_cpsw_build_skb(void *page_addr, · 3 unmodified lines | |||
| 852 | if (unlikely(!skb)) | 861 | if (unlikely(!skb)) |
| 853 | return NULL; | 862 | return NULL; |
| 854 | 863 | ||
| 855 | skb_reserve(skb, AM65_CPSW_HEADROOM); | 864 | skb_reserve(skb, headroom); |
| 856 | skb->dev = ndev; | 865 | skb->dev = ndev; |
| 857 | 866 | ||
| 858 | return skb; | 867 | return skb; |
| @@ -1169,9 +1178,11 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow, · 310 unmodified lines | |||
| 1169 | struct xdp_frame *xdpf; | 1178 | struct xdp_frame *xdpf; |
| 1170 | struct bpf_prog *prog; | 1179 | struct bpf_prog *prog; |
| 1171 | struct page *page; | 1180 | struct page *page; |
| 1181 | int pkt_len; | ||
| 1172 | u32 act; | 1182 | u32 act; |
| 1173 | int err; | 1183 | int err; |
| 1174 | 1184 | ||
| 1185 | pkt_len = *len; | ||
| 1175 | prog = READ_ONCE(port->xdp_prog); | 1186 | prog = READ_ONCE(port->xdp_prog); |
| 1176 | if (!prog) | 1187 | if (!prog) |
| 1177 | return AM65_CPSW_XDP_PASS; | 1188 | return AM65_CPSW_XDP_PASS; |
| @@ -1189,8 +1200,10 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow, · 11 unmodified lines | |||
| 1189 | netif_txq = netdev_get_tx_queue(ndev, tx_chn->id); | 1200 | netif_txq = netdev_get_tx_queue(ndev, tx_chn->id); |
| 1190 | 1201 | ||
| 1191 | xdpf = xdp_convert_buff_to_frame(xdp); | 1202 | xdpf = xdp_convert_buff_to_frame(xdp); |
| 1192 | if (unlikely(!xdpf)) | 1203 | if (unlikely(!xdpf)) { |
| 1204 | ndev->stats.tx_dropped++; | ||
| 1193 | goto drop; | 1205 | goto drop; |
| 1206 | } | ||
| 1194 | 1207 | ||
| 1195 | __netif_tx_lock(netif_txq, cpu); | 1208 | __netif_tx_lock(netif_txq, cpu); |
| 1196 | err = am65_cpsw_xdp_tx_frame(ndev, tx_chn, xdpf, | 1209 | err = am65_cpsw_xdp_tx_frame(ndev, tx_chn, xdpf, |
| @@ -1199,14 +1212,14 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_rx_flow *flow, · 2 unmodified lines | |||
| 1199 | if (err) | 1212 | if (err) |
| 1200 | goto drop; | 1213 | goto drop; |
| 1201 | 1214 | ||
| 1202 | dev_sw_netstats_tx_add(ndev, 1, *len); | 1215 | dev_sw_netstats_rx_add(ndev, pkt_len); |
| 1203 | ret = AM65_CPSW_XDP_CONSUMED; | 1216 | ret = AM65_CPSW_XDP_CONSUMED; |
| 1204 | goto out; | 1217 | goto out; |
| 1205 | case XDP_REDIRECT: | 1218 | case XDP_REDIRECT: |
| 1206 | if (unlikely(xdp_do_redirect(ndev, xdp, prog))) | 1219 | if (unlikely(xdp_do_redirect(ndev, xdp, prog))) |
| 1207 | goto drop; | 1220 | goto drop; |
| 1208 | 1221 | ||
| 1209 | dev_sw_netstats_rx_add(ndev, *len); | 1222 | dev_sw_netstats_rx_add(ndev, pkt_len); |
| 1210 | ret = AM65_CPSW_XDP_REDIRECT; | 1223 | ret = AM65_CPSW_XDP_REDIRECT; |
| 1211 | goto out; | 1224 | goto out; |
| 1212 | default: | 1225 | default: |
| @@ -1315,16 +1328,8 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow, · 102 unmodified lines | |||
| 1315 | dev_dbg(dev, "%s rx csum_info:%#x\n", __func__, csum_info); | 1328 | dev_dbg(dev, "%s rx csum_info:%#x\n", __func__, csum_info); |
| 1316 | 1329 | ||
| 1317 | dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); | 1330 | dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); |
| 1318 | |||
| 1319 | k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); | 1331 | k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); |
| 1320 | 1332 | ||
| 1321 | skb = am65_cpsw_build_skb(page_addr, ndev, | ||
| 1322 | AM65_CPSW_MAX_PACKET_SIZE); | ||
| 1323 | if (unlikely(!skb)) { | ||
| 1324 | new_page = page; | ||
| 1325 | goto requeue; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | if (port->xdp_prog) { | 1333 | if (port->xdp_prog) { |
| 1329 | xdp_init_buff(&xdp, PAGE_SIZE, &port->xdp_rxq[flow->id]); | 1334 | xdp_init_buff(&xdp, PAGE_SIZE, &port->xdp_rxq[flow->id]); |
| 1330 | xdp_prepare_buff(&xdp, page_addr, AM65_CPSW_HEADROOM, | 1335 | xdp_prepare_buff(&xdp, page_addr, AM65_CPSW_HEADROOM, |
| @@ -1334,9 +1339,16 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow, · 3 unmodified lines | |||
| 1334 | if (*xdp_state != AM65_CPSW_XDP_PASS) | 1339 | if (*xdp_state != AM65_CPSW_XDP_PASS) |
| 1335 | goto allocate; | 1340 | goto allocate; |
| 1336 | 1341 | ||
| 1337 | /* Compute additional headroom to be reserved */ | 1342 | headroom = xdp.data - xdp.data_hard_start; |
| 1338 | headroom = (xdp.data - xdp.data_hard_start) - skb_headroom(skb); | 1343 | } else { |
| 1339 | skb_reserve(skb, headroom); | 1344 | headroom = AM65_CPSW_HEADROOM; |
| 1345 | } | ||
| 1346 | |||
| 1347 | skb = am65_cpsw_build_skb(page_addr, ndev, | ||
| 1348 | AM65_CPSW_MAX_PACKET_SIZE, headroom); | ||
| 1349 | if (unlikely(!skb)) { | ||
| 1350 | new_page = page; | ||
| 1351 | goto requeue; | ||
| 1340 | } | 1352 | } |
| 1341 | 1353 | ||
| 1342 | ndev_priv = netdev_priv(ndev); | 1354 | ndev_priv = netdev_priv(ndev); |
| @@ -2265,12 +2265,15 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, · 2264 unmodified lines | |||
| 2265 | /* Allow the MAC to stop its clock if the PHY has the capability */ | 2265 | /* Allow the MAC to stop its clock if the PHY has the capability */ |
| 2266 | pl->mac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) > 0; | 2266 | pl->mac_tx_clk_stop = phy_eee_tx_clock_stop_capable(phy) > 0; |
| 2267 | 2267 | ||
| 2268 | /* Explicitly configure whether the PHY is allowed to stop it's | 2268 | if (pl->mac_supports_eee_ops) { |
| 2269 | * receive clock. | 2269 | /* Explicitly configure whether the PHY is allowed to stop it's |
| 2270 | */ | 2270 | * receive clock. |
| 2271 | ret = phy_eee_rx_clock_stop(phy, pl->config->eee_rx_clk_stop_enable); | 2271 | */ |
| 2272 | if (ret == -EOPNOTSUPP) | 2272 | ret = phy_eee_rx_clock_stop(phy, |
| 2273 | ret = 0; | 2273 | pl->config->eee_rx_clk_stop_enable); |
| 2274 | if (ret == -EOPNOTSUPP) | ||
| 2275 | ret = 0; | ||
| 2276 | } | ||
| 2274 | 2277 | ||
| 2275 | return ret; | 2278 | return ret; |
| 2276 | } | 2279 | } |
| @@ -319,7 +319,7 @@ static int pse_pi_get_current_limit(struct regulator_dev *rdev) · 318 unmodified lines | |||
| 319 | goto out; | 319 | goto out; |
| 320 | mW = ret; | 320 | mW = ret; |
| 321 | 321 | ||
| 322 | ret = pse_pi_get_voltage(rdev); | 322 | ret = _pse_pi_get_voltage(rdev); |
| 323 | if (!ret) { | 323 | if (!ret) { |
| 324 | dev_err(pcdev->dev, "Voltage null\n"); | 324 | dev_err(pcdev->dev, "Voltage null\n"); |
| 325 | ret = -ERANGE; | 325 | ret = -ERANGE; |
| @@ -356,7 +356,7 @@ static int pse_pi_set_current_limit(struct regulator_dev *rdev, int min_uA, · 30 unmodified lines | |||
| 356 | 356 | ||
| 357 | id = rdev_get_id(rdev); | 357 | id = rdev_get_id(rdev); |
| 358 | mutex_lock(&pcdev->lock); | 358 | mutex_lock(&pcdev->lock); |
| 359 | ret = pse_pi_get_voltage(rdev); | 359 | ret = _pse_pi_get_voltage(rdev); |
| 360 | if (!ret) { | 360 | if (!ret) { |
| 361 | dev_err(pcdev->dev, "Voltage null\n"); | 361 | dev_err(pcdev->dev, "Voltage null\n"); |
| 362 | ret = -ERANGE; | 362 | ret = -ERANGE; |
| @@ -2639,7 +2639,9 @@ int team_nl_options_set_doit(struct sk_buff *skb, struct genl_info *info) · 2638 unmodified lines | |||
| 2639 | ctx.data.u32_val = nla_get_u32(attr_data); | 2639 | ctx.data.u32_val = nla_get_u32(attr_data); |
| 2640 | break; | 2640 | break; |
| 2641 | case TEAM_OPTION_TYPE_STRING: | 2641 | case TEAM_OPTION_TYPE_STRING: |
| 2642 | if (nla_len(attr_data) > TEAM_STRING_MAX_LEN) { | 2642 | if (nla_len(attr_data) > TEAM_STRING_MAX_LEN || |
| 2643 | !memchr(nla_data(attr_data), '\0', | ||
| 2644 | nla_len(attr_data))) { | ||
| 2643 | err = -EINVAL; | 2645 | err = -EINVAL; |
| 2644 | goto team_put; | 2646 | goto team_put; |
| 2645 | } | 2647 | } |
| @@ -2898,8 +2898,11 @@ static int vxlan_init(struct net_device *dev) · 2897 unmodified lines | |||
| 2898 | struct vxlan_dev *vxlan = netdev_priv(dev); | 2898 | struct vxlan_dev *vxlan = netdev_priv(dev); |
| 2899 | int err; | 2899 | int err; |
| 2900 | 2900 | ||
| 2901 | if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) | 2901 | if (vxlan->cfg.flags & VXLAN_F_VNIFILTER) { |
| 2902 | vxlan_vnigroup_init(vxlan); | 2902 | err = vxlan_vnigroup_init(vxlan); |
| 2903 | if (err) | ||
| 2904 | return err; | ||
| 2905 | } | ||
| 2903 | 2906 | ||
| 2904 | err = gro_cells_init(&vxlan->gro_cells, dev); | 2907 | err = gro_cells_init(&vxlan->gro_cells, dev); |
| 2905 | if (err) | 2908 | if (err) |
| @@ -4851,6 +4851,22 @@ static struct ath12k_reg_rule · 4850 unmodified lines | |||
| 4851 | return reg_rule_ptr; | 4851 | return reg_rule_ptr; |
| 4852 | } | 4852 | } |
| 4853 | 4853 | ||
| 4854 | static u8 ath12k_wmi_ignore_num_extra_rules(struct ath12k_wmi_reg_rule_ext_params *rule, | ||
| 4855 | u32 num_reg_rules) | ||
| 4856 | { | ||
| 4857 | u8 num_invalid_5ghz_rules = 0; | ||
| 4858 | u32 count, start_freq; | ||
| 4859 | |||
| 4860 | for (count = 0; count < num_reg_rules; count++) { | ||
| 4861 | start_freq = le32_get_bits(rule[count].freq_info, REG_RULE_START_FREQ); | ||
| 4862 | |||
| 4863 | if (start_freq >= ATH12K_MIN_6G_FREQ) | ||
| 4864 | num_invalid_5ghz_rules++; | ||
| 4865 | } | ||
| 4866 | |||
| 4867 | return num_invalid_5ghz_rules; | ||
| 4868 | } | ||
| 4869 | |||
| 4854 | static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, | 4870 | static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, |
| 4855 | struct sk_buff *skb, | 4871 | struct sk_buff *skb, |
| 4856 | struct ath12k_reg_info *reg_info) | 4872 | struct ath12k_reg_info *reg_info) |
| @@ -4861,6 +4877,7 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, · 4 unmodified lines | |||
| 4861 | u32 num_2g_reg_rules, num_5g_reg_rules; | 4877 | u32 num_2g_reg_rules, num_5g_reg_rules; |
| 4862 | u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; | 4878 | u32 num_6g_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; |
| 4863 | u32 num_6g_reg_rules_cl[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; | 4879 | u32 num_6g_reg_rules_cl[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; |
| 4880 | u8 num_invalid_5ghz_ext_rules; | ||
| 4864 | u32 total_reg_rules = 0; | 4881 | u32 total_reg_rules = 0; |
| 4865 | int ret, i, j; | 4882 | int ret, i, j; |
| 4866 | 4883 | ||
| @@ -4954,20 +4971,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, · 87 unmodified lines | |||
| 4954 | 4971 | ||
| 4955 | memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN); | 4972 | memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN); |
| 4956 | 4973 | ||
| 4957 | /* FIXME: Currently FW includes 6G reg rule also in 5G rule | ||
| 4958 | * list for country US. | ||
| 4959 | * Having same 6G reg rule in 5G and 6G rules list causes | ||
| 4960 | * intersect check to be true, and same rules will be shown | ||
| 4961 | * multiple times in iw cmd. So added hack below to avoid | ||
| 4962 | * parsing 6G rule from 5G reg rule list, and this can be | ||
| 4963 | * removed later, after FW updates to remove 6G reg rule | ||
| 4964 | * from 5G rules list. | ||
| 4965 | */ | ||
| 4966 | if (memcmp(reg_info->alpha2, "US", 2) == 0) { | ||
| 4967 | reg_info->num_5g_reg_rules = REG_US_5G_NUM_REG_RULES; | ||
| 4968 | num_5g_reg_rules = reg_info->num_5g_reg_rules; | ||
| 4969 | } | ||
| 4970 | |||
| 4971 | reg_info->dfs_region = le32_to_cpu(ev->dfs_region); | 4974 | reg_info->dfs_region = le32_to_cpu(ev->dfs_region); |
| 4972 | reg_info->phybitmap = le32_to_cpu(ev->phybitmap); | 4975 | reg_info->phybitmap = le32_to_cpu(ev->phybitmap); |
| 4973 | reg_info->num_phy = le32_to_cpu(ev->num_phy); | 4976 | reg_info->num_phy = le32_to_cpu(ev->num_phy); |
| @@ -5070,8 +5073,29 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, · 96 unmodified lines | |||
| 5070 | } | 5073 | } |
| 5071 | } | 5074 | } |
| 5072 | 5075 | ||
| 5076 | ext_wmi_reg_rule += num_2g_reg_rules; | ||
| 5077 | |||
| 5078 | /* Firmware might include 6 GHz reg rule in 5 GHz rule list | ||
| 5079 | * for few countries along with separate 6 GHz rule. | ||
| 5080 | * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list | ||
| 5081 | * causes intersect check to be true, and same rules will be | ||
| 5082 | * shown multiple times in iw cmd. | ||
| 5083 | * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list | ||
| 5084 | */ | ||
| 5085 | num_invalid_5ghz_ext_rules = ath12k_wmi_ignore_num_extra_rules(ext_wmi_reg_rule, | ||
| 5086 | num_5g_reg_rules); | ||
| 5087 | |||
| 5088 | if (num_invalid_5ghz_ext_rules) { | ||
| 5089 | ath12k_dbg(ab, ATH12K_DBG_WMI, | ||
| 5090 | "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules", | ||
| 5091 | reg_info->alpha2, reg_info->num_5g_reg_rules, | ||
| 5092 | num_invalid_5ghz_ext_rules); | ||
| 5093 | |||
| 5094 | num_5g_reg_rules = num_5g_reg_rules - num_invalid_5ghz_ext_rules; | ||
| 5095 | reg_info->num_5g_reg_rules = num_5g_reg_rules; | ||
| 5096 | } | ||
| 5097 | |||
| 5073 | if (num_5g_reg_rules) { | 5098 | if (num_5g_reg_rules) { |
| 5074 | ext_wmi_reg_rule += num_2g_reg_rules; | ||
| 5075 | reg_info->reg_rules_5g_ptr = | 5099 | reg_info->reg_rules_5g_ptr = |
| 5076 | create_ext_reg_rules_from_wmi(num_5g_reg_rules, | 5100 | create_ext_reg_rules_from_wmi(num_5g_reg_rules, |
| 5077 | ext_wmi_reg_rule); | 5101 | ext_wmi_reg_rule); |
| @@ -5083,7 +5107,12 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab, · 5 unmodified lines | |||
| 5083 | } | 5107 | } |
| 5084 | } | 5108 | } |
| 5085 | 5109 | ||
| 5086 | ext_wmi_reg_rule += num_5g_reg_rules; | 5110 | /* We have adjusted the number of 5 GHz reg rules above. But still those |
| 5111 | * many rules needs to be adjusted in ext_wmi_reg_rule. | ||
| 5112 | * | ||
| 5113 | * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases. | ||
| 5114 | */ | ||
| 5115 | ext_wmi_reg_rule += (num_5g_reg_rules + num_invalid_5ghz_ext_rules); | ||
| 5087 | 5116 | ||
| 5088 | for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { | 5117 | for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { |
| 5089 | reg_info->reg_rules_6g_ap_ptr[i] = | 5118 | reg_info->reg_rules_6g_ap_ptr[i] = |
| @@ -4073,7 +4073,6 @@ struct ath12k_wmi_eht_rate_set_params { · 4072 unmodified lines | |||
| 4073 | #define MAX_REG_RULES 10 | 4073 | #define MAX_REG_RULES 10 |
| 4074 | #define REG_ALPHA2_LEN 2 | 4074 | #define REG_ALPHA2_LEN 2 |
| 4075 | #define MAX_6G_REG_RULES 5 | 4075 | #define MAX_6G_REG_RULES 5 |
| 4076 | #define REG_US_5G_NUM_REG_RULES 4 | ||
| 4077 | 4076 | ||
| 4078 | enum wmi_start_event_param { | 4077 | enum wmi_start_event_param { |
| 4079 | WMI_VDEV_START_RESP_EVENT = 0, | 4078 | WMI_VDEV_START_RESP_EVENT = 0, |
| @@ -2712,7 +2712,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { · 2711 unmodified lines | |||
| 2712 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID, WCC), | 2712 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID, WCC), |
| 2713 | BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355, WCC), | 2713 | BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355, WCC), |
| 2714 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID, WCC), | 2714 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID, WCC), |
| 2715 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4355_DEVICE_ID, WCC), | 2715 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4355_DEVICE_ID, WCC_SEED), |
| 2716 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID, WCC), | 2716 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID, WCC), |
| 2717 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID, WCC), | 2717 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID, WCC), |
| 2718 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID, WCC), | 2718 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID, WCC), |
| @@ -2723,7 +2723,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { · 4 unmodified lines | |||
| 2723 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID, WCC), | 2723 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID, WCC), |
| 2724 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID, WCC), | 2724 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID, WCC), |
| 2725 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID, WCC), | 2725 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID, WCC), |
| 2726 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4364_DEVICE_ID, WCC), | 2726 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4364_DEVICE_ID, WCC_SEED), |
| 2727 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID, BCA), | 2727 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID, BCA), |
| 2728 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID, BCA), | 2728 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID, BCA), |
| 2729 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID, BCA), | 2729 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID, BCA), |
| @@ -414,16 +414,16 @@ static ssize_t vmclock_miscdev_read(struct file *fp, char __user *buf, · 413 unmodified lines | |||
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | static const struct file_operations vmclock_miscdev_fops = { | 416 | static const struct file_operations vmclock_miscdev_fops = { |
| 417 | .owner = THIS_MODULE, | ||
| 417 | .mmap = vmclock_miscdev_mmap, | 418 | .mmap = vmclock_miscdev_mmap, |
| 418 | .read = vmclock_miscdev_read, | 419 | .read = vmclock_miscdev_read, |
| 419 | }; | 420 | }; |
| 420 | 421 | ||
| 421 | /* module operations */ | 422 | /* module operations */ |
| 422 | 423 | ||
| 423 | static void vmclock_remove(struct platform_device *pdev) | 424 | static void vmclock_remove(void *data) |
| 424 | { | 425 | { |
| 425 | struct device *dev = &pdev->dev; | 426 | struct vmclock_state *st = data; |
| 426 | struct vmclock_state *st = dev_get_drvdata(dev); | ||
| 427 | 427 | ||
| 428 | if (st->ptp_clock) | 428 | if (st->ptp_clock) |
| 429 | ptp_clock_unregister(st->ptp_clock); | 429 | ptp_clock_unregister(st->ptp_clock); |
| @@ -506,14 +506,13 @@ static int vmclock_probe(struct platform_device *pdev) · 76 unmodified lines | |||
| 506 | 506 | ||
| 507 | if (ret) { | 507 | if (ret) { |
| 508 | dev_info(dev, "Failed to obtain physical address: %d\n", ret); | 508 | dev_info(dev, "Failed to obtain physical address: %d\n", ret); |
| 509 | goto out; | 509 | return ret; |
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | if (resource_size(&st->res) < VMCLOCK_MIN_SIZE) { | 512 | if (resource_size(&st->res) < VMCLOCK_MIN_SIZE) { |
| 513 | dev_info(dev, "Region too small (0x%llx)\n", | 513 | dev_info(dev, "Region too small (0x%llx)\n", |
| 514 | resource_size(&st->res)); | 514 | resource_size(&st->res)); |
| 515 | ret = -EINVAL; | 515 | return -EINVAL; |
| 516 | goto out; | ||
| 517 | } | 516 | } |
| 518 | st->clk = devm_memremap(dev, st->res.start, resource_size(&st->res), | 517 | st->clk = devm_memremap(dev, st->res.start, resource_size(&st->res), |
| 519 | MEMREMAP_WB | MEMREMAP_DEC); | 518 | MEMREMAP_WB | MEMREMAP_DEC); |
| @@ -521,31 +520,34 @@ static int vmclock_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 521 | ret = PTR_ERR(st->clk); | 520 | ret = PTR_ERR(st->clk); |
| 522 | dev_info(dev, "failed to map shared memory\n"); | 521 | dev_info(dev, "failed to map shared memory\n"); |
| 523 | st->clk = NULL; | 522 | st->clk = NULL; |
| 524 | goto out; | 523 | return ret; |
| 525 | } | 524 | } |
| 526 | 525 | ||
| 527 | if (le32_to_cpu(st->clk->magic) != VMCLOCK_MAGIC || | 526 | if (le32_to_cpu(st->clk->magic) != VMCLOCK_MAGIC || |
| 528 | le32_to_cpu(st->clk->size) > resource_size(&st->res) || | 527 | le32_to_cpu(st->clk->size) > resource_size(&st->res) || |
| 529 | le16_to_cpu(st->clk->version) != 1) { | 528 | le16_to_cpu(st->clk->version) != 1) { |
| 530 | dev_info(dev, "vmclock magic fields invalid\n"); | 529 | dev_info(dev, "vmclock magic fields invalid\n"); |
| 531 | ret = -EINVAL; | 530 | return -EINVAL; |
| 532 | goto out; | ||
| 533 | } | 531 | } |
| 534 | 532 | ||
| 535 | ret = ida_alloc(&vmclock_ida, GFP_KERNEL); | 533 | ret = ida_alloc(&vmclock_ida, GFP_KERNEL); |
| 536 | if (ret < 0) | 534 | if (ret < 0) |
| 537 | goto out; | 535 | return ret; |
| 538 | 536 | ||
| 539 | st->index = ret; | 537 | st->index = ret; |
| 540 | ret = devm_add_action_or_reset(&pdev->dev, vmclock_put_idx, st); | 538 | ret = devm_add_action_or_reset(&pdev->dev, vmclock_put_idx, st); |
| 541 | if (ret) | 539 | if (ret) |
| 542 | goto out; | 540 | return ret; |
| 543 | 541 | ||
| 544 | st->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "vmclock%d", st->index); | 542 | st->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "vmclock%d", st->index); |
| 545 | if (!st->name) { | 543 | if (!st->name) |
| 546 | ret = -ENOMEM; | 544 | return -ENOMEM; |
| 547 | goto out; | 545 | |
| 548 | } | 546 | st->miscdev.minor = MISC_DYNAMIC_MINOR; |
| 547 | |||
| 548 | ret = devm_add_action_or_reset(&pdev->dev, vmclock_remove, st); | ||
| 549 | if (ret) | ||
| 550 | return ret; | ||
| 549 | 551 | ||
| 550 | /* | 552 | /* |
| 551 | * If the structure is big enough, it can be mapped to userspace. | 553 | * If the structure is big enough, it can be mapped to userspace. |
| @@ -554,13 +556,12 @@ static int vmclock_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 554 | * cross that bridge if/when we come to it. | 556 | * cross that bridge if/when we come to it. |
| 555 | */ | 557 | */ |
| 556 | if (le32_to_cpu(st->clk->size) >= PAGE_SIZE) { | 558 | if (le32_to_cpu(st->clk->size) >= PAGE_SIZE) { |
| 557 | st->miscdev.minor = MISC_DYNAMIC_MINOR; | ||
| 558 | st->miscdev.fops = &vmclock_miscdev_fops; | 559 | st->miscdev.fops = &vmclock_miscdev_fops; |
| 559 | st->miscdev.name = st->name; | 560 | st->miscdev.name = st->name; |
| 560 | 561 | ||
| 561 | ret = misc_register(&st->miscdev); | 562 | ret = misc_register(&st->miscdev); |
| 562 | if (ret) | 563 | if (ret) |
| 563 | goto out; | 564 | return ret; |
| 564 | } | 565 | } |
| 565 | 566 | ||
| 566 | /* If there is valid clock information, register a PTP clock */ | 567 | /* If there is valid clock information, register a PTP clock */ |
| @@ -570,16 +571,14 @@ static int vmclock_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 570 | if (IS_ERR(st->ptp_clock)) { | 571 | if (IS_ERR(st->ptp_clock)) { |
| 571 | ret = PTR_ERR(st->ptp_clock); | 572 | ret = PTR_ERR(st->ptp_clock); |
| 572 | st->ptp_clock = NULL; | 573 | st->ptp_clock = NULL; |
| 573 | vmclock_remove(pdev); | 574 | return ret; |
| 574 | goto out; | ||
| 575 | } | 575 | } |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | if (!st->miscdev.minor && !st->ptp_clock) { | 578 | if (!st->miscdev.minor && !st->ptp_clock) { |
| 579 | /* Neither miscdev nor PTP registered */ | 579 | /* Neither miscdev nor PTP registered */ |
| 580 | dev_info(dev, "vmclock: Neither miscdev nor PTP available; not registering\n"); | 580 | dev_info(dev, "vmclock: Neither miscdev nor PTP available; not registering\n"); |
| 581 | ret = -ENODEV; | 581 | return -ENODEV; |
| 582 | goto out; | ||
| 583 | } | 582 | } |
| 584 | 583 | ||
| 585 | dev_info(dev, "%s: registered %s%s%s\n", st->name, | 584 | dev_info(dev, "%s: registered %s%s%s\n", st->name, |
| @@ -587,10 +586,7 @@ static int vmclock_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 587 | (st->miscdev.minor && st->ptp_clock) ? ", " : "", | 586 | (st->miscdev.minor && st->ptp_clock) ? ", " : "", |
| 588 | st->ptp_clock ? "PTP" : ""); | 587 | st->ptp_clock ? "PTP" : ""); |
| 589 | 588 | ||
| 590 | dev_set_drvdata(dev, st); | 589 | return 0; |
| 591 | |||
| 592 | out: | ||
| 593 | return ret; | ||
| 594 | } | 590 | } |
| 595 | 591 | ||
| 596 | static const struct acpi_device_id vmclock_acpi_ids[] = { | 592 | static const struct acpi_device_id vmclock_acpi_ids[] = { |
| @@ -601,7 +597,6 @@ MODULE_DEVICE_TABLE(acpi, vmclock_acpi_ids); · 4 unmodified lines | |||
| 601 | 597 | ||
| 602 | static struct platform_driver vmclock_platform_driver = { | 598 | static struct platform_driver vmclock_platform_driver = { |
| 603 | .probe = vmclock_probe, | 599 | .probe = vmclock_probe, |
| 604 | .remove = vmclock_remove, | ||
| 605 | .driver = { | 600 | .driver = { |
| 606 | .name = "vmclock", | 601 | .name = "vmclock", |
| 607 | .acpi_match_table = vmclock_acpi_ids, | 602 | .acpi_match_table = vmclock_acpi_ids, |
| @@ -7050,14 +7050,16 @@ int qeth_open(struct net_device *dev) · 7049 unmodified lines | |||
| 7050 | card->data.state = CH_STATE_UP; | 7050 | card->data.state = CH_STATE_UP; |
| 7051 | netif_tx_start_all_queues(dev); | 7051 | netif_tx_start_all_queues(dev); |
| 7052 | 7052 | ||
| 7053 | local_bh_disable(); | ||
| 7054 | qeth_for_each_output_queue(card, queue, i) { | 7053 | qeth_for_each_output_queue(card, queue, i) { |
| 7055 | netif_napi_add_tx(dev, &queue->napi, qeth_tx_poll); | 7054 | netif_napi_add_tx(dev, &queue->napi, qeth_tx_poll); |
| 7056 | napi_enable(&queue->napi); | 7055 | napi_enable(&queue->napi); |
| 7057 | napi_schedule(&queue->napi); | ||
| 7058 | } | 7056 | } |
| 7059 | |||
| 7060 | napi_enable(&card->napi); | 7057 | napi_enable(&card->napi); |
| 7058 | |||
| 7059 | local_bh_disable(); | ||
| 7060 | qeth_for_each_output_queue(card, queue, i) { | ||
| 7061 | napi_schedule(&queue->napi); | ||
| 7062 | } | ||
| 7061 | napi_schedule(&card->napi); | 7063 | napi_schedule(&card->napi); |
| 7062 | /* kick-start the NAPI softirq: */ | 7064 | /* kick-start the NAPI softirq: */ |
| 7063 | local_bh_enable(); | 7065 | local_bh_enable(); |
| @@ -2663,6 +2663,12 @@ struct net *dev_net(const struct net_device *dev) · 2662 unmodified lines | |||
| 2663 | return read_pnet(&dev->nd_net); | 2663 | return read_pnet(&dev->nd_net); |
| 2664 | } | 2664 | } |
| 2665 | 2665 | ||
| 2666 | static inline | ||
| 2667 | struct net *dev_net_rcu(const struct net_device *dev) | ||
| 2668 | { | ||
| 2669 | return read_pnet_rcu(&dev->nd_net); | ||
| 2670 | } | ||
| 2671 | |||
| 2666 | static inline | 2672 | static inline |
| 2667 | void dev_net_set(struct net_device *dev, struct net *net) | 2673 | void dev_net_set(struct net_device *dev, struct net *net) |
| 2668 | { | 2674 | { |
| @@ -668,7 +668,7 @@ struct l2cap_conn { · 667 unmodified lines | |||
| 668 | struct l2cap_chan *smp; | 668 | struct l2cap_chan *smp; |
| 669 | 669 | ||
| 670 | struct list_head chan_l; | 670 | struct list_head chan_l; |
| 671 | struct mutex chan_lock; | 671 | struct mutex lock; |
| 672 | struct kref ref; | 672 | struct kref ref; |
| 673 | struct list_head users; | 673 | struct list_head users; |
| 674 | }; | 674 | }; |
| @@ -970,6 +970,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err); · 295 unmodified lines | |||
| 970 | void l2cap_send_conn_req(struct l2cap_chan *chan); | 970 | void l2cap_send_conn_req(struct l2cap_chan *chan); |
| 971 | 971 | ||
| 972 | struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); | 972 | struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); |
| 973 | struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *conn); | ||
| 973 | void l2cap_conn_put(struct l2cap_conn *conn); | 974 | void l2cap_conn_put(struct l2cap_conn *conn); |
| 974 | 975 | ||
| 975 | int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); | 976 | int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); |
| @@ -471,9 +471,12 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, · 470 unmodified lines | |||
| 471 | bool forwarding) | 471 | bool forwarding) |
| 472 | { | 472 | { |
| 473 | const struct rtable *rt = dst_rtable(dst); | 473 | const struct rtable *rt = dst_rtable(dst); |
| 474 | struct net *net = dev_net(dst->dev); | 474 | unsigned int mtu, res; |
| 475 | unsigned int mtu; | 475 | struct net *net; |
| 476 | |||
| 477 | rcu_read_lock(); | ||
| 476 | 478 | ||
| 479 | net = dev_net_rcu(dst->dev); | ||
| 477 | if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || | 480 | if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) || |
| 478 | ip_mtu_locked(dst) || | 481 | ip_mtu_locked(dst) || |
| 479 | !forwarding) { | 482 | !forwarding) { |
| @@ -497,7 +500,11 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, · 17 unmodified lines | |||
| 497 | out: | 500 | out: |
| 498 | mtu = min_t(unsigned int, mtu, IP_MAX_MTU); | 501 | mtu = min_t(unsigned int, mtu, IP_MAX_MTU); |
| 499 | 502 | ||
| 500 | return mtu - lwtunnel_headroom(dst->lwtstate, mtu); | 503 | res = mtu - lwtunnel_headroom(dst->lwtstate, mtu); |
| 504 | |||
| 505 | rcu_read_unlock(); | ||
| 506 | |||
| 507 | return res; | ||
| 501 | } | 508 | } |
| 502 | 509 | ||
| 503 | static inline unsigned int ip_skb_dst_mtu(struct sock *sk, | 510 | static inline unsigned int ip_skb_dst_mtu(struct sock *sk, |
| @@ -198,10 +198,12 @@ struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto) · 197 unmodified lines | |||
| 198 | if (netif_is_l3_slave(dev)) { | 198 | if (netif_is_l3_slave(dev)) { |
| 199 | struct net_device *master; | 199 | struct net_device *master; |
| 200 | 200 | ||
| 201 | rcu_read_lock(); | ||
| 201 | master = netdev_master_upper_dev_get_rcu(dev); | 202 | master = netdev_master_upper_dev_get_rcu(dev); |
| 202 | if (master && master->l3mdev_ops->l3mdev_l3_out) | 203 | if (master && master->l3mdev_ops->l3mdev_l3_out) |
| 203 | skb = master->l3mdev_ops->l3mdev_l3_out(master, sk, | 204 | skb = master->l3mdev_ops->l3mdev_l3_out(master, sk, |
| 204 | skb, proto); | 205 | skb, proto); |
| 206 | rcu_read_unlock(); | ||
| 205 | } | 207 | } |
| 206 | 208 | ||
| 207 | return skb; | 209 | return skb; |
| @@ -398,7 +398,7 @@ static inline struct net *read_pnet(const possible_net_t *pnet) · 397 unmodified lines | |||
| 398 | #endif | 398 | #endif |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | static inline struct net *read_pnet_rcu(possible_net_t *pnet) | 401 | static inline struct net *read_pnet_rcu(const possible_net_t *pnet) |
| 402 | { | 402 | { |
| 403 | #ifdef CONFIG_NET_NS | 403 | #ifdef CONFIG_NET_NS |
| 404 | return rcu_dereference(pnet->net); | 404 | return rcu_dereference(pnet->net); |
| @@ -382,10 +382,15 @@ static inline int inet_iif(const struct sk_buff *skb) · 381 unmodified lines | |||
| 382 | static inline int ip4_dst_hoplimit(const struct dst_entry *dst) | 382 | static inline int ip4_dst_hoplimit(const struct dst_entry *dst) |
| 383 | { | 383 | { |
| 384 | int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); | 384 | int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); |
| 385 | struct net *net = dev_net(dst->dev); | ||
| 386 | 385 | ||
| 387 | if (hoplimit == 0) | 386 | if (hoplimit == 0) { |
| 387 | const struct net *net; | ||
| 388 | |||
| 389 | rcu_read_lock(); | ||
| 390 | net = dev_net_rcu(dst->dev); | ||
| 388 | hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl); | 391 | hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl); |
| 392 | rcu_read_unlock(); | ||
| 393 | } | ||
| 389 | return hoplimit; | 394 | return hoplimit; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| @@ -682,6 +682,7 @@ enum ethtool_link_ext_substate_module { · 681 unmodified lines | |||
| 682 | * @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics | 682 | * @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics |
| 683 | * @ETH_SS_STATS_RMON: names of RMON statistics | 683 | * @ETH_SS_STATS_RMON: names of RMON statistics |
| 684 | * @ETH_SS_STATS_PHY: names of PHY(dev) statistics | 684 | * @ETH_SS_STATS_PHY: names of PHY(dev) statistics |
| 685 | * @ETH_SS_TS_FLAGS: hardware timestamping flags | ||
| 685 | * | 686 | * |
| 686 | * @ETH_SS_COUNT: number of defined string sets | 687 | * @ETH_SS_COUNT: number of defined string sets |
| 687 | */ | 688 | */ |
| @@ -708,6 +709,7 @@ enum ethtool_stringset { · 20 unmodified lines | |||
| 708 | ETH_SS_STATS_ETH_CTRL, | 709 | ETH_SS_STATS_ETH_CTRL, |
| 709 | ETH_SS_STATS_RMON, | 710 | ETH_SS_STATS_RMON, |
| 710 | ETH_SS_STATS_PHY, | 711 | ETH_SS_STATS_PHY, |
| 712 | ETH_SS_TS_FLAGS, | ||
| 711 | 713 | ||
| 712 | /* add new constants above here */ | 714 | /* add new constants above here */ |
| 713 | ETH_SS_COUNT | 715 | ETH_SS_COUNT |
| @@ -685,6 +685,15 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, · 684 unmodified lines | |||
| 685 | break; | 685 | break; |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | if (ax25->ax25_dev) { | ||
| 689 | if (dev == ax25->ax25_dev->dev) { | ||
| 690 | rcu_read_unlock(); | ||
| 691 | break; | ||
| 692 | } | ||
| 693 | netdev_put(ax25->ax25_dev->dev, &ax25->dev_tracker); | ||
| 694 | ax25_dev_put(ax25->ax25_dev); | ||
| 695 | } | ||
| 696 | |||
| 688 | ax25->ax25_dev = ax25_dev_ax25dev(dev); | 697 | ax25->ax25_dev = ax25_dev_ax25dev(dev); |
| 689 | if (!ax25->ax25_dev) { | 698 | if (!ax25->ax25_dev) { |
| 690 | rcu_read_unlock(); | 699 | rcu_read_unlock(); |
| @@ -692,6 +701,8 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, · 1 unmodified line | |||
| 692 | break; | 701 | break; |
| 693 | } | 702 | } |
| 694 | ax25_fillin_cb(ax25, ax25->ax25_dev); | 703 | ax25_fillin_cb(ax25, ax25->ax25_dev); |
| 704 | netdev_hold(dev, &ax25->dev_tracker, GFP_ATOMIC); | ||
| 705 | ax25_dev_hold(ax25->ax25_dev); | ||
| 695 | rcu_read_unlock(); | 706 | rcu_read_unlock(); |
| 696 | break; | 707 | break; |
| 697 | 708 | ||
| @@ -113,8 +113,6 @@ static void · 112 unmodified lines | |||
| 113 | batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) | 113 | batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) |
| 114 | { | 114 | { |
| 115 | ewma_throughput_init(&hardif_neigh->bat_v.throughput); | 115 | ewma_throughput_init(&hardif_neigh->bat_v.throughput); |
| 116 | INIT_WORK(&hardif_neigh->bat_v.metric_work, | ||
| 117 | batadv_v_elp_throughput_metric_update); | ||
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /** | 118 | /** |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/if_ether.h> | 18 | #include <linux/if_ether.h> |
| 19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
| 20 | #include <linux/kref.h> | 20 | #include <linux/kref.h> |
| 21 | #include <linux/list.h> | ||
| 21 | #include <linux/minmax.h> | 22 | #include <linux/minmax.h> |
| 22 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
| 23 | #include <linux/nl80211.h> | 24 | #include <linux/nl80211.h> |
| @@ -26,6 +27,7 @@ · 2 unmodified lines | |||
| 26 | #include <linux/rcupdate.h> | 27 | #include <linux/rcupdate.h> |
| 27 | #include <linux/rtnetlink.h> | 28 | #include <linux/rtnetlink.h> |
| 28 | #include <linux/skbuff.h> | 29 | #include <linux/skbuff.h> |
| 30 | #include <linux/slab.h> | ||
| 29 | #include <linux/stddef.h> | 31 | #include <linux/stddef.h> |
| 30 | #include <linux/string.h> | 32 | #include <linux/string.h> |
| 31 | #include <linux/types.h> | 33 | #include <linux/types.h> |
| @@ -41,6 +43,18 @@ · 9 unmodified lines | |||
| 41 | #include "routing.h" | 43 | #include "routing.h" |
| 42 | #include "send.h" | 44 | #include "send.h" |
| 43 | 45 | ||
| 46 | /** | ||
| 47 | * struct batadv_v_metric_queue_entry - list of hardif neighbors which require | ||
| 48 | * and metric update | ||
| 49 | */ | ||
| 50 | struct batadv_v_metric_queue_entry { | ||
| 51 | /** @hardif_neigh: hardif neighbor scheduled for metric update */ | ||
| 52 | struct batadv_hardif_neigh_node *hardif_neigh; | ||
| 53 | |||
| 54 | /** @list: list node for metric_queue */ | ||
| 55 | struct list_head list; | ||
| 56 | }; | ||
| 57 | |||
| 44 | /** | 58 | /** |
| 45 | * batadv_v_elp_start_timer() - restart timer for ELP periodic work | 59 | * batadv_v_elp_start_timer() - restart timer for ELP periodic work |
| 46 | * @hard_iface: the interface for which the timer has to be reset | 60 | * @hard_iface: the interface for which the timer has to be reset |
| @@ -59,25 +73,36 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) · 12 unmodified lines | |||
| 59 | /** | 73 | /** |
| 60 | * batadv_v_elp_get_throughput() - get the throughput towards a neighbour | 74 | * batadv_v_elp_get_throughput() - get the throughput towards a neighbour |
| 61 | * @neigh: the neighbour for which the throughput has to be obtained | 75 | * @neigh: the neighbour for which the throughput has to be obtained |
| 76 | * @pthroughput: calculated throughput towards the given neighbour in multiples | ||
| 77 | * of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). | ||
| 62 | * | 78 | * |
| 63 | * Return: The throughput towards the given neighbour in multiples of 100kpbs | 79 | * Return: true when value behind @pthroughput was set |
| 64 | * (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). | ||
| 65 | */ | 80 | */ |
| 66 | static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) | 81 | static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh, |
| 82 | u32 *pthroughput) | ||
| 67 | { | 83 | { |
| 68 | struct batadv_hard_iface *hard_iface = neigh->if_incoming; | 84 | struct batadv_hard_iface *hard_iface = neigh->if_incoming; |
| 85 | struct net_device *soft_iface = hard_iface->soft_iface; | ||
| 69 | struct ethtool_link_ksettings link_settings; | 86 | struct ethtool_link_ksettings link_settings; |
| 70 | struct net_device *real_netdev; | 87 | struct net_device *real_netdev; |
| 71 | struct station_info sinfo; | 88 | struct station_info sinfo; |
| 72 | u32 throughput; | 89 | u32 throughput; |
| 73 | int ret; | 90 | int ret; |
| 74 | 91 | ||
| 92 | /* don't query throughput when no longer associated with any | ||
| 93 | * batman-adv interface | ||
| 94 | */ | ||
| 95 | if (!soft_iface) | ||
| 96 | return false; | ||
| 97 | |||
| 75 | /* if the user specified a customised value for this interface, then | 98 | /* if the user specified a customised value for this interface, then |
| 76 | * return it directly | 99 | * return it directly |
| 77 | */ | 100 | */ |
| 78 | throughput = atomic_read(&hard_iface->bat_v.throughput_override); | 101 | throughput = atomic_read(&hard_iface->bat_v.throughput_override); |
| 79 | if (throughput != 0) | 102 | if (throughput != 0) { |
| 80 | return throughput; | 103 | *pthroughput = throughput; |
| 104 | return true; | ||
| 105 | } | ||
| 81 | 106 | ||
| 82 | /* if this is a wireless device, then ask its throughput through | 107 | /* if this is a wireless device, then ask its throughput through |
| 83 | * cfg80211 API | 108 | * cfg80211 API |
| @@ -104,27 +129,39 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) · 20 unmodified lines | |||
| 104 | * possible to delete this neighbor. For now set | 129 | * possible to delete this neighbor. For now set |
| 105 | * the throughput metric to 0. | 130 | * the throughput metric to 0. |
| 106 | */ | 131 | */ |
| 107 | return 0; | 132 | *pthroughput = 0; |
| 133 | return true; | ||
| 108 | } | 134 | } |
| 109 | if (ret) | 135 | if (ret) |
| 110 | goto default_throughput; | 136 | goto default_throughput; |
| 111 | 137 | ||
| 112 | if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) | 138 | if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) { |
| 113 | return sinfo.expected_throughput / 100; | 139 | *pthroughput = sinfo.expected_throughput / 100; |
| 140 | return true; | ||
| 141 | } | ||
| 114 | 142 | ||
| 115 | /* try to estimate the expected throughput based on reported tx | 143 | /* try to estimate the expected throughput based on reported tx |
| 116 | * rates | 144 | * rates |
| 117 | */ | 145 | */ |
| 118 | if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) | 146 | if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) { |
| 119 | return cfg80211_calculate_bitrate(&sinfo.txrate) / 3; | 147 | *pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3; |
| 148 | return true; | ||
| 149 | } | ||
| 120 | 150 | ||
| 121 | goto default_throughput; | 151 | goto default_throughput; |
| 122 | } | 152 | } |
| 123 | 153 | ||
| 154 | /* only use rtnl_trylock because the elp worker will be cancelled while | ||
| 155 | * the rntl_lock is held. the cancel_delayed_work_sync() would otherwise | ||
| 156 | * wait forever when the elp work_item was started and it is then also | ||
| 157 | * trying to rtnl_lock | ||
| 158 | */ | ||
| 159 | if (!rtnl_trylock()) | ||
| 160 | return false; | ||
| 161 | |||
| 124 | /* if not a wifi interface, check if this device provides data via | 162 | /* if not a wifi interface, check if this device provides data via |
| 125 | * ethtool (e.g. an Ethernet adapter) | 163 | * ethtool (e.g. an Ethernet adapter) |
| 126 | */ | 164 | */ |
| 127 | rtnl_lock(); | ||
| 128 | ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); | 165 | ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); |
| 129 | rtnl_unlock(); | 166 | rtnl_unlock(); |
| 130 | if (ret == 0) { | 167 | if (ret == 0) { |
| @@ -135,13 +172,15 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) · 4 unmodified lines | |||
| 135 | hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; | 172 | hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; |
| 136 | 173 | ||
| 137 | throughput = link_settings.base.speed; | 174 | throughput = link_settings.base.speed; |
| 138 | if (throughput && throughput != SPEED_UNKNOWN) | 175 | if (throughput && throughput != SPEED_UNKNOWN) { |
| 139 | return throughput * 10; | 176 | *pthroughput = throughput * 10; |
| 177 | return true; | ||
| 178 | } | ||
| 140 | } | 179 | } |
| 141 | 180 | ||
| 142 | default_throughput: | 181 | default_throughput: |
| 143 | if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) { | 182 | if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) { |
| 144 | batadv_info(hard_iface->soft_iface, | 183 | batadv_info(soft_iface, |
| 145 | "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n", | 184 | "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n", |
| 146 | hard_iface->net_dev->name, | 185 | hard_iface->net_dev->name, |
| 147 | BATADV_THROUGHPUT_DEFAULT_VALUE / 10, | 186 | BATADV_THROUGHPUT_DEFAULT_VALUE / 10, |
| @@ -150,31 +189,26 @@ default_throughput: · 2 unmodified lines | |||
| 150 | } | 189 | } |
| 151 | 190 | ||
| 152 | /* if none of the above cases apply, return the base_throughput */ | 191 | /* if none of the above cases apply, return the base_throughput */ |
| 153 | return BATADV_THROUGHPUT_DEFAULT_VALUE; | 192 | *pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE; |
| 193 | return true; | ||
| 154 | } | 194 | } |
| 155 | 195 | ||
| 156 | /** | 196 | /** |
| 157 | * batadv_v_elp_throughput_metric_update() - worker updating the throughput | 197 | * batadv_v_elp_throughput_metric_update() - worker updating the throughput |
| 158 | * metric of a single hop neighbour | 198 | * metric of a single hop neighbour |
| 159 | * @work: the work queue item | 199 | * @neigh: the neighbour to probe |
| 160 | */ | 200 | */ |
| 161 | void batadv_v_elp_throughput_metric_update(struct work_struct *work) | 201 | static void |
| 202 | batadv_v_elp_throughput_metric_update(struct batadv_hardif_neigh_node *neigh) | ||
| 162 | { | 203 | { |
| 163 | struct batadv_hardif_neigh_node_bat_v *neigh_bat_v; | 204 | u32 throughput; |
| 164 | struct batadv_hardif_neigh_node *neigh; | 205 | bool valid; |
| 165 | |||
| 166 | neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, | ||
| 167 | metric_work); | ||
| 168 | neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, | ||
| 169 | bat_v); | ||
| 170 | 206 | ||
| 171 | ewma_throughput_add(&neigh->bat_v.throughput, | 207 | valid = batadv_v_elp_get_throughput(neigh, &throughput); |
| 172 | batadv_v_elp_get_throughput(neigh)); | 208 | if (!valid) |
| 209 | return; | ||
| 173 | 210 | ||
| 174 | /* decrement refcounter to balance increment performed before scheduling | 211 | ewma_throughput_add(&neigh->bat_v.throughput, throughput); |
| 175 | * this task | ||
| 176 | */ | ||
| 177 | batadv_hardif_neigh_put(neigh); | ||
| 178 | } | 212 | } |
| 179 | 213 | ||
| 180 | /** | 214 | /** |
| @@ -248,14 +282,16 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) · 67 unmodified lines | |||
| 248 | */ | 282 | */ |
| 249 | static void batadv_v_elp_periodic_work(struct work_struct *work) | 283 | static void batadv_v_elp_periodic_work(struct work_struct *work) |
| 250 | { | 284 | { |
| 285 | struct batadv_v_metric_queue_entry *metric_entry; | ||
| 286 | struct batadv_v_metric_queue_entry *metric_safe; | ||
| 251 | struct batadv_hardif_neigh_node *hardif_neigh; | 287 | struct batadv_hardif_neigh_node *hardif_neigh; |
| 252 | struct batadv_hard_iface *hard_iface; | 288 | struct batadv_hard_iface *hard_iface; |
| 253 | struct batadv_hard_iface_bat_v *bat_v; | 289 | struct batadv_hard_iface_bat_v *bat_v; |
| 254 | struct batadv_elp_packet *elp_packet; | 290 | struct batadv_elp_packet *elp_packet; |
| 291 | struct list_head metric_queue; | ||
| 255 | struct batadv_priv *bat_priv; | 292 | struct batadv_priv *bat_priv; |
| 256 | struct sk_buff *skb; | 293 | struct sk_buff *skb; |
| 257 | u32 elp_interval; | 294 | u32 elp_interval; |
| 258 | bool ret; | ||
| 259 | 295 | ||
| 260 | bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work); | 296 | bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work); |
| 261 | hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v); | 297 | hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v); |
| @@ -291,6 +327,8 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) · 29 unmodified lines | |||
| 291 | 327 | ||
| 292 | atomic_inc(&hard_iface->bat_v.elp_seqno); | 328 | atomic_inc(&hard_iface->bat_v.elp_seqno); |
| 293 | 329 | ||
| 330 | INIT_LIST_HEAD(&metric_queue); | ||
| 331 | |||
| 294 | /* The throughput metric is updated on each sent packet. This way, if a | 332 | /* The throughput metric is updated on each sent packet. This way, if a |
| 295 | * node is dead and no longer sends packets, batman-adv is still able to | 333 | * node is dead and no longer sends packets, batman-adv is still able to |
| 296 | * react timely to its death. | 334 | * react timely to its death. |
| @@ -315,16 +353,28 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) · 18 unmodified lines | |||
| 315 | 353 | ||
| 316 | /* Reading the estimated throughput from cfg80211 is a task that | 354 | /* Reading the estimated throughput from cfg80211 is a task that |
| 317 | * may sleep and that is not allowed in an rcu protected | 355 | * may sleep and that is not allowed in an rcu protected |
| 318 | * context. Therefore schedule a task for that. | 356 | * context. Therefore add it to metric_queue and process it |
| 357 | * outside rcu protected context. | ||
| 319 | */ | 358 | */ |
| 320 | ret = queue_work(batadv_event_workqueue, | 359 | metric_entry = kzalloc(sizeof(*metric_entry), GFP_ATOMIC); |
| 321 | &hardif_neigh->bat_v.metric_work); | 360 | if (!metric_entry) { |
| 322 | |||
| 323 | if (!ret) | ||
| 324 | batadv_hardif_neigh_put(hardif_neigh); | 361 | batadv_hardif_neigh_put(hardif_neigh); |
| 362 | continue; | ||
| 363 | } | ||
| 364 | |||
| 365 | metric_entry->hardif_neigh = hardif_neigh; | ||
| 366 | list_add(&metric_entry->list, &metric_queue); | ||
| 325 | } | 367 | } |
| 326 | rcu_read_unlock(); | 368 | rcu_read_unlock(); |
| 327 | 369 | ||
| 370 | list_for_each_entry_safe(metric_entry, metric_safe, &metric_queue, list) { | ||
| 371 | batadv_v_elp_throughput_metric_update(metric_entry->hardif_neigh); | ||
| 372 | |||
| 373 | batadv_hardif_neigh_put(metric_entry->hardif_neigh); | ||
| 374 | list_del(&metric_entry->list); | ||
| 375 | kfree(metric_entry); | ||
| 376 | } | ||
| 377 | |||
| 328 | restart_timer: | 378 | restart_timer: |
| 329 | batadv_v_elp_start_timer(hard_iface); | 379 | batadv_v_elp_start_timer(hard_iface); |
| 330 | out: | 380 | out: |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | #include "main.h" | 10 | #include "main.h" |
| 11 | 11 | ||
| 12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
| 13 | #include <linux/workqueue.h> | ||
| 14 | 13 | ||
| 15 | int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface); | 14 | int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface); |
| 16 | void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface); | 15 | void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface); |
| @@ -19,6 +18,5 @@ void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface, · 2 unmodified lines | |||
| 19 | void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface); | 18 | void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface); |
| 20 | int batadv_v_elp_packet_recv(struct sk_buff *skb, | 19 | int batadv_v_elp_packet_recv(struct sk_buff *skb, |
| 21 | struct batadv_hard_iface *if_incoming); | 20 | struct batadv_hard_iface *if_incoming); |
| 22 | void batadv_v_elp_throughput_metric_update(struct work_struct *work); | ||
| 23 | 21 | ||
| 24 | #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */ | 22 | #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */ |
| @@ -3937,23 +3937,21 @@ static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, · 3936 unmodified lines | |||
| 3937 | struct batadv_tvlv_tt_change *tt_change; | 3937 | struct batadv_tvlv_tt_change *tt_change; |
| 3938 | struct batadv_tvlv_tt_data *tt_data; | 3938 | struct batadv_tvlv_tt_data *tt_data; |
| 3939 | u16 num_entries, num_vlan; | 3939 | u16 num_entries, num_vlan; |
| 3940 | size_t flex_size; | 3940 | size_t tt_data_sz; |
| 3941 | 3941 | ||
| 3942 | if (tvlv_value_len < sizeof(*tt_data)) | 3942 | if (tvlv_value_len < sizeof(*tt_data)) |
| 3943 | return; | 3943 | return; |
| 3944 | 3944 | ||
| 3945 | tt_data = tvlv_value; | 3945 | tt_data = tvlv_value; |
| 3946 | tvlv_value_len -= sizeof(*tt_data); | ||
| 3947 | |||
| 3948 | num_vlan = ntohs(tt_data->num_vlan); | 3946 | num_vlan = ntohs(tt_data->num_vlan); |
| 3949 | 3947 | ||
| 3950 | flex_size = flex_array_size(tt_data, vlan_data, num_vlan); | 3948 | tt_data_sz = struct_size(tt_data, vlan_data, num_vlan); |
| 3951 | if (tvlv_value_len < flex_size) | 3949 | if (tvlv_value_len < tt_data_sz) |
| 3952 | return; | 3950 | return; |
| 3953 | 3951 | ||
| 3954 | tt_change = (struct batadv_tvlv_tt_change *)((void *)tt_data | 3952 | tt_change = (struct batadv_tvlv_tt_change *)((void *)tt_data |
| 3955 | + flex_size); | 3953 | + tt_data_sz); |
| 3956 | tvlv_value_len -= flex_size; | 3954 | tvlv_value_len -= tt_data_sz; |
| 3957 | 3955 | ||
| 3958 | num_entries = batadv_tt_entries(tvlv_value_len); | 3956 | num_entries = batadv_tt_entries(tvlv_value_len); |
| 3959 | 3957 | ||
| @@ -596,9 +596,6 @@ struct batadv_hardif_neigh_node_bat_v { · 595 unmodified lines | |||
| 596 | * neighbor | 596 | * neighbor |
| 597 | */ | 597 | */ |
| 598 | unsigned long last_unicast_tx; | 598 | unsigned long last_unicast_tx; |
| 599 | |||
| 600 | /** @metric_work: work queue callback item for metric update */ | ||
| 601 | struct work_struct metric_work; | ||
| 602 | }; | 599 | }; |
| 603 | 600 | ||
| 604 | /** | 601 | /** |
| @@ -119,7 +119,6 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, · 118 unmodified lines | |||
| 119 | { | 119 | { |
| 120 | struct l2cap_chan *c; | 120 | struct l2cap_chan *c; |
| 121 | 121 | ||
| 122 | mutex_lock(&conn->chan_lock); | ||
| 123 | c = __l2cap_get_chan_by_scid(conn, cid); | 122 | c = __l2cap_get_chan_by_scid(conn, cid); |
| 124 | if (c) { | 123 | if (c) { |
| 125 | /* Only lock if chan reference is not 0 */ | 124 | /* Only lock if chan reference is not 0 */ |
| @@ -127,7 +126,6 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, · 1 unmodified line | |||
| 127 | if (c) | 126 | if (c) |
| 128 | l2cap_chan_lock(c); | 127 | l2cap_chan_lock(c); |
| 129 | } | 128 | } |
| 130 | mutex_unlock(&conn->chan_lock); | ||
| 131 | 129 | ||
| 132 | return c; | 130 | return c; |
| 133 | } | 131 | } |
| @@ -140,7 +138,6 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, · 6 unmodified lines | |||
| 140 | { | 138 | { |
| 141 | struct l2cap_chan *c; | 139 | struct l2cap_chan *c; |
| 142 | 140 | ||
| 143 | mutex_lock(&conn->chan_lock); | ||
| 144 | c = __l2cap_get_chan_by_dcid(conn, cid); | 141 | c = __l2cap_get_chan_by_dcid(conn, cid); |
| 145 | if (c) { | 142 | if (c) { |
| 146 | /* Only lock if chan reference is not 0 */ | 143 | /* Only lock if chan reference is not 0 */ |
| @@ -148,7 +145,6 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, · 1 unmodified line | |||
| 148 | if (c) | 145 | if (c) |
| 149 | l2cap_chan_lock(c); | 146 | l2cap_chan_lock(c); |
| 150 | } | 147 | } |
| 151 | mutex_unlock(&conn->chan_lock); | ||
| 152 | 148 | ||
| 153 | return c; | 149 | return c; |
| 154 | } | 150 | } |
| @@ -418,7 +414,7 @@ static void l2cap_chan_timeout(struct work_struct *work) · 263 unmodified lines | |||
| 418 | if (!conn) | 414 | if (!conn) |
| 419 | return; | 415 | return; |
| 420 | 416 | ||
| 421 | mutex_lock(&conn->chan_lock); | 417 | mutex_lock(&conn->lock); |
| 422 | /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling | 418 | /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling |
| 423 | * this work. No need to call l2cap_chan_hold(chan) here again. | 419 | * this work. No need to call l2cap_chan_hold(chan) here again. |
| 424 | */ | 420 | */ |
| @@ -439,7 +435,7 @@ static void l2cap_chan_timeout(struct work_struct *work) · 14 unmodified lines | |||
| 439 | l2cap_chan_unlock(chan); | 435 | l2cap_chan_unlock(chan); |
| 440 | l2cap_chan_put(chan); | 436 | l2cap_chan_put(chan); |
| 441 | 437 | ||
| 442 | mutex_unlock(&conn->chan_lock); | 438 | mutex_unlock(&conn->lock); |
| 443 | } | 439 | } |
| 444 | 440 | ||
| 445 | struct l2cap_chan *l2cap_chan_create(void) | 441 | struct l2cap_chan *l2cap_chan_create(void) |
| @@ -641,9 +637,9 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) · 195 unmodified lines | |||
| 641 | 637 | ||
| 642 | void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 638 | void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
| 643 | { | 639 | { |
| 644 | mutex_lock(&conn->chan_lock); | 640 | mutex_lock(&conn->lock); |
| 645 | __l2cap_chan_add(conn, chan); | 641 | __l2cap_chan_add(conn, chan); |
| 646 | mutex_unlock(&conn->chan_lock); | 642 | mutex_unlock(&conn->lock); |
| 647 | } | 643 | } |
| 648 | 644 | ||
| 649 | void l2cap_chan_del(struct l2cap_chan *chan, int err) | 645 | void l2cap_chan_del(struct l2cap_chan *chan, int err) |
| @@ -731,9 +727,9 @@ void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func, · 81 unmodified lines | |||
| 731 | if (!conn) | 727 | if (!conn) |
| 732 | return; | 728 | return; |
| 733 | 729 | ||
| 734 | mutex_lock(&conn->chan_lock); | 730 | mutex_lock(&conn->lock); |
| 735 | __l2cap_chan_list(conn, func, data); | 731 | __l2cap_chan_list(conn, func, data); |
| 736 | mutex_unlock(&conn->chan_lock); | 732 | mutex_unlock(&conn->lock); |
| 737 | } | 733 | } |
| 738 | 734 | ||
| 739 | EXPORT_SYMBOL_GPL(l2cap_chan_list); | 735 | EXPORT_SYMBOL_GPL(l2cap_chan_list); |
| @@ -745,7 +741,7 @@ static void l2cap_conn_update_id_addr(struct work_struct *work) · 5 unmodified lines | |||
| 745 | struct hci_conn *hcon = conn->hcon; | 741 | struct hci_conn *hcon = conn->hcon; |
| 746 | struct l2cap_chan *chan; | 742 | struct l2cap_chan *chan; |
| 747 | 743 | ||
| 748 | mutex_lock(&conn->chan_lock); | 744 | mutex_lock(&conn->lock); |
| 749 | 745 | ||
| 750 | list_for_each_entry(chan, &conn->chan_l, list) { | 746 | list_for_each_entry(chan, &conn->chan_l, list) { |
| 751 | l2cap_chan_lock(chan); | 747 | l2cap_chan_lock(chan); |
| @@ -754,7 +750,7 @@ static void l2cap_conn_update_id_addr(struct work_struct *work) · 2 unmodified lines | |||
| 754 | l2cap_chan_unlock(chan); | 750 | l2cap_chan_unlock(chan); |
| 755 | } | 751 | } |
| 756 | 752 | ||
| 757 | mutex_unlock(&conn->chan_lock); | 753 | mutex_unlock(&conn->lock); |
| 758 | } | 754 | } |
| 759 | 755 | ||
| 760 | static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) | 756 | static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) |
| @@ -948,6 +944,16 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn) · 187 unmodified lines | |||
| 948 | return id; | 944 | return id; |
| 949 | } | 945 | } |
| 950 | 946 | ||
| 947 | static void l2cap_send_acl(struct l2cap_conn *conn, struct sk_buff *skb, | ||
| 948 | u8 flags) | ||
| 949 | { | ||
| 950 | /* Check if the hcon still valid before attempting to send */ | ||
| 951 | if (hci_conn_valid(conn->hcon->hdev, conn->hcon)) | ||
| 952 | hci_send_acl(conn->hchan, skb, flags); | ||
| 953 | else | ||
| 954 | kfree_skb(skb); | ||
| 955 | } | ||
| 956 | |||
| 951 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | 957 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, |
| 952 | void *data) | 958 | void *data) |
| 953 | { | 959 | { |
| @@ -970,7 +976,7 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, · 16 unmodified lines | |||
| 970 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; | 976 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; |
| 971 | skb->priority = HCI_PRIO_MAX; | 977 | skb->priority = HCI_PRIO_MAX; |
| 972 | 978 | ||
| 973 | hci_send_acl(conn->hchan, skb, flags); | 979 | l2cap_send_acl(conn, skb, flags); |
| 974 | } | 980 | } |
| 975 | 981 | ||
| 976 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | 982 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) |
| @@ -1497,8 +1503,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn) · 520 unmodified lines | |||
| 1497 | 1503 | ||
| 1498 | BT_DBG("conn %p", conn); | 1504 | BT_DBG("conn %p", conn); |
| 1499 | 1505 | ||
| 1500 | mutex_lock(&conn->chan_lock); | ||
| 1501 | |||
| 1502 | list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { | 1506 | list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { |
| 1503 | l2cap_chan_lock(chan); | 1507 | l2cap_chan_lock(chan); |
| 1504 | 1508 | ||
| @@ -1567,8 +1571,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn) · 62 unmodified lines | |||
| 1567 | 1571 | ||
| 1568 | l2cap_chan_unlock(chan); | 1572 | l2cap_chan_unlock(chan); |
| 1569 | } | 1573 | } |
| 1570 | |||
| 1571 | mutex_unlock(&conn->chan_lock); | ||
| 1572 | } | 1574 | } |
| 1573 | 1575 | ||
| 1574 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 1576 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
| @@ -1614,7 +1616,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) · 39 unmodified lines | |||
| 1614 | if (hcon->type == ACL_LINK) | 1616 | if (hcon->type == ACL_LINK) |
| 1615 | l2cap_request_info(conn); | 1617 | l2cap_request_info(conn); |
| 1616 | 1618 | ||
| 1617 | mutex_lock(&conn->chan_lock); | 1619 | mutex_lock(&conn->lock); |
| 1618 | 1620 | ||
| 1619 | list_for_each_entry(chan, &conn->chan_l, list) { | 1621 | list_for_each_entry(chan, &conn->chan_l, list) { |
| 1620 | 1622 | ||
| @@ -1632,7 +1634,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) · 11 unmodified lines | |||
| 1632 | l2cap_chan_unlock(chan); | 1634 | l2cap_chan_unlock(chan); |
| 1633 | } | 1635 | } |
| 1634 | 1636 | ||
| 1635 | mutex_unlock(&conn->chan_lock); | 1637 | mutex_unlock(&conn->lock); |
| 1636 | 1638 | ||
| 1637 | if (hcon->type == LE_LINK) | 1639 | if (hcon->type == LE_LINK) |
| 1638 | l2cap_le_conn_ready(conn); | 1640 | l2cap_le_conn_ready(conn); |
| @@ -1647,14 +1649,10 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) · 8 unmodified lines | |||
| 1647 | 1649 | ||
| 1648 | BT_DBG("conn %p", conn); | 1650 | BT_DBG("conn %p", conn); |
| 1649 | 1651 | ||
| 1650 | mutex_lock(&conn->chan_lock); | ||
| 1651 | |||
| 1652 | list_for_each_entry(chan, &conn->chan_l, list) { | 1652 | list_for_each_entry(chan, &conn->chan_l, list) { |
| 1653 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) | 1653 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
| 1654 | l2cap_chan_set_err(chan, err); | 1654 | l2cap_chan_set_err(chan, err); |
| 1655 | } | 1655 | } |
| 1656 | |||
| 1657 | mutex_unlock(&conn->chan_lock); | ||
| 1658 | } | 1656 | } |
| 1659 | 1657 | ||
| 1660 | static void l2cap_info_timeout(struct work_struct *work) | 1658 | static void l2cap_info_timeout(struct work_struct *work) |
| @@ -1665,7 +1663,9 @@ static void l2cap_info_timeout(struct work_struct *work) · 4 unmodified lines | |||
| 1665 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 1663 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
| 1666 | conn->info_ident = 0; | 1664 | conn->info_ident = 0; |
| 1667 | 1665 | ||
| 1666 | mutex_lock(&conn->lock); | ||
| 1668 | l2cap_conn_start(conn); | 1667 | l2cap_conn_start(conn); |
| 1668 | mutex_unlock(&conn->lock); | ||
| 1669 | } | 1669 | } |
| 1670 | 1670 | ||
| 1671 | /* | 1671 | /* |
| @@ -1757,6 +1757,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) · 85 unmodified lines | |||
| 1757 | 1757 | ||
| 1758 | BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); | 1758 | BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); |
| 1759 | 1759 | ||
| 1760 | mutex_lock(&conn->lock); | ||
| 1761 | |||
| 1760 | kfree_skb(conn->rx_skb); | 1762 | kfree_skb(conn->rx_skb); |
| 1761 | 1763 | ||
| 1762 | skb_queue_purge(&conn->pending_rx); | 1764 | skb_queue_purge(&conn->pending_rx); |
| @@ -1775,8 +1777,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) · 12 unmodified lines | |||
| 1775 | /* Force the connection to be immediately dropped */ | 1777 | /* Force the connection to be immediately dropped */ |
| 1776 | hcon->disc_timeout = 0; | 1778 | hcon->disc_timeout = 0; |
| 1777 | 1779 | ||
| 1778 | mutex_lock(&conn->chan_lock); | ||
| 1779 | |||
| 1780 | /* Kill channels */ | 1780 | /* Kill channels */ |
| 1781 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { | 1781 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { |
| 1782 | l2cap_chan_hold(chan); | 1782 | l2cap_chan_hold(chan); |
| @@ -1790,15 +1790,14 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) · 7 unmodified lines | |||
| 1790 | l2cap_chan_put(chan); | 1790 | l2cap_chan_put(chan); |
| 1791 | } | 1791 | } |
| 1792 | 1792 | ||
| 1793 | mutex_unlock(&conn->chan_lock); | ||
| 1794 | |||
| 1795 | hci_chan_del(conn->hchan); | ||
| 1796 | |||
| 1797 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 1793 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
| 1798 | cancel_delayed_work_sync(&conn->info_timer); | 1794 | cancel_delayed_work_sync(&conn->info_timer); |
| 1799 | 1795 | ||
| 1800 | hcon->l2cap_data = NULL; | 1796 | hci_chan_del(conn->hchan); |
| 1801 | conn->hchan = NULL; | 1797 | conn->hchan = NULL; |
| 1798 | |||
| 1799 | hcon->l2cap_data = NULL; | ||
| 1800 | mutex_unlock(&conn->lock); | ||
| 1802 | l2cap_conn_put(conn); | 1801 | l2cap_conn_put(conn); |
| 1803 | } | 1802 | } |
| 1804 | 1803 | ||
| @@ -2916,8 +2915,6 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) · 1111 unmodified lines | |||
| 2916 | 2915 | ||
| 2917 | BT_DBG("conn %p", conn); | 2916 | BT_DBG("conn %p", conn); |
| 2918 | 2917 | ||
| 2919 | mutex_lock(&conn->chan_lock); | ||
| 2920 | |||
| 2921 | list_for_each_entry(chan, &conn->chan_l, list) { | 2918 | list_for_each_entry(chan, &conn->chan_l, list) { |
| 2922 | if (chan->chan_type != L2CAP_CHAN_RAW) | 2919 | if (chan->chan_type != L2CAP_CHAN_RAW) |
| 2923 | continue; | 2920 | continue; |
| @@ -2932,8 +2929,6 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) · 8 unmodified lines | |||
| 2932 | if (chan->ops->recv(chan, nskb)) | 2929 | if (chan->ops->recv(chan, nskb)) |
| 2933 | kfree_skb(nskb); | 2930 | kfree_skb(nskb); |
| 2934 | } | 2931 | } |
| 2935 | |||
| 2936 | mutex_unlock(&conn->chan_lock); | ||
| 2937 | } | 2932 | } |
| 2938 | 2933 | ||
| 2939 | /* ---- L2CAP signalling commands ---- */ | 2934 | /* ---- L2CAP signalling commands ---- */ |
| @@ -3952,7 +3947,6 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, · 1012 unmodified lines | |||
| 3952 | goto response; | 3947 | goto response; |
| 3953 | } | 3948 | } |
| 3954 | 3949 | ||
| 3955 | mutex_lock(&conn->chan_lock); | ||
| 3956 | l2cap_chan_lock(pchan); | 3950 | l2cap_chan_lock(pchan); |
| 3957 | 3951 | ||
| 3958 | /* Check if the ACL is secure enough (if not SDP) */ | 3952 | /* Check if the ACL is secure enough (if not SDP) */ |
| @@ -4059,7 +4053,6 @@ response: · 100 unmodified lines | |||
| 4059 | } | 4053 | } |
| 4060 | 4054 | ||
| 4061 | l2cap_chan_unlock(pchan); | 4055 | l2cap_chan_unlock(pchan); |
| 4062 | mutex_unlock(&conn->chan_lock); | ||
| 4063 | l2cap_chan_put(pchan); | 4056 | l2cap_chan_put(pchan); |
| 4064 | } | 4057 | } |
| 4065 | 4058 | ||
| @@ -4098,27 +4091,19 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, · 32 unmodified lines | |||
| 4098 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", | 4091 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", |
| 4099 | dcid, scid, result, status); | 4092 | dcid, scid, result, status); |
| 4100 | 4093 | ||
| 4101 | mutex_lock(&conn->chan_lock); | ||
| 4102 | |||
| 4103 | if (scid) { | 4094 | if (scid) { |
| 4104 | chan = __l2cap_get_chan_by_scid(conn, scid); | 4095 | chan = __l2cap_get_chan_by_scid(conn, scid); |
| 4105 | if (!chan) { | 4096 | if (!chan) |
| 4106 | err = -EBADSLT; | 4097 | return -EBADSLT; |
| 4107 | goto unlock; | ||
| 4108 | } | ||
| 4109 | } else { | 4098 | } else { |
| 4110 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); | 4099 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); |
| 4111 | if (!chan) { | 4100 | if (!chan) |
| 4112 | err = -EBADSLT; | 4101 | return -EBADSLT; |
| 4113 | goto unlock; | ||
| 4114 | } | ||
| 4115 | } | 4102 | } |
| 4116 | 4103 | ||
| 4117 | chan = l2cap_chan_hold_unless_zero(chan); | 4104 | chan = l2cap_chan_hold_unless_zero(chan); |
| 4118 | if (!chan) { | 4105 | if (!chan) |
| 4119 | err = -EBADSLT; | 4106 | return -EBADSLT; |
| 4120 | goto unlock; | ||
| 4121 | } | ||
| 4122 | 4107 | ||
| 4123 | err = 0; | 4108 | err = 0; |
| 4124 | 4109 | ||
| @@ -4156,9 +4141,6 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, · 31 unmodified lines | |||
| 4156 | l2cap_chan_unlock(chan); | 4141 | l2cap_chan_unlock(chan); |
| 4157 | l2cap_chan_put(chan); | 4142 | l2cap_chan_put(chan); |
| 4158 | 4143 | ||
| 4159 | unlock: | ||
| 4160 | mutex_unlock(&conn->chan_lock); | ||
| 4161 | |||
| 4162 | return err; | 4144 | return err; |
| 4163 | } | 4145 | } |
| 4164 | 4146 | ||
| @@ -4446,11 +4428,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, · 281 unmodified lines | |||
| 4446 | 4428 | ||
| 4447 | chan->ops->set_shutdown(chan); | 4429 | chan->ops->set_shutdown(chan); |
| 4448 | 4430 | ||
| 4449 | l2cap_chan_unlock(chan); | ||
| 4450 | mutex_lock(&conn->chan_lock); | ||
| 4451 | l2cap_chan_lock(chan); | ||
| 4452 | l2cap_chan_del(chan, ECONNRESET); | 4431 | l2cap_chan_del(chan, ECONNRESET); |
| 4453 | mutex_unlock(&conn->chan_lock); | ||
| 4454 | 4432 | ||
| 4455 | chan->ops->close(chan); | 4433 | chan->ops->close(chan); |
| 4456 | 4434 | ||
| @@ -4487,11 +4465,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, · 30 unmodified lines | |||
| 4487 | return 0; | 4465 | return 0; |
| 4488 | } | 4466 | } |
| 4489 | 4467 | ||
| 4490 | l2cap_chan_unlock(chan); | ||
| 4491 | mutex_lock(&conn->chan_lock); | ||
| 4492 | l2cap_chan_lock(chan); | ||
| 4493 | l2cap_chan_del(chan, 0); | 4468 | l2cap_chan_del(chan, 0); |
| 4494 | mutex_unlock(&conn->chan_lock); | ||
| 4495 | 4469 | ||
| 4496 | chan->ops->close(chan); | 4470 | chan->ops->close(chan); |
| 4497 | 4471 | ||
| @@ -4689,13 +4663,9 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, · 191 unmodified lines | |||
| 4689 | BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x", | 4663 | BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x", |
| 4690 | dcid, mtu, mps, credits, result); | 4664 | dcid, mtu, mps, credits, result); |
| 4691 | 4665 | ||
| 4692 | mutex_lock(&conn->chan_lock); | ||
| 4693 | |||
| 4694 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); | 4666 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); |
| 4695 | if (!chan) { | 4667 | if (!chan) |
| 4696 | err = -EBADSLT; | 4668 | return -EBADSLT; |
| 4697 | goto unlock; | ||
| 4698 | } | ||
| 4699 | 4669 | ||
| 4700 | err = 0; | 4670 | err = 0; |
| 4701 | 4671 | ||
| @@ -4743,9 +4713,6 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn, · 41 unmodified lines | |||
| 4743 | 4713 | ||
| 4744 | l2cap_chan_unlock(chan); | 4714 | l2cap_chan_unlock(chan); |
| 4745 | 4715 | ||
| 4746 | unlock: | ||
| 4747 | mutex_unlock(&conn->chan_lock); | ||
| 4748 | |||
| 4749 | return err; | 4716 | return err; |
| 4750 | } | 4717 | } |
| 4751 | 4718 | ||
| @@ -4857,7 +4824,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, · 105 unmodified lines | |||
| 4857 | goto response; | 4824 | goto response; |
| 4858 | } | 4825 | } |
| 4859 | 4826 | ||
| 4860 | mutex_lock(&conn->chan_lock); | ||
| 4861 | l2cap_chan_lock(pchan); | 4827 | l2cap_chan_lock(pchan); |
| 4862 | 4828 | ||
| 4863 | if (!smp_sufficient_security(conn->hcon, pchan->sec_level, | 4829 | if (!smp_sufficient_security(conn->hcon, pchan->sec_level, |
| @@ -4923,7 +4889,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, · 59 unmodified lines | |||
| 4923 | 4889 | ||
| 4924 | response_unlock: | 4890 | response_unlock: |
| 4925 | l2cap_chan_unlock(pchan); | 4891 | l2cap_chan_unlock(pchan); |
| 4926 | mutex_unlock(&conn->chan_lock); | ||
| 4927 | l2cap_chan_put(pchan); | 4892 | l2cap_chan_put(pchan); |
| 4928 | 4893 | ||
| 4929 | if (result == L2CAP_CR_PEND) | 4894 | if (result == L2CAP_CR_PEND) |
| @@ -5057,7 +5022,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, · 127 unmodified lines | |||
| 5057 | goto response; | 5022 | goto response; |
| 5058 | } | 5023 | } |
| 5059 | 5024 | ||
| 5060 | mutex_lock(&conn->chan_lock); | ||
| 5061 | l2cap_chan_lock(pchan); | 5025 | l2cap_chan_lock(pchan); |
| 5062 | 5026 | ||
| 5063 | if (!smp_sufficient_security(conn->hcon, pchan->sec_level, | 5027 | if (!smp_sufficient_security(conn->hcon, pchan->sec_level, |
| @@ -5132,7 +5096,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, · 68 unmodified lines | |||
| 5132 | 5096 | ||
| 5133 | unlock: | 5097 | unlock: |
| 5134 | l2cap_chan_unlock(pchan); | 5098 | l2cap_chan_unlock(pchan); |
| 5135 | mutex_unlock(&conn->chan_lock); | ||
| 5136 | l2cap_chan_put(pchan); | 5099 | l2cap_chan_put(pchan); |
| 5137 | 5100 | ||
| 5138 | response: | 5101 | response: |
| @@ -5169,8 +5132,6 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, · 30 unmodified lines | |||
| 5169 | BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits, | 5132 | BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits, |
| 5170 | result); | 5133 | result); |
| 5171 | 5134 | ||
| 5172 | mutex_lock(&conn->chan_lock); | ||
| 5173 | |||
| 5174 | cmd_len -= sizeof(*rsp); | 5135 | cmd_len -= sizeof(*rsp); |
| 5175 | 5136 | ||
| 5176 | list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { | 5137 | list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { |
| @@ -5256,8 +5217,6 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn, · 79 unmodified lines | |||
| 5256 | l2cap_chan_unlock(chan); | 5217 | l2cap_chan_unlock(chan); |
| 5257 | } | 5218 | } |
| 5258 | 5219 | ||
| 5259 | mutex_unlock(&conn->chan_lock); | ||
| 5260 | |||
| 5261 | return err; | 5220 | return err; |
| 5262 | } | 5221 | } |
| 5263 | 5222 | ||
| @@ -5370,8 +5329,6 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn, · 106 unmodified lines | |||
| 5370 | if (cmd_len < sizeof(*rej)) | 5329 | if (cmd_len < sizeof(*rej)) |
| 5371 | return -EPROTO; | 5330 | return -EPROTO; |
| 5372 | 5331 | ||
| 5373 | mutex_lock(&conn->chan_lock); | ||
| 5374 | |||
| 5375 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); | 5332 | chan = __l2cap_get_chan_by_ident(conn, cmd->ident); |
| 5376 | if (!chan) | 5333 | if (!chan) |
| 5377 | goto done; | 5334 | goto done; |
| @@ -5386,7 +5343,6 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn, · 8 unmodified lines | |||
| 5386 | l2cap_chan_put(chan); | 5343 | l2cap_chan_put(chan); |
| 5387 | 5344 | ||
| 5388 | done: | 5345 | done: |
| 5389 | mutex_unlock(&conn->chan_lock); | ||
| 5390 | return 0; | 5346 | return 0; |
| 5391 | } | 5347 | } |
| 5392 | 5348 | ||
| @@ -6841,8 +6797,12 @@ static void process_pending_rx(struct work_struct *work) · 1448 unmodified lines | |||
| 6841 | 6797 | ||
| 6842 | BT_DBG(""); | 6798 | BT_DBG(""); |
| 6843 | 6799 | ||
| 6800 | mutex_lock(&conn->lock); | ||
| 6801 | |||
| 6844 | while ((skb = skb_dequeue(&conn->pending_rx))) | 6802 | while ((skb = skb_dequeue(&conn->pending_rx))) |
| 6845 | l2cap_recv_frame(conn, skb); | 6803 | l2cap_recv_frame(conn, skb); |
| 6804 | |||
| 6805 | mutex_unlock(&conn->lock); | ||
| 6846 | } | 6806 | } |
| 6847 | 6807 | ||
| 6848 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) | 6808 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) |
| @@ -6881,7 +6841,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) · 32 unmodified lines | |||
| 6881 | conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR; | 6841 | conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR; |
| 6882 | 6842 | ||
| 6883 | mutex_init(&conn->ident_lock); | 6843 | mutex_init(&conn->ident_lock); |
| 6884 | mutex_init(&conn->chan_lock); | 6844 | mutex_init(&conn->lock); |
| 6885 | 6845 | ||
| 6886 | INIT_LIST_HEAD(&conn->chan_l); | 6846 | INIT_LIST_HEAD(&conn->chan_l); |
| 6887 | INIT_LIST_HEAD(&conn->users); | 6847 | INIT_LIST_HEAD(&conn->users); |
| @@ -7072,7 +7032,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · 184 unmodified lines | |||
| 7072 | } | 7032 | } |
| 7073 | } | 7033 | } |
| 7074 | 7034 | ||
| 7075 | mutex_lock(&conn->chan_lock); | 7035 | mutex_lock(&conn->lock); |
| 7076 | l2cap_chan_lock(chan); | 7036 | l2cap_chan_lock(chan); |
| 7077 | 7037 | ||
| 7078 | if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { | 7038 | if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { |
| @@ -7113,7 +7073,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · 34 unmodified lines | |||
| 7113 | 7073 | ||
| 7114 | chan_unlock: | 7074 | chan_unlock: |
| 7115 | l2cap_chan_unlock(chan); | 7075 | l2cap_chan_unlock(chan); |
| 7116 | mutex_unlock(&conn->chan_lock); | 7076 | mutex_unlock(&conn->lock); |
| 7117 | done: | 7077 | done: |
| 7118 | hci_dev_unlock(hdev); | 7078 | hci_dev_unlock(hdev); |
| 7119 | hci_dev_put(hdev); | 7079 | hci_dev_put(hdev); |
| @@ -7325,7 +7285,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 205 unmodified lines | |||
| 7325 | 7285 | ||
| 7326 | BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); | 7286 | BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); |
| 7327 | 7287 | ||
| 7328 | mutex_lock(&conn->chan_lock); | 7288 | mutex_lock(&conn->lock); |
| 7329 | 7289 | ||
| 7330 | list_for_each_entry(chan, &conn->chan_l, list) { | 7290 | list_for_each_entry(chan, &conn->chan_l, list) { |
| 7331 | l2cap_chan_lock(chan); | 7291 | l2cap_chan_lock(chan); |
| @@ -7399,7 +7359,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 67 unmodified lines | |||
| 7399 | l2cap_chan_unlock(chan); | 7359 | l2cap_chan_unlock(chan); |
| 7400 | } | 7360 | } |
| 7401 | 7361 | ||
| 7402 | mutex_unlock(&conn->chan_lock); | 7362 | mutex_unlock(&conn->lock); |
| 7403 | } | 7363 | } |
| 7404 | 7364 | ||
| 7405 | /* Append fragment into frame respecting the maximum len of rx_skb */ | 7365 | /* Append fragment into frame respecting the maximum len of rx_skb */ |
| @@ -7466,19 +7426,45 @@ static void l2cap_recv_reset(struct l2cap_conn *conn) · 60 unmodified lines | |||
| 7466 | conn->rx_len = 0; | 7426 | conn->rx_len = 0; |
| 7467 | } | 7427 | } |
| 7468 | 7428 | ||
| 7429 | struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c) | ||
| 7430 | { | ||
| 7431 | if (!c) | ||
| 7432 | return NULL; | ||
| 7433 | |||
| 7434 | BT_DBG("conn %p orig refcnt %u", c, kref_read(&c->ref)); | ||
| 7435 | |||
| 7436 | if (!kref_get_unless_zero(&c->ref)) | ||
| 7437 | return NULL; | ||
| 7438 | |||
| 7439 | return c; | ||
| 7440 | } | ||
| 7441 | |||
| 7469 | void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) | 7442 | void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) |
| 7470 | { | 7443 | { |
| 7471 | struct l2cap_conn *conn = hcon->l2cap_data; | 7444 | struct l2cap_conn *conn; |
| 7472 | int len; | 7445 | int len; |
| 7473 | 7446 | ||
| 7447 | /* Lock hdev to access l2cap_data to avoid race with l2cap_conn_del */ | ||
| 7448 | hci_dev_lock(hcon->hdev); | ||
| 7449 | |||
| 7450 | conn = hcon->l2cap_data; | ||
| 7451 | |||
| 7474 | if (!conn) | 7452 | if (!conn) |
| 7475 | conn = l2cap_conn_add(hcon); | 7453 | conn = l2cap_conn_add(hcon); |
| 7476 | 7454 | ||
| 7477 | if (!conn) | 7455 | conn = l2cap_conn_hold_unless_zero(conn); |
| 7478 | goto drop; | 7456 | |
| 7457 | hci_dev_unlock(hcon->hdev); | ||
| 7458 | |||
| 7459 | if (!conn) { | ||
| 7460 | kfree_skb(skb); | ||
| 7461 | return; | ||
| 7462 | } | ||
| 7479 | 7463 | ||
| 7480 | BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags); | 7464 | BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags); |
| 7481 | 7465 | ||
| 7466 | mutex_lock(&conn->lock); | ||
| 7467 | |||
| 7482 | switch (flags) { | 7468 | switch (flags) { |
| 7483 | case ACL_START: | 7469 | case ACL_START: |
| 7484 | case ACL_START_NO_FLUSH: | 7470 | case ACL_START_NO_FLUSH: |
| @@ -7503,7 +7489,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 18 unmodified lines | |||
| 7503 | if (len == skb->len) { | 7489 | if (len == skb->len) { |
| 7504 | /* Complete frame received */ | 7490 | /* Complete frame received */ |
| 7505 | l2cap_recv_frame(conn, skb); | 7491 | l2cap_recv_frame(conn, skb); |
| 7506 | return; | 7492 | goto unlock; |
| 7507 | } | 7493 | } |
| 7508 | 7494 | ||
| 7509 | BT_DBG("Start: total len %d, frag len %u", len, skb->len); | 7495 | BT_DBG("Start: total len %d, frag len %u", len, skb->len); |
| @@ -7567,6 +7553,9 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 57 unmodified lines | |||
| 7567 | 7553 | ||
| 7568 | drop: | 7554 | drop: |
| 7569 | kfree_skb(skb); | 7555 | kfree_skb(skb); |
| 7556 | unlock: | ||
| 7557 | mutex_unlock(&conn->lock); | ||
| 7558 | l2cap_conn_put(conn); | ||
| 7570 | } | 7559 | } |
| 7571 | 7560 | ||
| 7572 | static struct hci_cb l2cap_cb = { | 7561 | static struct hci_cb l2cap_cb = { |
| @@ -1326,9 +1326,10 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) · 1325 unmodified lines | |||
| 1326 | /* prevent sk structure from being freed whilst unlocked */ | 1326 | /* prevent sk structure from being freed whilst unlocked */ |
| 1327 | sock_hold(sk); | 1327 | sock_hold(sk); |
| 1328 | 1328 | ||
| 1329 | chan = l2cap_pi(sk)->chan; | ||
| 1330 | /* prevent chan structure from being freed whilst unlocked */ | 1329 | /* prevent chan structure from being freed whilst unlocked */ |
| 1331 | l2cap_chan_hold(chan); | 1330 | chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan); |
| 1331 | if (!chan) | ||
| 1332 | goto shutdown_already; | ||
| 1332 | 1333 | ||
| 1333 | BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); | 1334 | BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); |
| 1334 | 1335 | ||
| @@ -1358,22 +1359,20 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) · 23 unmodified lines | |||
| 1358 | release_sock(sk); | 1359 | release_sock(sk); |
| 1359 | 1360 | ||
| 1360 | l2cap_chan_lock(chan); | 1361 | l2cap_chan_lock(chan); |
| 1361 | conn = chan->conn; | 1362 | /* prevent conn structure from being freed */ |
| 1362 | if (conn) | 1363 | conn = l2cap_conn_hold_unless_zero(chan->conn); |
| 1363 | /* prevent conn structure from being freed */ | ||
| 1364 | l2cap_conn_get(conn); | ||
| 1365 | l2cap_chan_unlock(chan); | 1364 | l2cap_chan_unlock(chan); |
| 1366 | 1365 | ||
| 1367 | if (conn) | 1366 | if (conn) |
| 1368 | /* mutex lock must be taken before l2cap_chan_lock() */ | 1367 | /* mutex lock must be taken before l2cap_chan_lock() */ |
| 1369 | mutex_lock(&conn->chan_lock); | 1368 | mutex_lock(&conn->lock); |
| 1370 | 1369 | ||
| 1371 | l2cap_chan_lock(chan); | 1370 | l2cap_chan_lock(chan); |
| 1372 | l2cap_chan_close(chan, 0); | 1371 | l2cap_chan_close(chan, 0); |
| 1373 | l2cap_chan_unlock(chan); | 1372 | l2cap_chan_unlock(chan); |
| 1374 | 1373 | ||
| 1375 | if (conn) { | 1374 | if (conn) { |
| 1376 | mutex_unlock(&conn->chan_lock); | 1375 | mutex_unlock(&conn->lock); |
| 1377 | l2cap_conn_put(conn); | 1376 | l2cap_conn_put(conn); |
| 1378 | } | 1377 | } |
| 1379 | 1378 | ||
| @@ -1132,7 +1132,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk, · 1131 unmodified lines | |||
| 1132 | 1132 | ||
| 1133 | todo_size = size; | 1133 | todo_size = size; |
| 1134 | 1134 | ||
| 1135 | while (todo_size) { | 1135 | do { |
| 1136 | struct j1939_sk_buff_cb *skcb; | 1136 | struct j1939_sk_buff_cb *skcb; |
| 1137 | 1137 | ||
| 1138 | segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE, | 1138 | segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE, |
| @@ -1177,7 +1177,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk, · 38 unmodified lines | |||
| 1177 | 1177 | ||
| 1178 | todo_size -= segment_size; | 1178 | todo_size -= segment_size; |
| 1179 | session->total_queued_size += segment_size; | 1179 | session->total_queued_size += segment_size; |
| 1180 | } | 1180 | } while (todo_size); |
| 1181 | 1181 | ||
| 1182 | switch (ret) { | 1182 | switch (ret) { |
| 1183 | case 0: /* OK */ | 1183 | case 0: /* OK */ |
| @@ -382,8 +382,9 @@ sk_buff *j1939_session_skb_get_by_offset(struct j1939_session *session, · 381 unmodified lines | |||
| 382 | skb_queue_walk(&session->skb_queue, do_skb) { | 382 | skb_queue_walk(&session->skb_queue, do_skb) { |
| 383 | do_skcb = j1939_skb_to_cb(do_skb); | 383 | do_skcb = j1939_skb_to_cb(do_skb); |
| 384 | 384 | ||
| 385 | if (offset_start >= do_skcb->offset && | 385 | if ((offset_start >= do_skcb->offset && |
| 386 | offset_start < (do_skcb->offset + do_skb->len)) { | 386 | offset_start < (do_skcb->offset + do_skb->len)) || |
| 387 | (offset_start == 0 && do_skcb->offset == 0 && do_skb->len == 0)) { | ||
| 387 | skb = do_skb; | 388 | skb = do_skb; |
| 388 | } | 389 | } |
| 389 | } | 390 | } |
| @@ -37,8 +37,8 @@ static const struct fib_kuid_range fib_kuid_range_unset = { · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | bool fib_rule_matchall(const struct fib_rule *rule) | 38 | bool fib_rule_matchall(const struct fib_rule *rule) |
| 39 | { | 39 | { |
| 40 | if (rule->iifindex || rule->oifindex || rule->mark || rule->tun_id || | 40 | if (READ_ONCE(rule->iifindex) || READ_ONCE(rule->oifindex) || |
| 41 | rule->flags) | 41 | rule->mark || rule->tun_id || rule->flags) |
| 42 | return false; | 42 | return false; |
| 43 | if (rule->suppress_ifgroup != -1 || rule->suppress_prefixlen != -1) | 43 | if (rule->suppress_ifgroup != -1 || rule->suppress_prefixlen != -1) |
| 44 | return false; | 44 | return false; |
| @@ -261,12 +261,14 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, · 216 unmodified lines | |||
| 261 | struct flowi *fl, int flags, | 261 | struct flowi *fl, int flags, |
| 262 | struct fib_lookup_arg *arg) | 262 | struct fib_lookup_arg *arg) |
| 263 | { | 263 | { |
| 264 | int ret = 0; | 264 | int iifindex, oifindex, ret = 0; |
| 265 | 265 | ||
| 266 | if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) | 266 | iifindex = READ_ONCE(rule->iifindex); |
| 267 | if (iifindex && (iifindex != fl->flowi_iif)) | ||
| 267 | goto out; | 268 | goto out; |
| 268 | 269 | ||
| 269 | if (rule->oifindex && (rule->oifindex != fl->flowi_oif)) | 270 | oifindex = READ_ONCE(rule->oifindex); |
| 271 | if (oifindex && (oifindex != fl->flowi_oif)) | ||
| 270 | goto out; | 272 | goto out; |
| 271 | 273 | ||
| 272 | if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) | 274 | if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) |
| @@ -1041,14 +1043,14 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, · 768 unmodified lines | |||
| 1041 | if (rule->iifname[0]) { | 1043 | if (rule->iifname[0]) { |
| 1042 | if (nla_put_string(skb, FRA_IIFNAME, rule->iifname)) | 1044 | if (nla_put_string(skb, FRA_IIFNAME, rule->iifname)) |
| 1043 | goto nla_put_failure; | 1045 | goto nla_put_failure; |
| 1044 | if (rule->iifindex == -1) | 1046 | if (READ_ONCE(rule->iifindex) == -1) |
| 1045 | frh->flags |= FIB_RULE_IIF_DETACHED; | 1047 | frh->flags |= FIB_RULE_IIF_DETACHED; |
| 1046 | } | 1048 | } |
| 1047 | 1049 | ||
| 1048 | if (rule->oifname[0]) { | 1050 | if (rule->oifname[0]) { |
| 1049 | if (nla_put_string(skb, FRA_OIFNAME, rule->oifname)) | 1051 | if (nla_put_string(skb, FRA_OIFNAME, rule->oifname)) |
| 1050 | goto nla_put_failure; | 1052 | goto nla_put_failure; |
| 1051 | if (rule->oifindex == -1) | 1053 | if (READ_ONCE(rule->oifindex) == -1) |
| 1052 | frh->flags |= FIB_RULE_OIF_DETACHED; | 1054 | frh->flags |= FIB_RULE_OIF_DETACHED; |
| 1053 | } | 1055 | } |
| 1054 | 1056 | ||
| @@ -1220,10 +1222,10 @@ static void attach_rules(struct list_head *rules, struct net_device *dev) · 165 unmodified lines | |||
| 1220 | list_for_each_entry(rule, rules, list) { | 1222 | list_for_each_entry(rule, rules, list) { |
| 1221 | if (rule->iifindex == -1 && | 1223 | if (rule->iifindex == -1 && |
| 1222 | strcmp(dev->name, rule->iifname) == 0) | 1224 | strcmp(dev->name, rule->iifname) == 0) |
| 1223 | rule->iifindex = dev->ifindex; | 1225 | WRITE_ONCE(rule->iifindex, dev->ifindex); |
| 1224 | if (rule->oifindex == -1 && | 1226 | if (rule->oifindex == -1 && |
| 1225 | strcmp(dev->name, rule->oifname) == 0) | 1227 | strcmp(dev->name, rule->oifname) == 0) |
| 1226 | rule->oifindex = dev->ifindex; | 1228 | WRITE_ONCE(rule->oifindex, dev->ifindex); |
| 1227 | } | 1229 | } |
| 1228 | } | 1230 | } |
| 1229 | 1231 | ||
| @@ -1233,9 +1235,9 @@ static void detach_rules(struct list_head *rules, struct net_device *dev) · 3 unmodified lines | |||
| 1233 | 1235 | ||
| 1234 | list_for_each_entry(rule, rules, list) { | 1236 | list_for_each_entry(rule, rules, list) { |
| 1235 | if (rule->iifindex == dev->ifindex) | 1237 | if (rule->iifindex == dev->ifindex) |
| 1236 | rule->iifindex = -1; | 1238 | WRITE_ONCE(rule->iifindex, -1); |
| 1237 | if (rule->oifindex == dev->ifindex) | 1239 | if (rule->oifindex == dev->ifindex) |
| 1238 | rule->oifindex = -1; | 1240 | WRITE_ONCE(rule->oifindex, -1); |
| 1239 | } | 1241 | } |
| 1240 | } | 1242 | } |
| 1241 | 1243 | ||
| @@ -1108,10 +1108,12 @@ bool __skb_flow_dissect(const struct net *net, · 1107 unmodified lines | |||
| 1108 | FLOW_DISSECTOR_KEY_BASIC, | 1108 | FLOW_DISSECTOR_KEY_BASIC, |
| 1109 | target_container); | 1109 | target_container); |
| 1110 | 1110 | ||
| 1111 | rcu_read_lock(); | ||
| 1112 | |||
| 1111 | if (skb) { | 1113 | if (skb) { |
| 1112 | if (!net) { | 1114 | if (!net) { |
| 1113 | if (skb->dev) | 1115 | if (skb->dev) |
| 1114 | net = dev_net(skb->dev); | 1116 | net = dev_net_rcu(skb->dev); |
| 1115 | else if (skb->sk) | 1117 | else if (skb->sk) |
| 1116 | net = sock_net(skb->sk); | 1118 | net = sock_net(skb->sk); |
| 1117 | } | 1119 | } |
| @@ -1122,7 +1124,6 @@ bool __skb_flow_dissect(const struct net *net, · 4 unmodified lines | |||
| 1122 | enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR; | 1124 | enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR; |
| 1123 | struct bpf_prog_array *run_array; | 1125 | struct bpf_prog_array *run_array; |
| 1124 | 1126 | ||
| 1125 | rcu_read_lock(); | ||
| 1126 | run_array = rcu_dereference(init_net.bpf.run_array[type]); | 1127 | run_array = rcu_dereference(init_net.bpf.run_array[type]); |
| 1127 | if (!run_array) | 1128 | if (!run_array) |
| 1128 | run_array = rcu_dereference(net->bpf.run_array[type]); | 1129 | run_array = rcu_dereference(net->bpf.run_array[type]); |
| @@ -1150,17 +1151,17 @@ bool __skb_flow_dissect(const struct net *net, · 21 unmodified lines | |||
| 1150 | prog = READ_ONCE(run_array->items[0].prog); | 1151 | prog = READ_ONCE(run_array->items[0].prog); |
| 1151 | result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff, | 1152 | result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff, |
| 1152 | hlen, flags); | 1153 | hlen, flags); |
| 1153 | if (result == BPF_FLOW_DISSECTOR_CONTINUE) | 1154 | if (result != BPF_FLOW_DISSECTOR_CONTINUE) { |
| 1154 | goto dissect_continue; | 1155 | __skb_flow_bpf_to_target(&flow_keys, flow_dissector, |
| 1155 | __skb_flow_bpf_to_target(&flow_keys, flow_dissector, | 1156 | target_container); |
| 1156 | target_container); | 1157 | rcu_read_unlock(); |
| 1157 | rcu_read_unlock(); | 1158 | return result == BPF_OK; |
| 1158 | return result == BPF_OK; | 1159 | } |
| 1159 | } | 1160 | } |
| 1160 | dissect_continue: | ||
| 1161 | rcu_read_unlock(); | ||
| 1162 | } | 1161 | } |
| 1163 | 1162 | ||
| 1163 | rcu_read_unlock(); | ||
| 1164 | |||
| 1164 | if (dissector_uses_key(flow_dissector, | 1165 | if (dissector_uses_key(flow_dissector, |
| 1165 | FLOW_DISSECTOR_KEY_ETH_ADDRS)) { | 1166 | FLOW_DISSECTOR_KEY_ETH_ADDRS)) { |
| 1166 | struct ethhdr *eth = eth_hdr(skb); | 1167 | struct ethhdr *eth = eth_hdr(skb); |
| @@ -3447,10 +3447,12 @@ static const struct seq_operations neigh_stat_seq_ops = { · 3446 unmodified lines | |||
| 3447 | static void __neigh_notify(struct neighbour *n, int type, int flags, | 3447 | static void __neigh_notify(struct neighbour *n, int type, int flags, |
| 3448 | u32 pid) | 3448 | u32 pid) |
| 3449 | { | 3449 | { |
| 3450 | struct net *net = dev_net(n->dev); | ||
| 3451 | struct sk_buff *skb; | 3450 | struct sk_buff *skb; |
| 3452 | int err = -ENOBUFS; | 3451 | int err = -ENOBUFS; |
| 3452 | struct net *net; | ||
| 3453 | 3453 | ||
| 3454 | rcu_read_lock(); | ||
| 3455 | net = dev_net_rcu(n->dev); | ||
| 3454 | skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC); | 3456 | skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC); |
| 3455 | if (skb == NULL) | 3457 | if (skb == NULL) |
| 3456 | goto errout; | 3458 | goto errout; |
| @@ -3463,9 +3465,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags, · 6 unmodified lines | |||
| 3463 | goto errout; | 3465 | goto errout; |
| 3464 | } | 3466 | } |
| 3465 | rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); | 3467 | rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); |
| 3466 | return; | 3468 | goto out; |
| 3467 | errout: | 3469 | errout: |
| 3468 | rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); | 3470 | rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); |
| 3471 | out: | ||
| 3472 | rcu_read_unlock(); | ||
| 3469 | } | 3473 | } |
| 3470 | 3474 | ||
| 3471 | void neigh_app_ns(struct neighbour *n) | 3475 | void neigh_app_ns(struct neighbour *n) |
| @@ -3432,6 +3432,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, · 3431 unmodified lines | |||
| 3432 | err = -ENODEV; | 3432 | err = -ENODEV; |
| 3433 | 3433 | ||
| 3434 | rtnl_nets_unlock(&rtnl_nets); | 3434 | rtnl_nets_unlock(&rtnl_nets); |
| 3435 | rtnl_nets_destroy(&rtnl_nets); | ||
| 3435 | errout: | 3436 | errout: |
| 3436 | return err; | 3437 | return err; |
| 3437 | } | 3438 | } |
| @@ -462,6 +462,11 @@ const char ts_rx_filter_names[][ETH_GSTRING_LEN] = { · 461 unmodified lines | |||
| 462 | }; | 462 | }; |
| 463 | static_assert(ARRAY_SIZE(ts_rx_filter_names) == __HWTSTAMP_FILTER_CNT); | 463 | static_assert(ARRAY_SIZE(ts_rx_filter_names) == __HWTSTAMP_FILTER_CNT); |
| 464 | 464 | ||
| 465 | const char ts_flags_names[][ETH_GSTRING_LEN] = { | ||
| 466 | [const_ilog2(HWTSTAMP_FLAG_BONDED_PHC_INDEX)] = "bonded-phc-index", | ||
| 467 | }; | ||
| 468 | static_assert(ARRAY_SIZE(ts_flags_names) == __HWTSTAMP_FLAG_CNT); | ||
| 469 | |||
| 465 | const char udp_tunnel_type_names[][ETH_GSTRING_LEN] = { | 470 | const char udp_tunnel_type_names[][ETH_GSTRING_LEN] = { |
| 466 | [ETHTOOL_UDP_TUNNEL_TYPE_VXLAN] = "vxlan", | 471 | [ETHTOOL_UDP_TUNNEL_TYPE_VXLAN] = "vxlan", |
| 467 | [ETHTOOL_UDP_TUNNEL_TYPE_GENEVE] = "geneve", | 472 | [ETHTOOL_UDP_TUNNEL_TYPE_GENEVE] = "geneve", |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | ETHTOOL_LINK_MODE_ ## speed ## base ## type ## _ ## duplex ## _BIT | 13 | ETHTOOL_LINK_MODE_ ## speed ## base ## type ## _ ## duplex ## _BIT |
| 14 | 14 | ||
| 15 | #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1) | 15 | #define __SOF_TIMESTAMPING_CNT (const_ilog2(SOF_TIMESTAMPING_LAST) + 1) |
| 16 | #define __HWTSTAMP_FLAG_CNT (const_ilog2(HWTSTAMP_FLAG_LAST) + 1) | ||
| 16 | 17 | ||
| 17 | struct link_mode_info { | 18 | struct link_mode_info { |
| 18 | int speed; | 19 | int speed; |
| @@ -38,6 +39,7 @@ extern const char wol_mode_names[][ETH_GSTRING_LEN]; · 19 unmodified lines | |||
| 38 | extern const char sof_timestamping_names[][ETH_GSTRING_LEN]; | 39 | extern const char sof_timestamping_names[][ETH_GSTRING_LEN]; |
| 39 | extern const char ts_tx_type_names[][ETH_GSTRING_LEN]; | 40 | extern const char ts_tx_type_names[][ETH_GSTRING_LEN]; |
| 40 | extern const char ts_rx_filter_names[][ETH_GSTRING_LEN]; | 41 | extern const char ts_rx_filter_names[][ETH_GSTRING_LEN]; |
| 42 | extern const char ts_flags_names[][ETH_GSTRING_LEN]; | ||
| 41 | extern const char udp_tunnel_type_names[][ETH_GSTRING_LEN]; | 43 | extern const char udp_tunnel_type_names[][ETH_GSTRING_LEN]; |
| 42 | 44 | ||
| 43 | int __ethtool_get_link(struct net_device *dev); | 45 | int __ethtool_get_link(struct net_device *dev); |
| @@ -75,6 +75,11 @@ static const struct strset_info info_template[] = { · 74 unmodified lines | |||
| 75 | .count = __HWTSTAMP_FILTER_CNT, | 75 | .count = __HWTSTAMP_FILTER_CNT, |
| 76 | .strings = ts_rx_filter_names, | 76 | .strings = ts_rx_filter_names, |
| 77 | }, | 77 | }, |
| 78 | [ETH_SS_TS_FLAGS] = { | ||
| 79 | .per_dev = false, | ||
| 80 | .count = __HWTSTAMP_FLAG_CNT, | ||
| 81 | .strings = ts_flags_names, | ||
| 82 | }, | ||
| 78 | [ETH_SS_UDP_TUNNEL_TYPES] = { | 83 | [ETH_SS_UDP_TUNNEL_TYPES] = { |
| 79 | .per_dev = false, | 84 | .per_dev = false, |
| 80 | .count = __ETHTOOL_UDP_TUNNEL_TYPE_CNT, | 85 | .count = __ETHTOOL_UDP_TUNNEL_TYPE_CNT, |
| @@ -54,7 +54,7 @@ static int tsconfig_prepare_data(const struct ethnl_req_info *req_base, · 53 unmodified lines | |||
| 54 | 54 | ||
| 55 | data->hwtst_config.tx_type = BIT(cfg.tx_type); | 55 | data->hwtst_config.tx_type = BIT(cfg.tx_type); |
| 56 | data->hwtst_config.rx_filter = BIT(cfg.rx_filter); | 56 | data->hwtst_config.rx_filter = BIT(cfg.rx_filter); |
| 57 | data->hwtst_config.flags = BIT(cfg.flags); | 57 | data->hwtst_config.flags = cfg.flags; |
| 58 | 58 | ||
| 59 | data->hwprov_desc.index = -1; | 59 | data->hwprov_desc.index = -1; |
| 60 | hwprov = rtnl_dereference(dev->hwprov); | 60 | hwprov = rtnl_dereference(dev->hwprov); |
| @@ -91,10 +91,16 @@ static int tsconfig_reply_size(const struct ethnl_req_info *req_base, · 30 unmodified lines | |||
| 91 | 91 | ||
| 92 | BUILD_BUG_ON(__HWTSTAMP_TX_CNT > 32); | 92 | BUILD_BUG_ON(__HWTSTAMP_TX_CNT > 32); |
| 93 | BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT > 32); | 93 | BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT > 32); |
| 94 | BUILD_BUG_ON(__HWTSTAMP_FLAG_CNT > 32); | ||
| 94 | 95 | ||
| 95 | if (data->hwtst_config.flags) | 96 | if (data->hwtst_config.flags) { |
| 96 | /* _TSCONFIG_HWTSTAMP_FLAGS */ | 97 | ret = ethnl_bitset32_size(&data->hwtst_config.flags, |
| 97 | len += nla_total_size(sizeof(u32)); | 98 | NULL, __HWTSTAMP_FLAG_CNT, |
| 99 | ts_flags_names, compact); | ||
| 100 | if (ret < 0) | ||
| 101 | return ret; | ||
| 102 | len += ret; /* _TSCONFIG_HWTSTAMP_FLAGS */ | ||
| 103 | } | ||
| 98 | 104 | ||
| 99 | if (data->hwtst_config.tx_type) { | 105 | if (data->hwtst_config.tx_type) { |
| 100 | ret = ethnl_bitset32_size(&data->hwtst_config.tx_type, | 106 | ret = ethnl_bitset32_size(&data->hwtst_config.tx_type, |
| @@ -130,8 +136,10 @@ static int tsconfig_fill_reply(struct sk_buff *skb, · 29 unmodified lines | |||
| 130 | int ret; | 136 | int ret; |
| 131 | 137 | ||
| 132 | if (data->hwtst_config.flags) { | 138 | if (data->hwtst_config.flags) { |
| 133 | ret = nla_put_u32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS, | 139 | ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS, |
| 134 | data->hwtst_config.flags); | 140 | &data->hwtst_config.flags, NULL, |
| 141 | __HWTSTAMP_FLAG_CNT, | ||
| 142 | ts_flags_names, compact); | ||
| 135 | if (ret < 0) | 143 | if (ret < 0) |
| 136 | return ret; | 144 | return ret; |
| 137 | } | 145 | } |
| @@ -180,7 +188,7 @@ const struct nla_policy ethnl_tsconfig_set_policy[ETHTOOL_A_TSCONFIG_MAX + 1] = · 42 unmodified lines | |||
| 180 | [ETHTOOL_A_TSCONFIG_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), | 188 | [ETHTOOL_A_TSCONFIG_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy), |
| 181 | [ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER] = | 189 | [ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER] = |
| 182 | NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy), | 190 | NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy), |
| 183 | [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_U32 }, | 191 | [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_NESTED }, |
| 184 | [ETHTOOL_A_TSCONFIG_RX_FILTERS] = { .type = NLA_NESTED }, | 192 | [ETHTOOL_A_TSCONFIG_RX_FILTERS] = { .type = NLA_NESTED }, |
| 185 | [ETHTOOL_A_TSCONFIG_TX_TYPES] = { .type = NLA_NESTED }, | 193 | [ETHTOOL_A_TSCONFIG_TX_TYPES] = { .type = NLA_NESTED }, |
| 186 | }; | 194 | }; |
| @@ -296,6 +304,7 @@ static int ethnl_set_tsconfig(struct ethnl_req_info *req_base, · 109 unmodified lines | |||
| 296 | 304 | ||
| 297 | BUILD_BUG_ON(__HWTSTAMP_TX_CNT >= 32); | 305 | BUILD_BUG_ON(__HWTSTAMP_TX_CNT >= 32); |
| 298 | BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT >= 32); | 306 | BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT >= 32); |
| 307 | BUILD_BUG_ON(__HWTSTAMP_FLAG_CNT > 32); | ||
| 299 | 308 | ||
| 300 | if (!netif_device_present(dev)) | 309 | if (!netif_device_present(dev)) |
| 301 | return -ENODEV; | 310 | return -ENODEV; |
| @@ -377,9 +386,13 @@ static int ethnl_set_tsconfig(struct ethnl_req_info *req_base, · 75 unmodified lines | |||
| 377 | } | 386 | } |
| 378 | 387 | ||
| 379 | if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS]) { | 388 | if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS]) { |
| 380 | ethnl_update_u32(&hwtst_config.flags, | 389 | ret = ethnl_update_bitset32(&hwtst_config.flags, |
| 381 | tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS], | 390 | __HWTSTAMP_FLAG_CNT, |
| 382 | &config_mod); | 391 | tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS], |
| 392 | ts_flags_names, info->extack, | ||
| 393 | &config_mod); | ||
| 394 | if (ret < 0) | ||
| 395 | goto err_free_hwprov; | ||
| 383 | } | 396 | } |
| 384 | 397 | ||
| 385 | ret = net_hwtstamp_validate(&hwtst_config); | 398 | ret = net_hwtstamp_validate(&hwtst_config); |
| @@ -659,10 +659,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb · 658 unmodified lines | |||
| 659 | */ | 659 | */ |
| 660 | void arp_xmit(struct sk_buff *skb) | 660 | void arp_xmit(struct sk_buff *skb) |
| 661 | { | 661 | { |
| 662 | rcu_read_lock(); | ||
| 662 | /* Send it off, maybe filter it using firewalling first. */ | 663 | /* Send it off, maybe filter it using firewalling first. */ |
| 663 | NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, | 664 | NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, |
| 664 | dev_net(skb->dev), NULL, skb, NULL, skb->dev, | 665 | dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev, |
| 665 | arp_xmit_finish); | 666 | arp_xmit_finish); |
| 667 | rcu_read_unlock(); | ||
| 666 | } | 668 | } |
| 667 | EXPORT_SYMBOL(arp_xmit); | 669 | EXPORT_SYMBOL(arp_xmit); |
| 668 | 670 | ||
| @@ -1371,10 +1371,11 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) · 1370 unmodified lines | |||
| 1371 | __be32 addr = 0; | 1371 | __be32 addr = 0; |
| 1372 | unsigned char localnet_scope = RT_SCOPE_HOST; | 1372 | unsigned char localnet_scope = RT_SCOPE_HOST; |
| 1373 | struct in_device *in_dev; | 1373 | struct in_device *in_dev; |
| 1374 | struct net *net = dev_net(dev); | 1374 | struct net *net; |
| 1375 | int master_idx; | 1375 | int master_idx; |
| 1376 | 1376 | ||
| 1377 | rcu_read_lock(); | 1377 | rcu_read_lock(); |
| 1378 | net = dev_net_rcu(dev); | ||
| 1378 | in_dev = __in_dev_get_rcu(dev); | 1379 | in_dev = __in_dev_get_rcu(dev); |
| 1379 | if (!in_dev) | 1380 | if (!in_dev) |
| 1380 | goto no_in_dev; | 1381 | goto no_in_dev; |
| @@ -399,10 +399,10 @@ static void icmp_push_reply(struct sock *sk, · 398 unmodified lines | |||
| 399 | 399 | ||
| 400 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | 400 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) |
| 401 | { | 401 | { |
| 402 | struct ipcm_cookie ipc; | ||
| 403 | struct rtable *rt = skb_rtable(skb); | 402 | struct rtable *rt = skb_rtable(skb); |
| 404 | struct net *net = dev_net(rt->dst.dev); | 403 | struct net *net = dev_net_rcu(rt->dst.dev); |
| 405 | bool apply_ratelimit = false; | 404 | bool apply_ratelimit = false; |
| 405 | struct ipcm_cookie ipc; | ||
| 406 | struct flowi4 fl4; | 406 | struct flowi4 fl4; |
| 407 | struct sock *sk; | 407 | struct sock *sk; |
| 408 | struct inet_sock *inet; | 408 | struct inet_sock *inet; |
| @@ -608,12 +608,14 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, · 199 unmodified lines | |||
| 608 | struct sock *sk; | 608 | struct sock *sk; |
| 609 | 609 | ||
| 610 | if (!rt) | 610 | if (!rt) |
| 611 | goto out; | 611 | return; |
| 612 | |||
| 613 | rcu_read_lock(); | ||
| 612 | 614 | ||
| 613 | if (rt->dst.dev) | 615 | if (rt->dst.dev) |
| 614 | net = dev_net(rt->dst.dev); | 616 | net = dev_net_rcu(rt->dst.dev); |
| 615 | else if (skb_in->dev) | 617 | else if (skb_in->dev) |
| 616 | net = dev_net(skb_in->dev); | 618 | net = dev_net_rcu(skb_in->dev); |
| 617 | else | 619 | else |
| 618 | goto out; | 620 | goto out; |
| 619 | 621 | ||
| @@ -785,7 +787,8 @@ out_unlock: · 165 unmodified lines | |||
| 785 | icmp_xmit_unlock(sk); | 787 | icmp_xmit_unlock(sk); |
| 786 | out_bh_enable: | 788 | out_bh_enable: |
| 787 | local_bh_enable(); | 789 | local_bh_enable(); |
| 788 | out:; | 790 | out: |
| 791 | rcu_read_unlock(); | ||
| 789 | } | 792 | } |
| 790 | EXPORT_SYMBOL(__icmp_send); | 793 | EXPORT_SYMBOL(__icmp_send); |
| 791 | 794 | ||
| @@ -834,7 +837,7 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info) · 42 unmodified lines | |||
| 834 | * avoid additional coding at protocol handlers. | 837 | * avoid additional coding at protocol handlers. |
| 835 | */ | 838 | */ |
| 836 | if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) { | 839 | if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) { |
| 837 | __ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS); | 840 | __ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS); |
| 838 | return; | 841 | return; |
| 839 | } | 842 | } |
| 840 | 843 | ||
| @@ -868,7 +871,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb) · 27 unmodified lines | |||
| 868 | struct net *net; | 871 | struct net *net; |
| 869 | u32 info = 0; | 872 | u32 info = 0; |
| 870 | 873 | ||
| 871 | net = dev_net(skb_dst(skb)->dev); | 874 | net = dev_net_rcu(skb_dst(skb)->dev); |
| 872 | 875 | ||
| 873 | /* | 876 | /* |
| 874 | * Incomplete header ? | 877 | * Incomplete header ? |
| @@ -979,7 +982,7 @@ out_err: · 104 unmodified lines | |||
| 979 | static enum skb_drop_reason icmp_redirect(struct sk_buff *skb) | 982 | static enum skb_drop_reason icmp_redirect(struct sk_buff *skb) |
| 980 | { | 983 | { |
| 981 | if (skb->len < sizeof(struct iphdr)) { | 984 | if (skb->len < sizeof(struct iphdr)) { |
| 982 | __ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS); | 985 | __ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS); |
| 983 | return SKB_DROP_REASON_PKT_TOO_SMALL; | 986 | return SKB_DROP_REASON_PKT_TOO_SMALL; |
| 984 | } | 987 | } |
| 985 | 988 | ||
| @@ -1011,7 +1014,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb) · 25 unmodified lines | |||
| 1011 | struct icmp_bxm icmp_param; | 1014 | struct icmp_bxm icmp_param; |
| 1012 | struct net *net; | 1015 | struct net *net; |
| 1013 | 1016 | ||
| 1014 | net = dev_net(skb_dst(skb)->dev); | 1017 | net = dev_net_rcu(skb_dst(skb)->dev); |
| 1015 | /* should there be an ICMP stat for ignored echos? */ | 1018 | /* should there be an ICMP stat for ignored echos? */ |
| 1016 | if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all)) | 1019 | if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all)) |
| 1017 | return SKB_NOT_DROPPED_YET; | 1020 | return SKB_NOT_DROPPED_YET; |
| @@ -1040,9 +1043,9 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb) · 22 unmodified lines | |||
| 1040 | 1043 | ||
| 1041 | bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr) | 1044 | bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr) |
| 1042 | { | 1045 | { |
| 1046 | struct net *net = dev_net_rcu(skb->dev); | ||
| 1043 | struct icmp_ext_hdr *ext_hdr, _ext_hdr; | 1047 | struct icmp_ext_hdr *ext_hdr, _ext_hdr; |
| 1044 | struct icmp_ext_echo_iio *iio, _iio; | 1048 | struct icmp_ext_echo_iio *iio, _iio; |
| 1045 | struct net *net = dev_net(skb->dev); | ||
| 1046 | struct inet6_dev *in6_dev; | 1049 | struct inet6_dev *in6_dev; |
| 1047 | struct in_device *in_dev; | 1050 | struct in_device *in_dev; |
| 1048 | struct net_device *dev; | 1051 | struct net_device *dev; |
| @@ -1181,7 +1184,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb) · 132 unmodified lines | |||
| 1181 | return SKB_NOT_DROPPED_YET; | 1184 | return SKB_NOT_DROPPED_YET; |
| 1182 | 1185 | ||
| 1183 | out_err: | 1186 | out_err: |
| 1184 | __ICMP_INC_STATS(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS); | 1187 | __ICMP_INC_STATS(dev_net_rcu(skb_dst(skb)->dev), ICMP_MIB_INERRORS); |
| 1185 | return SKB_DROP_REASON_PKT_TOO_SMALL; | 1188 | return SKB_DROP_REASON_PKT_TOO_SMALL; |
| 1186 | } | 1189 | } |
| 1187 | 1190 | ||
| @@ -1198,7 +1201,7 @@ int icmp_rcv(struct sk_buff *skb) · 10 unmodified lines | |||
| 1198 | { | 1201 | { |
| 1199 | enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; | 1202 | enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; |
| 1200 | struct rtable *rt = skb_rtable(skb); | 1203 | struct rtable *rt = skb_rtable(skb); |
| 1201 | struct net *net = dev_net(rt->dst.dev); | 1204 | struct net *net = dev_net_rcu(rt->dst.dev); |
| 1202 | struct icmphdr *icmph; | 1205 | struct icmphdr *icmph; |
| 1203 | 1206 | ||
| 1204 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { | 1207 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { |
| @@ -1371,9 +1374,9 @@ int icmp_err(struct sk_buff *skb, u32 info) · 166 unmodified lines | |||
| 1371 | struct iphdr *iph = (struct iphdr *)skb->data; | 1374 | struct iphdr *iph = (struct iphdr *)skb->data; |
| 1372 | int offset = iph->ihl<<2; | 1375 | int offset = iph->ihl<<2; |
| 1373 | struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset); | 1376 | struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset); |
| 1377 | struct net *net = dev_net_rcu(skb->dev); | ||
| 1374 | int type = icmp_hdr(skb)->type; | 1378 | int type = icmp_hdr(skb)->type; |
| 1375 | int code = icmp_hdr(skb)->code; | 1379 | int code = icmp_hdr(skb)->code; |
| 1376 | struct net *net = dev_net(skb->dev); | ||
| 1377 | 1380 | ||
| 1378 | /* | 1381 | /* |
| 1379 | * Use ping_err to handle all icmp errors except those | 1382 | * Use ping_err to handle all icmp errors except those |
| @@ -390,7 +390,13 @@ static inline int ip_rt_proc_init(void) · 389 unmodified lines | |||
| 390 | 390 | ||
| 391 | static inline bool rt_is_expired(const struct rtable *rth) | 391 | static inline bool rt_is_expired(const struct rtable *rth) |
| 392 | { | 392 | { |
| 393 | return rth->rt_genid != rt_genid_ipv4(dev_net(rth->dst.dev)); | 393 | bool res; |
| 394 | |||
| 395 | rcu_read_lock(); | ||
| 396 | res = rth->rt_genid != rt_genid_ipv4(dev_net_rcu(rth->dst.dev)); | ||
| 397 | rcu_read_unlock(); | ||
| 398 | |||
| 399 | return res; | ||
| 394 | } | 400 | } |
| 395 | 401 | ||
| 396 | void rt_cache_flush(struct net *net) | 402 | void rt_cache_flush(struct net *net) |
| @@ -1002,9 +1008,9 @@ out: kfree_skb_reason(skb, reason); · 605 unmodified lines | |||
| 1002 | static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) | 1008 | static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) |
| 1003 | { | 1009 | { |
| 1004 | struct dst_entry *dst = &rt->dst; | 1010 | struct dst_entry *dst = &rt->dst; |
| 1005 | struct net *net = dev_net(dst->dev); | ||
| 1006 | struct fib_result res; | 1011 | struct fib_result res; |
| 1007 | bool lock = false; | 1012 | bool lock = false; |
| 1013 | struct net *net; | ||
| 1008 | u32 old_mtu; | 1014 | u32 old_mtu; |
| 1009 | 1015 | ||
| 1010 | if (ip_mtu_locked(dst)) | 1016 | if (ip_mtu_locked(dst)) |
| @@ -1014,6 +1020,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) · 3 unmodified lines | |||
| 1014 | if (old_mtu < mtu) | 1020 | if (old_mtu < mtu) |
| 1015 | return; | 1021 | return; |
| 1016 | 1022 | ||
| 1023 | rcu_read_lock(); | ||
| 1024 | net = dev_net_rcu(dst->dev); | ||
| 1017 | if (mtu < net->ipv4.ip_rt_min_pmtu) { | 1025 | if (mtu < net->ipv4.ip_rt_min_pmtu) { |
| 1018 | lock = true; | 1026 | lock = true; |
| 1019 | mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu); | 1027 | mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu); |
| @@ -1021,9 +1029,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) · 1 unmodified line | |||
| 1021 | 1029 | ||
| 1022 | if (rt->rt_pmtu == mtu && !lock && | 1030 | if (rt->rt_pmtu == mtu && !lock && |
| 1023 | time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2)) | 1031 | time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2)) |
| 1024 | return; | 1032 | goto out; |
| 1025 | 1033 | ||
| 1026 | rcu_read_lock(); | ||
| 1027 | if (fib_lookup(net, fl4, &res, 0) == 0) { | 1034 | if (fib_lookup(net, fl4, &res, 0) == 0) { |
| 1028 | struct fib_nh_common *nhc; | 1035 | struct fib_nh_common *nhc; |
| 1029 | 1036 | ||
| @@ -1037,14 +1044,14 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) · 7 unmodified lines | |||
| 1037 | update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, | 1044 | update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, |
| 1038 | jiffies + net->ipv4.ip_rt_mtu_expires); | 1045 | jiffies + net->ipv4.ip_rt_mtu_expires); |
| 1039 | } | 1046 | } |
| 1040 | rcu_read_unlock(); | 1047 | goto out; |
| 1041 | return; | ||
| 1042 | } | 1048 | } |
| 1043 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ | 1049 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ |
| 1044 | nhc = FIB_RES_NHC(res); | 1050 | nhc = FIB_RES_NHC(res); |
| 1045 | update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, | 1051 | update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, |
| 1046 | jiffies + net->ipv4.ip_rt_mtu_expires); | 1052 | jiffies + net->ipv4.ip_rt_mtu_expires); |
| 1047 | } | 1053 | } |
| 1054 | out: | ||
| 1048 | rcu_read_unlock(); | 1055 | rcu_read_unlock(); |
| 1049 | } | 1056 | } |
| 1050 | 1057 | ||
| @@ -1307,10 +1314,15 @@ static void set_class_tag(struct rtable *rt, u32 tag) · 256 unmodified lines | |||
| 1307 | 1314 | ||
| 1308 | static unsigned int ipv4_default_advmss(const struct dst_entry *dst) | 1315 | static unsigned int ipv4_default_advmss(const struct dst_entry *dst) |
| 1309 | { | 1316 | { |
| 1310 | struct net *net = dev_net(dst->dev); | ||
| 1311 | unsigned int header_size = sizeof(struct tcphdr) + sizeof(struct iphdr); | 1317 | unsigned int header_size = sizeof(struct tcphdr) + sizeof(struct iphdr); |
| 1312 | unsigned int advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, | 1318 | unsigned int advmss; |
| 1313 | net->ipv4.ip_rt_min_advmss); | 1319 | struct net *net; |
| 1320 | |||
| 1321 | rcu_read_lock(); | ||
| 1322 | net = dev_net_rcu(dst->dev); | ||
| 1323 | advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, | ||
| 1324 | net->ipv4.ip_rt_min_advmss); | ||
| 1325 | rcu_read_unlock(); | ||
| 1314 | 1326 | ||
| 1315 | return min(advmss, IPV4_MAX_PMTU - header_size); | 1327 | return min(advmss, IPV4_MAX_PMTU - header_size); |
| 1316 | } | 1328 | } |
| @@ -76,7 +76,7 @@ static int icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 75 unmodified lines | |||
| 76 | { | 76 | { |
| 77 | /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ | 77 | /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ |
| 78 | struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset); | 78 | struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset); |
| 79 | struct net *net = dev_net(skb->dev); | 79 | struct net *net = dev_net_rcu(skb->dev); |
| 80 | 80 | ||
| 81 | if (type == ICMPV6_PKT_TOOBIG) | 81 | if (type == ICMPV6_PKT_TOOBIG) |
| 82 | ip6_update_pmtu(skb, net, info, skb->dev->ifindex, 0, sock_net_uid(net, NULL)); | 82 | ip6_update_pmtu(skb, net, info, skb->dev->ifindex, 0, sock_net_uid(net, NULL)); |
| @@ -473,7 +473,10 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 390 unmodified lines | |||
| 473 | 473 | ||
| 474 | if (!skb->dev) | 474 | if (!skb->dev) |
| 475 | return; | 475 | return; |
| 476 | net = dev_net(skb->dev); | 476 | |
| 477 | rcu_read_lock(); | ||
| 478 | |||
| 479 | net = dev_net_rcu(skb->dev); | ||
| 477 | mark = IP6_REPLY_MARK(net, skb->mark); | 480 | mark = IP6_REPLY_MARK(net, skb->mark); |
| 478 | /* | 481 | /* |
| 479 | * Make sure we respect the rules | 482 | * Make sure we respect the rules |
| @@ -496,7 +499,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 16 unmodified lines | |||
| 496 | !(type == ICMPV6_PARAMPROB && | 499 | !(type == ICMPV6_PARAMPROB && |
| 497 | code == ICMPV6_UNK_OPTION && | 500 | code == ICMPV6_UNK_OPTION && |
| 498 | (opt_unrec(skb, info)))) | 501 | (opt_unrec(skb, info)))) |
| 499 | return; | 502 | goto out; |
| 500 | 503 | ||
| 501 | saddr = NULL; | 504 | saddr = NULL; |
| 502 | } | 505 | } |
| @@ -526,7 +529,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 23 unmodified lines | |||
| 526 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { | 529 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { |
| 527 | net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n", | 530 | net_dbg_ratelimited("icmp6_send: addr_any/mcast source [%pI6c > %pI6c]\n", |
| 528 | &hdr->saddr, &hdr->daddr); | 531 | &hdr->saddr, &hdr->daddr); |
| 529 | return; | 532 | goto out; |
| 530 | } | 533 | } |
| 531 | 534 | ||
| 532 | /* | 535 | /* |
| @@ -535,7 +538,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 2 unmodified lines | |||
| 535 | if (is_ineligible(skb)) { | 538 | if (is_ineligible(skb)) { |
| 536 | net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n", | 539 | net_dbg_ratelimited("icmp6_send: no reply to icmp error [%pI6c > %pI6c]\n", |
| 537 | &hdr->saddr, &hdr->daddr); | 540 | &hdr->saddr, &hdr->daddr); |
| 538 | return; | 541 | goto out; |
| 539 | } | 542 | } |
| 540 | 543 | ||
| 541 | /* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */ | 544 | /* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */ |
| @@ -582,7 +585,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 40 unmodified lines | |||
| 582 | np = inet6_sk(sk); | 585 | np = inet6_sk(sk); |
| 583 | 586 | ||
| 584 | if (!icmpv6_xrlim_allow(sk, type, &fl6, apply_ratelimit)) | 587 | if (!icmpv6_xrlim_allow(sk, type, &fl6, apply_ratelimit)) |
| 585 | goto out; | 588 | goto out_unlock; |
| 586 | 589 | ||
| 587 | tmp_hdr.icmp6_type = type; | 590 | tmp_hdr.icmp6_type = type; |
| 588 | tmp_hdr.icmp6_code = code; | 591 | tmp_hdr.icmp6_code = code; |
| @@ -600,7 +603,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 11 unmodified lines | |||
| 600 | 603 | ||
| 601 | dst = icmpv6_route_lookup(net, skb, sk, &fl6); | 604 | dst = icmpv6_route_lookup(net, skb, sk, &fl6); |
| 602 | if (IS_ERR(dst)) | 605 | if (IS_ERR(dst)) |
| 603 | goto out; | 606 | goto out_unlock; |
| 604 | 607 | ||
| 605 | ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); | 608 | ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); |
| 606 | 609 | ||
| @@ -616,7 +619,6 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 9 unmodified lines | |||
| 616 | goto out_dst_release; | 619 | goto out_dst_release; |
| 617 | } | 620 | } |
| 618 | 621 | ||
| 619 | rcu_read_lock(); | ||
| 620 | idev = __in6_dev_get(skb->dev); | 622 | idev = __in6_dev_get(skb->dev); |
| 621 | 623 | ||
| 622 | if (ip6_append_data(sk, icmpv6_getfrag, &msg, | 624 | if (ip6_append_data(sk, icmpv6_getfrag, &msg, |
| @@ -630,13 +632,15 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 7 unmodified lines | |||
| 630 | icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, | 632 | icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, |
| 631 | len + sizeof(struct icmp6hdr)); | 633 | len + sizeof(struct icmp6hdr)); |
| 632 | } | 634 | } |
| 633 | rcu_read_unlock(); | 635 | |
| 634 | out_dst_release: | 636 | out_dst_release: |
| 635 | dst_release(dst); | 637 | dst_release(dst); |
| 636 | out: | 638 | out_unlock: |
| 637 | icmpv6_xmit_unlock(sk); | 639 | icmpv6_xmit_unlock(sk); |
| 638 | out_bh_enable: | 640 | out_bh_enable: |
| 639 | local_bh_enable(); | 641 | local_bh_enable(); |
| 642 | out: | ||
| 643 | rcu_read_unlock(); | ||
| 640 | } | 644 | } |
| 641 | EXPORT_SYMBOL(icmp6_send); | 645 | EXPORT_SYMBOL(icmp6_send); |
| 642 | 646 | ||
| @@ -679,8 +683,8 @@ int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type, · 36 unmodified lines | |||
| 679 | skb_pull(skb2, nhs); | 683 | skb_pull(skb2, nhs); |
| 680 | skb_reset_network_header(skb2); | 684 | skb_reset_network_header(skb2); |
| 681 | 685 | ||
| 682 | rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, | 686 | rt = rt6_lookup(dev_net_rcu(skb->dev), &ipv6_hdr(skb2)->saddr, |
| 683 | skb, 0); | 687 | NULL, 0, skb, 0); |
| 684 | 688 | ||
| 685 | if (rt && rt->dst.dev) | 689 | if (rt && rt->dst.dev) |
| 686 | skb2->dev = rt->dst.dev; | 690 | skb2->dev = rt->dst.dev; |
| @@ -717,7 +721,7 @@ EXPORT_SYMBOL(ip6_err_gen_icmpv6_unreach); · 30 unmodified lines | |||
| 717 | 721 | ||
| 718 | static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb) | 722 | static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb) |
| 719 | { | 723 | { |
| 720 | struct net *net = dev_net(skb->dev); | 724 | struct net *net = dev_net_rcu(skb->dev); |
| 721 | struct sock *sk; | 725 | struct sock *sk; |
| 722 | struct inet6_dev *idev; | 726 | struct inet6_dev *idev; |
| 723 | struct ipv6_pinfo *np; | 727 | struct ipv6_pinfo *np; |
| @@ -832,7 +836,7 @@ enum skb_drop_reason icmpv6_notify(struct sk_buff *skb, u8 type, · 108 unmodified lines | |||
| 832 | u8 code, __be32 info) | 836 | u8 code, __be32 info) |
| 833 | { | 837 | { |
| 834 | struct inet6_skb_parm *opt = IP6CB(skb); | 838 | struct inet6_skb_parm *opt = IP6CB(skb); |
| 835 | struct net *net = dev_net(skb->dev); | 839 | struct net *net = dev_net_rcu(skb->dev); |
| 836 | const struct inet6_protocol *ipprot; | 840 | const struct inet6_protocol *ipprot; |
| 837 | enum skb_drop_reason reason; | 841 | enum skb_drop_reason reason; |
| 838 | int inner_offset; | 842 | int inner_offset; |
| @@ -889,7 +893,7 @@ out: · 50 unmodified lines | |||
| 889 | static int icmpv6_rcv(struct sk_buff *skb) | 893 | static int icmpv6_rcv(struct sk_buff *skb) |
| 890 | { | 894 | { |
| 891 | enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; | 895 | enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; |
| 892 | struct net *net = dev_net(skb->dev); | 896 | struct net *net = dev_net_rcu(skb->dev); |
| 893 | struct net_device *dev = icmp6_dev(skb); | 897 | struct net_device *dev = icmp6_dev(skb); |
| 894 | struct inet6_dev *idev = __in6_dev_get(dev); | 898 | struct inet6_dev *idev = __in6_dev_get(dev); |
| 895 | const struct in6_addr *saddr, *daddr; | 899 | const struct in6_addr *saddr, *daddr; |
| @@ -921,7 +925,7 @@ static int icmpv6_rcv(struct sk_buff *skb) · 25 unmodified lines | |||
| 921 | skb_set_network_header(skb, nh); | 925 | skb_set_network_header(skb, nh); |
| 922 | } | 926 | } |
| 923 | 927 | ||
| 924 | __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_INMSGS); | 928 | __ICMP6_INC_STATS(dev_net_rcu(dev), idev, ICMP6_MIB_INMSGS); |
| 925 | 929 | ||
| 926 | saddr = &ipv6_hdr(skb)->saddr; | 930 | saddr = &ipv6_hdr(skb)->saddr; |
| 927 | daddr = &ipv6_hdr(skb)->daddr; | 931 | daddr = &ipv6_hdr(skb)->daddr; |
| @@ -939,7 +943,7 @@ static int icmpv6_rcv(struct sk_buff *skb) · 11 unmodified lines | |||
| 939 | 943 | ||
| 940 | type = hdr->icmp6_type; | 944 | type = hdr->icmp6_type; |
| 941 | 945 | ||
| 942 | ICMP6MSGIN_INC_STATS(dev_net(dev), idev, type); | 946 | ICMP6MSGIN_INC_STATS(dev_net_rcu(dev), idev, type); |
| 943 | 947 | ||
| 944 | switch (type) { | 948 | switch (type) { |
| 945 | case ICMPV6_ECHO_REQUEST: | 949 | case ICMPV6_ECHO_REQUEST: |
| @@ -1034,9 +1038,9 @@ static int icmpv6_rcv(struct sk_buff *skb) · 88 unmodified lines | |||
| 1034 | 1038 | ||
| 1035 | csum_error: | 1039 | csum_error: |
| 1036 | reason = SKB_DROP_REASON_ICMP_CSUM; | 1040 | reason = SKB_DROP_REASON_ICMP_CSUM; |
| 1037 | __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS); | 1041 | __ICMP6_INC_STATS(dev_net_rcu(dev), idev, ICMP6_MIB_CSUMERRORS); |
| 1038 | discard_it: | 1042 | discard_it: |
| 1039 | __ICMP6_INC_STATS(dev_net(dev), idev, ICMP6_MIB_INERRORS); | 1043 | __ICMP6_INC_STATS(dev_net_rcu(dev), idev, ICMP6_MIB_INERRORS); |
| 1040 | drop_no_count: | 1044 | drop_no_count: |
| 1041 | kfree_skb_reason(skb, reason); | 1045 | kfree_skb_reason(skb, reason); |
| 1042 | return 0; | 1046 | return 0; |
| @@ -477,9 +477,7 @@ discard: · 476 unmodified lines | |||
| 477 | static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | 477 | static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
| 478 | { | 478 | { |
| 479 | skb_clear_delivery_time(skb); | 479 | skb_clear_delivery_time(skb); |
| 480 | rcu_read_lock(); | ||
| 481 | ip6_protocol_deliver_rcu(net, skb, 0, false); | 480 | ip6_protocol_deliver_rcu(net, skb, 0, false); |
| 482 | rcu_read_unlock(); | ||
| 483 | 481 | ||
| 484 | return 0; | 482 | return 0; |
| 485 | } | 483 | } |
| @@ -487,9 +485,15 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk · 1 unmodified line | |||
| 487 | 485 | ||
| 488 | int ip6_input(struct sk_buff *skb) | 486 | int ip6_input(struct sk_buff *skb) |
| 489 | { | 487 | { |
| 490 | return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN, | 488 | int res; |
| 491 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, | 489 | |
| 492 | ip6_input_finish); | 490 | rcu_read_lock(); |
| 491 | res = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN, | ||
| 492 | dev_net_rcu(skb->dev), NULL, skb, skb->dev, NULL, | ||
| 493 | ip6_input_finish); | ||
| 494 | rcu_read_unlock(); | ||
| 495 | |||
| 496 | return res; | ||
| 493 | } | 497 | } |
| 494 | EXPORT_SYMBOL_GPL(ip6_input); | 498 | EXPORT_SYMBOL_GPL(ip6_input); |
| 495 | 499 | ||
| @@ -1773,21 +1773,19 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) · 1772 unmodified lines | |||
| 1773 | struct net_device *dev = idev->dev; | 1773 | struct net_device *dev = idev->dev; |
| 1774 | int hlen = LL_RESERVED_SPACE(dev); | 1774 | int hlen = LL_RESERVED_SPACE(dev); |
| 1775 | int tlen = dev->needed_tailroom; | 1775 | int tlen = dev->needed_tailroom; |
| 1776 | struct net *net = dev_net(dev); | ||
| 1777 | const struct in6_addr *saddr; | 1776 | const struct in6_addr *saddr; |
| 1778 | struct in6_addr addr_buf; | 1777 | struct in6_addr addr_buf; |
| 1779 | struct mld2_report *pmr; | 1778 | struct mld2_report *pmr; |
| 1780 | struct sk_buff *skb; | 1779 | struct sk_buff *skb; |
| 1781 | unsigned int size; | 1780 | unsigned int size; |
| 1782 | struct sock *sk; | 1781 | struct sock *sk; |
| 1783 | int err; | 1782 | struct net *net; |
| 1784 | 1783 | ||
| 1785 | sk = net->ipv6.igmp_sk; | ||
| 1786 | /* we assume size > sizeof(ra) here | 1784 | /* we assume size > sizeof(ra) here |
| 1787 | * Also try to not allocate high-order pages for big MTU | 1785 | * Also try to not allocate high-order pages for big MTU |
| 1788 | */ | 1786 | */ |
| 1789 | size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen; | 1787 | size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen; |
| 1790 | skb = sock_alloc_send_skb(sk, size, 1, &err); | 1788 | skb = alloc_skb(size, GFP_KERNEL); |
| 1791 | if (!skb) | 1789 | if (!skb) |
| 1792 | return NULL; | 1790 | return NULL; |
| 1793 | 1791 | ||
| @@ -1795,6 +1793,12 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) · 1 unmodified line | |||
| 1795 | skb_reserve(skb, hlen); | 1793 | skb_reserve(skb, hlen); |
| 1796 | skb_tailroom_reserve(skb, mtu, tlen); | 1794 | skb_tailroom_reserve(skb, mtu, tlen); |
| 1797 | 1795 | ||
| 1796 | rcu_read_lock(); | ||
| 1797 | |||
| 1798 | net = dev_net_rcu(dev); | ||
| 1799 | sk = net->ipv6.igmp_sk; | ||
| 1800 | skb_set_owner_w(skb, sk); | ||
| 1801 | |||
| 1798 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { | 1802 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { |
| 1799 | /* <draft-ietf-magma-mld-source-05.txt>: | 1803 | /* <draft-ietf-magma-mld-source-05.txt>: |
| 1800 | * use unspecified address as the source address | 1804 | * use unspecified address as the source address |
| @@ -1806,6 +1810,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) · 5 unmodified lines | |||
| 1806 | 1810 | ||
| 1807 | ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0); | 1811 | ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0); |
| 1808 | 1812 | ||
| 1813 | rcu_read_unlock(); | ||
| 1814 | |||
| 1809 | skb_put_data(skb, ra, sizeof(ra)); | 1815 | skb_put_data(skb, ra, sizeof(ra)); |
| 1810 | 1816 | ||
| 1811 | skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); | 1817 | skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); |
| @@ -2165,21 +2171,21 @@ static void mld_send_cr(struct inet6_dev *idev) · 353 unmodified lines | |||
| 2165 | 2171 | ||
| 2166 | static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | 2172 | static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) |
| 2167 | { | 2173 | { |
| 2168 | struct net *net = dev_net(dev); | 2174 | const struct in6_addr *snd_addr, *saddr; |
| 2169 | struct sock *sk = net->ipv6.igmp_sk; | 2175 | int err, len, payload_len, full_len; |
| 2176 | struct in6_addr addr_buf; | ||
| 2170 | struct inet6_dev *idev; | 2177 | struct inet6_dev *idev; |
| 2171 | struct sk_buff *skb; | 2178 | struct sk_buff *skb; |
| 2172 | struct mld_msg *hdr; | 2179 | struct mld_msg *hdr; |
| 2173 | const struct in6_addr *snd_addr, *saddr; | ||
| 2174 | struct in6_addr addr_buf; | ||
| 2175 | int hlen = LL_RESERVED_SPACE(dev); | 2180 | int hlen = LL_RESERVED_SPACE(dev); |
| 2176 | int tlen = dev->needed_tailroom; | 2181 | int tlen = dev->needed_tailroom; |
| 2177 | int err, len, payload_len, full_len; | ||
| 2178 | u8 ra[8] = { IPPROTO_ICMPV6, 0, | 2182 | u8 ra[8] = { IPPROTO_ICMPV6, 0, |
| 2179 | IPV6_TLV_ROUTERALERT, 2, 0, 0, | 2183 | IPV6_TLV_ROUTERALERT, 2, 0, 0, |
| 2180 | IPV6_TLV_PADN, 0 }; | 2184 | IPV6_TLV_PADN, 0 }; |
| 2181 | struct flowi6 fl6; | ||
| 2182 | struct dst_entry *dst; | 2185 | struct dst_entry *dst; |
| 2186 | struct flowi6 fl6; | ||
| 2187 | struct net *net; | ||
| 2188 | struct sock *sk; | ||
| 2183 | 2189 | ||
| 2184 | if (type == ICMPV6_MGM_REDUCTION) | 2190 | if (type == ICMPV6_MGM_REDUCTION) |
| 2185 | snd_addr = &in6addr_linklocal_allrouters; | 2191 | snd_addr = &in6addr_linklocal_allrouters; |
| @@ -2190,19 +2196,21 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) · 4 unmodified lines | |||
| 2190 | payload_len = len + sizeof(ra); | 2196 | payload_len = len + sizeof(ra); |
| 2191 | full_len = sizeof(struct ipv6hdr) + payload_len; | 2197 | full_len = sizeof(struct ipv6hdr) + payload_len; |
| 2192 | 2198 | ||
| 2193 | rcu_read_lock(); | 2199 | skb = alloc_skb(hlen + tlen + full_len, GFP_KERNEL); |
| 2194 | IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_OUTREQUESTS); | ||
| 2195 | rcu_read_unlock(); | ||
| 2196 | 2200 | ||
| 2197 | skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err); | 2201 | rcu_read_lock(); |
| 2198 | 2202 | ||
| 2203 | net = dev_net_rcu(dev); | ||
| 2204 | idev = __in6_dev_get(dev); | ||
| 2205 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); | ||
| 2199 | if (!skb) { | 2206 | if (!skb) { |
| 2200 | rcu_read_lock(); | 2207 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); |
| 2201 | IP6_INC_STATS(net, __in6_dev_get(dev), | ||
| 2202 | IPSTATS_MIB_OUTDISCARDS); | ||
| 2203 | rcu_read_unlock(); | 2208 | rcu_read_unlock(); |
| 2204 | return; | 2209 | return; |
| 2205 | } | 2210 | } |
| 2211 | sk = net->ipv6.igmp_sk; | ||
| 2212 | skb_set_owner_w(skb, sk); | ||
| 2213 | |||
| 2206 | skb->priority = TC_PRIO_CONTROL; | 2214 | skb->priority = TC_PRIO_CONTROL; |
| 2207 | skb_reserve(skb, hlen); | 2215 | skb_reserve(skb, hlen); |
| 2208 | 2216 | ||
| @@ -2227,9 +2235,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) · 18 unmodified lines | |||
| 2227 | IPPROTO_ICMPV6, | 2235 | IPPROTO_ICMPV6, |
| 2228 | csum_partial(hdr, len, 0)); | 2236 | csum_partial(hdr, len, 0)); |
| 2229 | 2237 | ||
| 2230 | rcu_read_lock(); | ||
| 2231 | idev = __in6_dev_get(skb->dev); | ||
| 2232 | |||
| 2233 | icmpv6_flow_init(sk, &fl6, type, | 2238 | icmpv6_flow_init(sk, &fl6, type, |
| 2234 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, | 2239 | &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, |
| 2235 | skb->dev->ifindex); | 2240 | skb->dev->ifindex); |
| @@ -418,15 +418,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, · 417 unmodified lines | |||
| 418 | { | 418 | { |
| 419 | int hlen = LL_RESERVED_SPACE(dev); | 419 | int hlen = LL_RESERVED_SPACE(dev); |
| 420 | int tlen = dev->needed_tailroom; | 420 | int tlen = dev->needed_tailroom; |
| 421 | struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; | ||
| 422 | struct sk_buff *skb; | 421 | struct sk_buff *skb; |
| 423 | 422 | ||
| 424 | skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); | 423 | skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); |
| 425 | if (!skb) { | 424 | if (!skb) |
| 426 | ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n", | ||
| 427 | __func__); | ||
| 428 | return NULL; | 425 | return NULL; |
| 429 | } | ||
| 430 | 426 | ||
| 431 | skb->protocol = htons(ETH_P_IPV6); | 427 | skb->protocol = htons(ETH_P_IPV6); |
| 432 | skb->dev = dev; | 428 | skb->dev = dev; |
| @@ -437,7 +433,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, · 4 unmodified lines | |||
| 437 | /* Manually assign socket ownership as we avoid calling | 433 | /* Manually assign socket ownership as we avoid calling |
| 438 | * sock_alloc_send_pskb() to bypass wmem buffer limits | 434 | * sock_alloc_send_pskb() to bypass wmem buffer limits |
| 439 | */ | 435 | */ |
| 440 | skb_set_owner_w(skb, sk); | 436 | rcu_read_lock(); |
| 437 | skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk); | ||
| 438 | rcu_read_unlock(); | ||
| 441 | 439 | ||
| 442 | return skb; | 440 | return skb; |
| 443 | } | 441 | } |
| @@ -473,16 +471,20 @@ static void ip6_nd_hdr(struct sk_buff *skb, · 29 unmodified lines | |||
| 473 | void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, | 471 | void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, |
| 474 | const struct in6_addr *saddr) | 472 | const struct in6_addr *saddr) |
| 475 | { | 473 | { |
| 474 | struct icmp6hdr *icmp6h = icmp6_hdr(skb); | ||
| 476 | struct dst_entry *dst = skb_dst(skb); | 475 | struct dst_entry *dst = skb_dst(skb); |
| 477 | struct net *net = dev_net(skb->dev); | ||
| 478 | struct sock *sk = net->ipv6.ndisc_sk; | ||
| 479 | struct inet6_dev *idev; | 476 | struct inet6_dev *idev; |
| 477 | struct net *net; | ||
| 478 | struct sock *sk; | ||
| 480 | int err; | 479 | int err; |
| 481 | struct icmp6hdr *icmp6h = icmp6_hdr(skb); | ||
| 482 | u8 type; | 480 | u8 type; |
| 483 | 481 | ||
| 484 | type = icmp6h->icmp6_type; | 482 | type = icmp6h->icmp6_type; |
| 485 | 483 | ||
| 484 | rcu_read_lock(); | ||
| 485 | |||
| 486 | net = dev_net_rcu(skb->dev); | ||
| 487 | sk = net->ipv6.ndisc_sk; | ||
| 486 | if (!dst) { | 488 | if (!dst) { |
| 487 | struct flowi6 fl6; | 489 | struct flowi6 fl6; |
| 488 | int oif = skb->dev->ifindex; | 490 | int oif = skb->dev->ifindex; |
| @@ -490,6 +492,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, · 1 unmodified line | |||
| 490 | icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif); | 492 | icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif); |
| 491 | dst = icmp6_dst_alloc(skb->dev, &fl6); | 493 | dst = icmp6_dst_alloc(skb->dev, &fl6); |
| 492 | if (IS_ERR(dst)) { | 494 | if (IS_ERR(dst)) { |
| 495 | rcu_read_unlock(); | ||
| 493 | kfree_skb(skb); | 496 | kfree_skb(skb); |
| 494 | return; | 497 | return; |
| 495 | } | 498 | } |
| @@ -504,7 +507,6 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, · 8 unmodified lines | |||
| 504 | 507 | ||
| 505 | ip6_nd_hdr(skb, saddr, daddr, READ_ONCE(inet6_sk(sk)->hop_limit), skb->len); | 508 | ip6_nd_hdr(skb, saddr, daddr, READ_ONCE(inet6_sk(sk)->hop_limit), skb->len); |
| 506 | 509 | ||
| 507 | rcu_read_lock(); | ||
| 508 | idev = __in6_dev_get(dst->dev); | 510 | idev = __in6_dev_get(dst->dev); |
| 509 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); | 511 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); |
| 510 | 512 | ||
| @@ -1694,7 +1696,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) · 1183 unmodified lines | |||
| 1694 | bool ret; | 1696 | bool ret; |
| 1695 | 1697 | ||
| 1696 | if (netif_is_l3_master(skb->dev)) { | 1698 | if (netif_is_l3_master(skb->dev)) { |
| 1697 | dev = __dev_get_by_index(dev_net(skb->dev), IPCB(skb)->iif); | 1699 | dev = dev_get_by_index_rcu(dev_net(skb->dev), IPCB(skb)->iif); |
| 1698 | if (!dev) | 1700 | if (!dev) |
| 1699 | return; | 1701 | return; |
| 1700 | } | 1702 | } |
| @@ -3196,13 +3196,18 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) · 3195 unmodified lines | |||
| 3196 | { | 3196 | { |
| 3197 | struct net_device *dev = dst->dev; | 3197 | struct net_device *dev = dst->dev; |
| 3198 | unsigned int mtu = dst_mtu(dst); | 3198 | unsigned int mtu = dst_mtu(dst); |
| 3199 | struct net *net = dev_net(dev); | 3199 | struct net *net; |
| 3200 | 3200 | ||
| 3201 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); | 3201 | mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); |
| 3202 | 3202 | ||
| 3203 | rcu_read_lock(); | ||
| 3204 | |||
| 3205 | net = dev_net_rcu(dev); | ||
| 3203 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) | 3206 | if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) |
| 3204 | mtu = net->ipv6.sysctl.ip6_rt_min_advmss; | 3207 | mtu = net->ipv6.sysctl.ip6_rt_min_advmss; |
| 3205 | 3208 | ||
| 3209 | rcu_read_unlock(); | ||
| 3210 | |||
| 3206 | /* | 3211 | /* |
| 3207 | * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and | 3212 | * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and |
| 3208 | * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. | 3213 | * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. |
| @@ -381,10 +381,8 @@ static int nf_flow_offload_forward(struct nf_flowtable_ctx *ctx, · 380 unmodified lines | |||
| 381 | flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); | 381 | flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); |
| 382 | 382 | ||
| 383 | mtu = flow->tuplehash[dir].tuple.mtu + ctx->offset; | 383 | mtu = flow->tuplehash[dir].tuple.mtu + ctx->offset; |
| 384 | if (unlikely(nf_flow_exceeds_mtu(skb, mtu))) { | 384 | if (unlikely(nf_flow_exceeds_mtu(skb, mtu))) |
| 385 | flow_offload_teardown(flow); | ||
| 386 | return 0; | 385 | return 0; |
| 387 | } | ||
| 388 | 386 | ||
| 389 | iph = (struct iphdr *)(skb_network_header(skb) + ctx->offset); | 387 | iph = (struct iphdr *)(skb_network_header(skb) + ctx->offset); |
| 390 | thoff = (iph->ihl * 4) + ctx->offset; | 388 | thoff = (iph->ihl * 4) + ctx->offset; |
| @@ -662,10 +660,8 @@ static int nf_flow_offload_ipv6_forward(struct nf_flowtable_ctx *ctx, · 271 unmodified lines | |||
| 662 | flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); | 660 | flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); |
| 663 | 661 | ||
| 664 | mtu = flow->tuplehash[dir].tuple.mtu + ctx->offset; | 662 | mtu = flow->tuplehash[dir].tuple.mtu + ctx->offset; |
| 665 | if (unlikely(nf_flow_exceeds_mtu(skb, mtu))) { | 663 | if (unlikely(nf_flow_exceeds_mtu(skb, mtu))) |
| 666 | flow_offload_teardown(flow); | ||
| 667 | return 0; | 664 | return 0; |
| 668 | } | ||
| 669 | 665 | ||
| 670 | ip6h = (struct ipv6hdr *)(skb_network_header(skb) + ctx->offset); | 666 | ip6h = (struct ipv6hdr *)(skb_network_header(skb) + ctx->offset); |
| 671 | thoff = sizeof(*ip6h) + ctx->offset; | 667 | thoff = sizeof(*ip6h) + ctx->offset; |
| @@ -2101,6 +2101,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, · 2100 unmodified lines | |||
| 2101 | { | 2101 | { |
| 2102 | struct ovs_header *ovs_header; | 2102 | struct ovs_header *ovs_header; |
| 2103 | struct ovs_vport_stats vport_stats; | 2103 | struct ovs_vport_stats vport_stats; |
| 2104 | struct net *net_vport; | ||
| 2104 | int err; | 2105 | int err; |
| 2105 | 2106 | ||
| 2106 | ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family, | 2107 | ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family, |
| @@ -2117,12 +2118,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, · 10 unmodified lines | |||
| 2117 | nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex)) | 2118 | nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex)) |
| 2118 | goto nla_put_failure; | 2119 | goto nla_put_failure; |
| 2119 | 2120 | ||
| 2120 | if (!net_eq(net, dev_net(vport->dev))) { | 2121 | rcu_read_lock(); |
| 2121 | int id = peernet2id_alloc(net, dev_net(vport->dev), gfp); | 2122 | net_vport = dev_net_rcu(vport->dev); |
| 2123 | if (!net_eq(net, net_vport)) { | ||
| 2124 | int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC); | ||
| 2122 | 2125 | ||
| 2123 | if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id)) | 2126 | if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id)) |
| 2124 | goto nla_put_failure; | 2127 | goto nla_put_failure_unlock; |
| 2125 | } | 2128 | } |
| 2129 | rcu_read_unlock(); | ||
| 2126 | 2130 | ||
| 2127 | ovs_vport_get_stats(vport, &vport_stats); | 2131 | ovs_vport_get_stats(vport, &vport_stats); |
| 2128 | if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS, | 2132 | if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS, |
| @@ -2143,6 +2147,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, · 14 unmodified lines | |||
| 2143 | genlmsg_end(skb, ovs_header); | 2147 | genlmsg_end(skb, ovs_header); |
| 2144 | return 0; | 2148 | return 0; |
| 2145 | 2149 | ||
| 2150 | nla_put_failure_unlock: | ||
| 2151 | rcu_read_unlock(); | ||
| 2146 | nla_put_failure: | 2152 | nla_put_failure: |
| 2147 | err = -EMSGSIZE; | 2153 | err = -EMSGSIZE; |
| 2148 | error: | 2154 | error: |
| @@ -327,8 +327,8 @@ struct rxrpc_local { · 326 unmodified lines | |||
| 327 | * packet with a maximum set of jumbo subpackets or a PING ACK padded | 327 | * packet with a maximum set of jumbo subpackets or a PING ACK padded |
| 328 | * out to 64K with zeropages for PMTUD. | 328 | * out to 64K with zeropages for PMTUD. |
| 329 | */ | 329 | */ |
| 330 | struct kvec kvec[RXRPC_MAX_NR_JUMBO > 3 + 16 ? | 330 | struct kvec kvec[1 + RXRPC_MAX_NR_JUMBO > 3 + 16 ? |
| 331 | RXRPC_MAX_NR_JUMBO : 3 + 16]; | 331 | 1 + RXRPC_MAX_NR_JUMBO : 3 + 16]; |
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | /* | 334 | /* |
| @@ -874,8 +874,7 @@ struct rxrpc_txbuf { · 539 unmodified lines | |||
| 874 | #define RXRPC_TXBUF_RESENT 0x100 /* Set if has been resent */ | 874 | #define RXRPC_TXBUF_RESENT 0x100 /* Set if has been resent */ |
| 875 | __be16 cksum; /* Checksum to go in header */ | 875 | __be16 cksum; /* Checksum to go in header */ |
| 876 | bool jumboable; /* Can be non-terminal jumbo subpacket */ | 876 | bool jumboable; /* Can be non-terminal jumbo subpacket */ |
| 877 | u8 nr_kvec; /* Amount of kvec[] used */ | 877 | void *data; /* Data with preceding jumbo header */ |
| 878 | struct kvec kvec[1]; | ||
| 879 | }; | 878 | }; |
| 880 | 879 | ||
| 881 | static inline bool rxrpc_sending_to_server(const struct rxrpc_txbuf *txb) | 880 | static inline bool rxrpc_sending_to_server(const struct rxrpc_txbuf *txb) |
| @@ -428,13 +428,13 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call) · 427 unmodified lines | |||
| 428 | static size_t rxrpc_prepare_data_subpacket(struct rxrpc_call *call, | 428 | static size_t rxrpc_prepare_data_subpacket(struct rxrpc_call *call, |
| 429 | struct rxrpc_send_data_req *req, | 429 | struct rxrpc_send_data_req *req, |
| 430 | struct rxrpc_txbuf *txb, | 430 | struct rxrpc_txbuf *txb, |
| 431 | struct rxrpc_wire_header *whdr, | ||
| 431 | rxrpc_serial_t serial, int subpkt) | 432 | rxrpc_serial_t serial, int subpkt) |
| 432 | { | 433 | { |
| 433 | struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base; | 434 | struct rxrpc_jumbo_header *jumbo = txb->data - sizeof(*jumbo); |
| 434 | struct rxrpc_jumbo_header *jumbo = (void *)(whdr + 1) - sizeof(*jumbo); | ||
| 435 | enum rxrpc_req_ack_trace why; | 435 | enum rxrpc_req_ack_trace why; |
| 436 | struct rxrpc_connection *conn = call->conn; | 436 | struct rxrpc_connection *conn = call->conn; |
| 437 | struct kvec *kv = &call->local->kvec[subpkt]; | 437 | struct kvec *kv = &call->local->kvec[1 + subpkt]; |
| 438 | size_t len = txb->pkt_len; | 438 | size_t len = txb->pkt_len; |
| 439 | bool last; | 439 | bool last; |
| 440 | u8 flags; | 440 | u8 flags; |
| @@ -491,18 +491,15 @@ static size_t rxrpc_prepare_data_subpacket(struct rxrpc_call *call, · 50 unmodified lines | |||
| 491 | } | 491 | } |
| 492 | dont_set_request_ack: | 492 | dont_set_request_ack: |
| 493 | 493 | ||
| 494 | /* The jumbo header overlays the wire header in the txbuf. */ | 494 | /* There's a jumbo header prepended to the data if we need it. */ |
| 495 | if (subpkt < req->n - 1) | 495 | if (subpkt < req->n - 1) |
| 496 | flags |= RXRPC_JUMBO_PACKET; | 496 | flags |= RXRPC_JUMBO_PACKET; |
| 497 | else | 497 | else |
| 498 | flags &= ~RXRPC_JUMBO_PACKET; | 498 | flags &= ~RXRPC_JUMBO_PACKET; |
| 499 | if (subpkt == 0) { | 499 | if (subpkt == 0) { |
| 500 | whdr->flags = flags; | 500 | whdr->flags = flags; |
| 501 | whdr->serial = htonl(txb->serial); | ||
| 502 | whdr->cksum = txb->cksum; | 501 | whdr->cksum = txb->cksum; |
| 503 | whdr->serviceId = htons(conn->service_id); | 502 | kv->iov_base = txb->data; |
| 504 | kv->iov_base = whdr; | ||
| 505 | len += sizeof(*whdr); | ||
| 506 | } else { | 503 | } else { |
| 507 | jumbo->flags = flags; | 504 | jumbo->flags = flags; |
| 508 | jumbo->pad = 0; | 505 | jumbo->pad = 0; |
| @@ -535,7 +532,9 @@ static unsigned int rxrpc_prepare_txqueue(struct rxrpc_txqueue *tq, · 26 unmodified lines | |||
| 535 | /* | 532 | /* |
| 536 | * Prepare a (jumbo) packet for transmission. | 533 | * Prepare a (jumbo) packet for transmission. |
| 537 | */ | 534 | */ |
| 538 | static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, struct rxrpc_send_data_req *req) | 535 | static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, |
| 536 | struct rxrpc_send_data_req *req, | ||
| 537 | struct rxrpc_wire_header *whdr) | ||
| 539 | { | 538 | { |
| 540 | struct rxrpc_txqueue *tq = req->tq; | 539 | struct rxrpc_txqueue *tq = req->tq; |
| 541 | rxrpc_serial_t serial; | 540 | rxrpc_serial_t serial; |
| @@ -549,6 +548,18 @@ static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, struct rxrpc_se · 7 unmodified lines | |||
| 549 | /* Each transmission of a Tx packet needs a new serial number */ | 548 | /* Each transmission of a Tx packet needs a new serial number */ |
| 550 | serial = rxrpc_get_next_serials(call->conn, req->n); | 549 | serial = rxrpc_get_next_serials(call->conn, req->n); |
| 551 | 550 | ||
| 551 | whdr->epoch = htonl(call->conn->proto.epoch); | ||
| 552 | whdr->cid = htonl(call->cid); | ||
| 553 | whdr->callNumber = htonl(call->call_id); | ||
| 554 | whdr->seq = htonl(seq); | ||
| 555 | whdr->serial = htonl(serial); | ||
| 556 | whdr->type = RXRPC_PACKET_TYPE_DATA; | ||
| 557 | whdr->flags = 0; | ||
| 558 | whdr->userStatus = 0; | ||
| 559 | whdr->securityIndex = call->security_ix; | ||
| 560 | whdr->_rsvd = 0; | ||
| 561 | whdr->serviceId = htons(call->conn->service_id); | ||
| 562 | |||
| 552 | call->tx_last_serial = serial + req->n - 1; | 563 | call->tx_last_serial = serial + req->n - 1; |
| 553 | call->tx_last_sent = req->now; | 564 | call->tx_last_sent = req->now; |
| 554 | xmit_ts = rxrpc_prepare_txqueue(tq, req); | 565 | xmit_ts = rxrpc_prepare_txqueue(tq, req); |
| @@ -576,7 +587,7 @@ static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, struct rxrpc_se · 21 unmodified lines | |||
| 576 | if (i + 1 == req->n) | 587 | if (i + 1 == req->n) |
| 577 | /* Only sample the last subpacket in a jumbo. */ | 588 | /* Only sample the last subpacket in a jumbo. */ |
| 578 | __set_bit(ix, &tq->rtt_samples); | 589 | __set_bit(ix, &tq->rtt_samples); |
| 579 | len += rxrpc_prepare_data_subpacket(call, req, txb, serial, i); | 590 | len += rxrpc_prepare_data_subpacket(call, req, txb, whdr, serial, i); |
| 580 | serial++; | 591 | serial++; |
| 581 | seq++; | 592 | seq++; |
| 582 | i++; | 593 | i++; |
| @@ -618,6 +629,7 @@ static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, struct rxrpc_se · 35 unmodified lines | |||
| 618 | } | 629 | } |
| 619 | 630 | ||
| 620 | rxrpc_set_keepalive(call, req->now); | 631 | rxrpc_set_keepalive(call, req->now); |
| 632 | page_frag_free(whdr); | ||
| 621 | return len; | 633 | return len; |
| 622 | } | 634 | } |
| 623 | 635 | ||
| @@ -626,25 +638,33 @@ static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, struct rxrpc_se · 2 unmodified lines | |||
| 626 | */ | 638 | */ |
| 627 | void rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_send_data_req *req) | 639 | void rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_send_data_req *req) |
| 628 | { | 640 | { |
| 641 | struct rxrpc_wire_header *whdr; | ||
| 629 | struct rxrpc_connection *conn = call->conn; | 642 | struct rxrpc_connection *conn = call->conn; |
| 630 | enum rxrpc_tx_point frag; | 643 | enum rxrpc_tx_point frag; |
| 631 | struct rxrpc_txqueue *tq = req->tq; | 644 | struct rxrpc_txqueue *tq = req->tq; |
| 632 | struct rxrpc_txbuf *txb; | 645 | struct rxrpc_txbuf *txb; |
| 633 | struct msghdr msg; | 646 | struct msghdr msg; |
| 634 | rxrpc_seq_t seq = req->seq; | 647 | rxrpc_seq_t seq = req->seq; |
| 635 | size_t len; | 648 | size_t len = sizeof(*whdr); |
| 636 | bool new_call = test_bit(RXRPC_CALL_BEGAN_RX_TIMER, &call->flags); | 649 | bool new_call = test_bit(RXRPC_CALL_BEGAN_RX_TIMER, &call->flags); |
| 637 | int ret, stat_ix; | 650 | int ret, stat_ix; |
| 638 | 651 | ||
| 639 | _enter("%x,%x-%x", tq->qbase, seq, seq + req->n - 1); | 652 | _enter("%x,%x-%x", tq->qbase, seq, seq + req->n - 1); |
| 640 | 653 | ||
| 654 | whdr = page_frag_alloc(&call->local->tx_alloc, sizeof(*whdr), GFP_NOFS); | ||
| 655 | if (!whdr) | ||
| 656 | return; /* Drop the packet if no memory. */ | ||
| 657 | |||
| 658 | call->local->kvec[0].iov_base = whdr; | ||
| 659 | call->local->kvec[0].iov_len = sizeof(*whdr); | ||
| 660 | |||
| 641 | stat_ix = umin(req->n, ARRAY_SIZE(call->rxnet->stat_tx_jumbo)) - 1; | 661 | stat_ix = umin(req->n, ARRAY_SIZE(call->rxnet->stat_tx_jumbo)) - 1; |
| 642 | atomic_inc(&call->rxnet->stat_tx_jumbo[stat_ix]); | 662 | atomic_inc(&call->rxnet->stat_tx_jumbo[stat_ix]); |
| 643 | 663 | ||
| 644 | len = rxrpc_prepare_data_packet(call, req); | 664 | len += rxrpc_prepare_data_packet(call, req, whdr); |
| 645 | txb = tq->bufs[seq & RXRPC_TXQ_MASK]; | 665 | txb = tq->bufs[seq & RXRPC_TXQ_MASK]; |
| 646 | 666 | ||
| 647 | iov_iter_kvec(&msg.msg_iter, WRITE, call->local->kvec, req->n, len); | 667 | iov_iter_kvec(&msg.msg_iter, WRITE, call->local->kvec, 1 + req->n, len); |
| 648 | 668 | ||
| 649 | msg.msg_name = &call->peer->srx.transport; | 669 | msg.msg_name = &call->peer->srx.transport; |
| 650 | msg.msg_namelen = call->peer->srx.transport_len; | 670 | msg.msg_namelen = call->peer->srx.transport_len; |
| @@ -695,13 +715,13 @@ void rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_send_data_req · 44 unmodified lines | |||
| 695 | 715 | ||
| 696 | if (ret == -EMSGSIZE) { | 716 | if (ret == -EMSGSIZE) { |
| 697 | rxrpc_inc_stat(call->rxnet, stat_tx_data_send_msgsize); | 717 | rxrpc_inc_stat(call->rxnet, stat_tx_data_send_msgsize); |
| 698 | trace_rxrpc_tx_packet(call->debug_id, call->local->kvec[0].iov_base, frag); | 718 | trace_rxrpc_tx_packet(call->debug_id, whdr, frag); |
| 699 | ret = 0; | 719 | ret = 0; |
| 700 | } else if (ret < 0) { | 720 | } else if (ret < 0) { |
| 701 | rxrpc_inc_stat(call->rxnet, stat_tx_data_send_fail); | 721 | rxrpc_inc_stat(call->rxnet, stat_tx_data_send_fail); |
| 702 | trace_rxrpc_tx_fail(call->debug_id, txb->serial, ret, frag); | 722 | trace_rxrpc_tx_fail(call->debug_id, txb->serial, ret, frag); |
| 703 | } else { | 723 | } else { |
| 704 | trace_rxrpc_tx_packet(call->debug_id, call->local->kvec[0].iov_base, frag); | 724 | trace_rxrpc_tx_packet(call->debug_id, whdr, frag); |
| 705 | } | 725 | } |
| 706 | 726 | ||
| 707 | rxrpc_tx_backoff(call, ret); | 727 | rxrpc_tx_backoff(call, ret); |
| @@ -169,6 +169,13 @@ void rxrpc_input_error(struct rxrpc_local *local, struct sk_buff *skb) · 168 unmodified lines | |||
| 169 | goto out; | 169 | goto out; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | if ((serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6 && | ||
| 173 | serr->ee.ee_type == ICMPV6_PKT_TOOBIG && | ||
| 174 | serr->ee.ee_code == 0)) { | ||
| 175 | rxrpc_adjust_mtu(peer, serr->ee.ee_info); | ||
| 176 | goto out; | ||
| 177 | } | ||
| 178 | |||
| 172 | rxrpc_store_error(peer, skb); | 179 | rxrpc_store_error(peer, skb); |
| 173 | out: | 180 | out: |
| 174 | rxrpc_put_peer(peer, rxrpc_peer_put_input_error); | 181 | rxrpc_put_peer(peer, rxrpc_peer_put_input_error); |
| @@ -257,8 +257,7 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call, · 256 unmodified lines | |||
| 257 | struct rxrpc_txbuf *txb, | 257 | struct rxrpc_txbuf *txb, |
| 258 | struct skcipher_request *req) | 258 | struct skcipher_request *req) |
| 259 | { | 259 | { |
| 260 | struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base; | 260 | struct rxkad_level1_hdr *hdr = txb->data; |
| 261 | struct rxkad_level1_hdr *hdr = (void *)(whdr + 1); | ||
| 262 | struct rxrpc_crypt iv; | 261 | struct rxrpc_crypt iv; |
| 263 | struct scatterlist sg; | 262 | struct scatterlist sg; |
| 264 | size_t pad; | 263 | size_t pad; |
| @@ -274,7 +273,7 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call, · 9 unmodified lines | |||
| 274 | pad = RXKAD_ALIGN - pad; | 273 | pad = RXKAD_ALIGN - pad; |
| 275 | pad &= RXKAD_ALIGN - 1; | 274 | pad &= RXKAD_ALIGN - 1; |
| 276 | if (pad) { | 275 | if (pad) { |
| 277 | memset(txb->kvec[0].iov_base + txb->offset, 0, pad); | 276 | memset(txb->data + txb->offset, 0, pad); |
| 278 | txb->pkt_len += pad; | 277 | txb->pkt_len += pad; |
| 279 | } | 278 | } |
| 280 | 279 | ||
| @@ -300,8 +299,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, · 19 unmodified lines | |||
| 300 | struct skcipher_request *req) | 299 | struct skcipher_request *req) |
| 301 | { | 300 | { |
| 302 | const struct rxrpc_key_token *token; | 301 | const struct rxrpc_key_token *token; |
| 303 | struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base; | 302 | struct rxkad_level2_hdr *rxkhdr = txb->data; |
| 304 | struct rxkad_level2_hdr *rxkhdr = (void *)(whdr + 1); | ||
| 305 | struct rxrpc_crypt iv; | 303 | struct rxrpc_crypt iv; |
| 306 | struct scatterlist sg; | 304 | struct scatterlist sg; |
| 307 | size_t content, pad; | 305 | size_t content, pad; |
| @@ -319,7 +317,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, · 11 unmodified lines | |||
| 319 | txb->pkt_len = round_up(content, RXKAD_ALIGN); | 317 | txb->pkt_len = round_up(content, RXKAD_ALIGN); |
| 320 | pad = txb->pkt_len - content; | 318 | pad = txb->pkt_len - content; |
| 321 | if (pad) | 319 | if (pad) |
| 322 | memset(txb->kvec[0].iov_base + txb->offset, 0, pad); | 320 | memset(txb->data + txb->offset, 0, pad); |
| 323 | 321 | ||
| 324 | /* encrypt from the session key */ | 322 | /* encrypt from the session key */ |
| 325 | token = call->conn->key->payload.data[0]; | 323 | token = call->conn->key->payload.data[0]; |
| @@ -407,9 +405,8 @@ static int rxkad_secure_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb) · 81 unmodified lines | |||
| 407 | 405 | ||
| 408 | /* Clear excess space in the packet */ | 406 | /* Clear excess space in the packet */ |
| 409 | if (txb->pkt_len < txb->alloc_size) { | 407 | if (txb->pkt_len < txb->alloc_size) { |
| 410 | struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base; | ||
| 411 | size_t gap = txb->alloc_size - txb->pkt_len; | 408 | size_t gap = txb->alloc_size - txb->pkt_len; |
| 412 | void *p = whdr + 1; | 409 | void *p = txb->data; |
| 413 | 410 | ||
| 414 | memset(p + txb->pkt_len, 0, gap); | 411 | memset(p + txb->pkt_len, 0, gap); |
| 415 | } | 412 | } |
| @@ -419,7 +419,7 @@ reload: · 418 unmodified lines | |||
| 419 | size_t copy = umin(txb->space, msg_data_left(msg)); | 419 | size_t copy = umin(txb->space, msg_data_left(msg)); |
| 420 | 420 | ||
| 421 | _debug("add %zu", copy); | 421 | _debug("add %zu", copy); |
| 422 | if (!copy_from_iter_full(txb->kvec[0].iov_base + txb->offset, | 422 | if (!copy_from_iter_full(txb->data + txb->offset, |
| 423 | copy, &msg->msg_iter)) | 423 | copy, &msg->msg_iter)) |
| 424 | goto efault; | 424 | goto efault; |
| 425 | _debug("added"); | 425 | _debug("added"); |
| @@ -445,8 +445,6 @@ reload: · 19 unmodified lines | |||
| 445 | ret = call->security->secure_packet(call, txb); | 445 | ret = call->security->secure_packet(call, txb); |
| 446 | if (ret < 0) | 446 | if (ret < 0) |
| 447 | goto out; | 447 | goto out; |
| 448 | |||
| 449 | txb->kvec[0].iov_len += txb->len; | ||
| 450 | rxrpc_queue_packet(rx, call, txb, notify_end_tx); | 448 | rxrpc_queue_packet(rx, call, txb, notify_end_tx); |
| 451 | txb = NULL; | 449 | txb = NULL; |
| 452 | } | 450 | } |
| @@ -19,17 +19,19 @@ atomic_t rxrpc_nr_txbuf; · 18 unmodified lines | |||
| 19 | struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_size, | 19 | struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_size, |
| 20 | size_t data_align, gfp_t gfp) | 20 | size_t data_align, gfp_t gfp) |
| 21 | { | 21 | { |
| 22 | struct rxrpc_wire_header *whdr; | ||
| 23 | struct rxrpc_txbuf *txb; | 22 | struct rxrpc_txbuf *txb; |
| 24 | size_t total, hoff; | 23 | size_t total, doff, jsize = sizeof(struct rxrpc_jumbo_header); |
| 25 | void *buf; | 24 | void *buf; |
| 26 | 25 | ||
| 27 | txb = kzalloc(sizeof(*txb), gfp); | 26 | txb = kzalloc(sizeof(*txb), gfp); |
| 28 | if (!txb) | 27 | if (!txb) |
| 29 | return NULL; | 28 | return NULL; |
| 30 | 29 | ||
| 31 | hoff = round_up(sizeof(*whdr), data_align) - sizeof(*whdr); | 30 | /* We put a jumbo header in the buffer, but not a full wire header to |
| 32 | total = hoff + sizeof(*whdr) + data_size; | 31 | * avoid delayed-corruption problems with zerocopy. |
| 32 | */ | ||
| 33 | doff = round_up(jsize, data_align); | ||
| 34 | total = doff + data_size; | ||
| 33 | 35 | ||
| 34 | data_align = umax(data_align, L1_CACHE_BYTES); | 36 | data_align = umax(data_align, L1_CACHE_BYTES); |
| 35 | mutex_lock(&call->conn->tx_data_alloc_lock); | 37 | mutex_lock(&call->conn->tx_data_alloc_lock); |
| @@ -41,30 +43,15 @@ struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_ · 5 unmodified lines | |||
| 41 | return NULL; | 43 | return NULL; |
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | whdr = buf + hoff; | ||
| 45 | |||
| 46 | refcount_set(&txb->ref, 1); | 46 | refcount_set(&txb->ref, 1); |
| 47 | txb->call_debug_id = call->debug_id; | 47 | txb->call_debug_id = call->debug_id; |
| 48 | txb->debug_id = atomic_inc_return(&rxrpc_txbuf_debug_ids); | 48 | txb->debug_id = atomic_inc_return(&rxrpc_txbuf_debug_ids); |
| 49 | txb->alloc_size = data_size; | 49 | txb->alloc_size = data_size; |
| 50 | txb->space = data_size; | 50 | txb->space = data_size; |
| 51 | txb->offset = sizeof(*whdr); | 51 | txb->offset = 0; |
| 52 | txb->flags = call->conn->out_clientflag; | 52 | txb->flags = call->conn->out_clientflag; |
| 53 | txb->seq = call->send_top + 1; | 53 | txb->seq = call->send_top + 1; |
| 54 | txb->nr_kvec = 1; | 54 | txb->data = buf + doff; |
| 55 | txb->kvec[0].iov_base = whdr; | ||
| 56 | txb->kvec[0].iov_len = sizeof(*whdr); | ||
| 57 | |||
| 58 | whdr->epoch = htonl(call->conn->proto.epoch); | ||
| 59 | whdr->cid = htonl(call->cid); | ||
| 60 | whdr->callNumber = htonl(call->call_id); | ||
| 61 | whdr->seq = htonl(txb->seq); | ||
| 62 | whdr->type = RXRPC_PACKET_TYPE_DATA; | ||
| 63 | whdr->flags = 0; | ||
| 64 | whdr->userStatus = 0; | ||
| 65 | whdr->securityIndex = call->security_ix; | ||
| 66 | whdr->_rsvd = 0; | ||
| 67 | whdr->serviceId = htons(call->dest_srx.srx_service); | ||
| 68 | 55 | ||
| 69 | trace_rxrpc_txbuf(txb->debug_id, txb->call_debug_id, txb->seq, 1, | 56 | trace_rxrpc_txbuf(txb->debug_id, txb->call_debug_id, txb->seq, 1, |
| 70 | rxrpc_txbuf_alloc_data); | 57 | rxrpc_txbuf_alloc_data); |
| @@ -90,14 +77,10 @@ void rxrpc_see_txbuf(struct rxrpc_txbuf *txb, enum rxrpc_txbuf_trace what) · 19 unmodified lines | |||
| 90 | 77 | ||
| 91 | static void rxrpc_free_txbuf(struct rxrpc_txbuf *txb) | 78 | static void rxrpc_free_txbuf(struct rxrpc_txbuf *txb) |
| 92 | { | 79 | { |
| 93 | int i; | ||
| 94 | |||
| 95 | trace_rxrpc_txbuf(txb->debug_id, txb->call_debug_id, txb->seq, 0, | 80 | trace_rxrpc_txbuf(txb->debug_id, txb->call_debug_id, txb->seq, 0, |
| 96 | rxrpc_txbuf_free); | 81 | rxrpc_txbuf_free); |
| 97 | for (i = 0; i < txb->nr_kvec; i++) | 82 | if (txb->data) |
| 98 | if (txb->kvec[i].iov_base && | 83 | page_frag_free(txb->data); |
| 99 | !is_zero_pfn(page_to_pfn(virt_to_page(txb->kvec[i].iov_base)))) | ||
| 100 | page_frag_free(txb->kvec[i].iov_base); | ||
| 101 | kfree(txb); | 84 | kfree(txb); |
| 102 | atomic_dec(&rxrpc_nr_txbuf); | 85 | atomic_dec(&rxrpc_nr_txbuf); |
| 103 | } | 86 | } |
| @@ -824,13 +824,19 @@ static void __vsock_release(struct sock *sk, int level) · 823 unmodified lines | |||
| 824 | */ | 824 | */ |
| 825 | lock_sock_nested(sk, level); | 825 | lock_sock_nested(sk, level); |
| 826 | 826 | ||
| 827 | sock_orphan(sk); | 827 | /* Indicate to vsock_remove_sock() that the socket is being released and |
| 828 | * can be removed from the bound_table. Unlike transport reassignment | ||
| 829 | * case, where the socket must remain bound despite vsock_remove_sock() | ||
| 830 | * being called from the transport release() callback. | ||
| 831 | */ | ||
| 832 | sock_set_flag(sk, SOCK_DEAD); | ||
| 828 | 833 | ||
| 829 | if (vsk->transport) | 834 | if (vsk->transport) |
| 830 | vsk->transport->release(vsk); | 835 | vsk->transport->release(vsk); |
| 831 | else if (sock_type_connectible(sk->sk_type)) | 836 | else if (sock_type_connectible(sk->sk_type)) |
| 832 | vsock_remove_sock(vsk); | 837 | vsock_remove_sock(vsk); |
| 833 | 838 | ||
| 839 | sock_orphan(sk); | ||
| 834 | sk->sk_shutdown = SHUTDOWN_MASK; | 840 | sk->sk_shutdown = SHUTDOWN_MASK; |
| 835 | 841 | ||
| 836 | skb_queue_purge(&sk->sk_receive_queue); | 842 | skb_queue_purge(&sk->sk_receive_queue); |
| @@ -1788,6 +1788,42 @@ static void test_stream_connect_retry_server(const struct test_opts *opts) · 1787 unmodified lines | |||
| 1788 | close(fd); | 1788 | close(fd); |
| 1789 | } | 1789 | } |
| 1790 | 1790 | ||
| 1791 | static void test_stream_linger_client(const struct test_opts *opts) | ||
| 1792 | { | ||
| 1793 | struct linger optval = { | ||
| 1794 | .l_onoff = 1, | ||
| 1795 | .l_linger = 1 | ||
| 1796 | }; | ||
| 1797 | int fd; | ||
| 1798 | |||
| 1799 | fd = vsock_stream_connect(opts->peer_cid, opts->peer_port); | ||
| 1800 | if (fd < 0) { | ||
| 1801 | perror("connect"); | ||
| 1802 | exit(EXIT_FAILURE); | ||
| 1803 | } | ||
| 1804 | |||
| 1805 | if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &optval, sizeof(optval))) { | ||
| 1806 | perror("setsockopt(SO_LINGER)"); | ||
| 1807 | exit(EXIT_FAILURE); | ||
| 1808 | } | ||
| 1809 | |||
| 1810 | close(fd); | ||
| 1811 | } | ||
| 1812 | |||
| 1813 | static void test_stream_linger_server(const struct test_opts *opts) | ||
| 1814 | { | ||
| 1815 | int fd; | ||
| 1816 | |||
| 1817 | fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL); | ||
| 1818 | if (fd < 0) { | ||
| 1819 | perror("accept"); | ||
| 1820 | exit(EXIT_FAILURE); | ||
| 1821 | } | ||
| 1822 | |||
| 1823 | vsock_wait_remote_close(fd); | ||
| 1824 | close(fd); | ||
| 1825 | } | ||
| 1826 | |||
| 1791 | static struct test_case test_cases[] = { | 1827 | static struct test_case test_cases[] = { |
| 1792 | { | 1828 | { |
| 1793 | .name = "SOCK_STREAM connection reset", | 1829 | .name = "SOCK_STREAM connection reset", |
| @@ -1943,6 +1979,11 @@ static struct test_case test_cases[] = { · 149 unmodified lines | |||
| 1943 | .run_client = test_stream_connect_retry_client, | 1979 | .run_client = test_stream_connect_retry_client, |
| 1944 | .run_server = test_stream_connect_retry_server, | 1980 | .run_server = test_stream_connect_retry_server, |
| 1945 | }, | 1981 | }, |
| 1982 | { | ||
| 1983 | .name = "SOCK_STREAM SO_LINGER null-ptr-deref", | ||
| 1984 | .run_client = test_stream_linger_client, | ||
| 1985 | .run_server = test_stream_linger_server, | ||
| 1986 | }, | ||
| 1946 | {}, | 1987 | {}, |
| 1947 | }; | 1988 | }; |
| 1948 | 1989 | ||