Pull networking fixes from Jakub Kicinski: "Including fixes from netfilter. As Paolo promised we continue to hammer out issues in our selftests. This is not the end but probably the peak. Current release - regressions: - smc: fix incorrect SMC-D link group matching logic Current release - new code bugs: - eth: bnxt: silence WARN() when device skips a timestamp, it happens Previous releases - regressions: - ipmr: fix null-deref when forwarding mcast packets - conntrack: evaluate window negotiation only for packets in the REPLY direction, otherwise SYN retransmissions trigger incorrect window scale negotiation - ipset: fix performance regression in swap operation Previous releases - always broken: - tcp: add sanity checks to types of pages getting into the rx zerocopy path, we only support basic NIC -> user, no page cache pages etc. - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() - nt_tables: more input sanitization changes - dsa: mt7530: fix 10M/100M speed on MediaTek MT7988 switch - bridge: mcast: fix loss of snooping after long uptime, jiffies do wrap on 32bit - xen-netback: properly sync TX responses, protect with locking - phy: mediatek-ge-soc: sync calibration values with MediaTek SDK, increase connection stability - eth: pds: fixes for various teardown, and reset races Misc: - hsr: silence WARN() if we can't alloc supervision frame, it happens" * tag 'net-6.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (82 commits) doc/netlink/specs: Add missing attr in rt_link spec idpf: avoid compiler padding in virtchnl2_ptype struct selftests: mptcp: join: stop transfer when check is done (part 2) selftests: mptcp: join: stop transfer when check is done (part 1) selftests: mptcp: allow changing subtests prefix selftests: mptcp: decrease BW in simult flows selftests: mptcp: increase timeout to 30 min selftests: mptcp: add missing kconfig for NF Mangle selftests: mptcp: add missing kconfig for NF Filter in v6 selftests: mptcp: add missing kconfig for NF Filter mptcp: fix data re-injection from stale subflow selftests: net: enable some more knobs selftests: net: add missing config for NF_TARGET_TTL selftests: forwarding: List helper scripts in TEST_FILES Makefile variable selftests: net: List helper scripts in TEST_FILES Makefile variable selftests: net: Remove executable bits from library scripts selftests: bonding: Check initial state selftests: team: Add missing config options hv_netvsc: Fix race condition between netvsc_probe and netvsc_remove xen-netback: properly sync TX responses ...
Unified · Split
| @@ -1,4 +1,4 @@ | |||
| 1 | What: /sys/class/<iface>/queues/rx-<queue>/rps_cpus | 1 | What: /sys/class/net/<iface>/queues/rx-<queue>/rps_cpus |
| 2 | Date: March 2010 | 2 | Date: March 2010 |
| 3 | KernelVersion: 2.6.35 | 3 | KernelVersion: 2.6.35 |
| 4 | Contact: netdev@vger.kernel.org | 4 | Contact: netdev@vger.kernel.org |
| @@ -8,7 +8,7 @@ Description: · 3 unmodified lines | |||
| 8 | network device queue. Possible values depend on the number | 8 | network device queue. Possible values depend on the number |
| 9 | of available CPU(s) in the system. | 9 | of available CPU(s) in the system. |
| 10 | 10 | ||
| 11 | What: /sys/class/<iface>/queues/rx-<queue>/rps_flow_cnt | 11 | What: /sys/class/net/<iface>/queues/rx-<queue>/rps_flow_cnt |
| 12 | Date: April 2010 | 12 | Date: April 2010 |
| 13 | KernelVersion: 2.6.35 | 13 | KernelVersion: 2.6.35 |
| 14 | Contact: netdev@vger.kernel.org | 14 | Contact: netdev@vger.kernel.org |
| @@ -16,7 +16,7 @@ Description: · 1 unmodified line | |||
| 16 | Number of Receive Packet Steering flows being currently | 16 | Number of Receive Packet Steering flows being currently |
| 17 | processed by this particular network device receive queue. | 17 | processed by this particular network device receive queue. |
| 18 | 18 | ||
| 19 | What: /sys/class/<iface>/queues/tx-<queue>/tx_timeout | 19 | What: /sys/class/net/<iface>/queues/tx-<queue>/tx_timeout |
| 20 | Date: November 2011 | 20 | Date: November 2011 |
| 21 | KernelVersion: 3.3 | 21 | KernelVersion: 3.3 |
| 22 | Contact: netdev@vger.kernel.org | 22 | Contact: netdev@vger.kernel.org |
| @@ -24,7 +24,7 @@ Description: · 1 unmodified line | |||
| 24 | Indicates the number of transmit timeout events seen by this | 24 | Indicates the number of transmit timeout events seen by this |
| 25 | network interface transmit queue. | 25 | network interface transmit queue. |
| 26 | 26 | ||
| 27 | What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate | 27 | What: /sys/class/net/<iface>/queues/tx-<queue>/tx_maxrate |
| 28 | Date: March 2015 | 28 | Date: March 2015 |
| 29 | KernelVersion: 4.1 | 29 | KernelVersion: 4.1 |
| 30 | Contact: netdev@vger.kernel.org | 30 | Contact: netdev@vger.kernel.org |
| @@ -32,7 +32,7 @@ Description: · 1 unmodified line | |||
| 32 | A Mbps max-rate set for the queue, a value of zero means disabled, | 32 | A Mbps max-rate set for the queue, a value of zero means disabled, |
| 33 | default is disabled. | 33 | default is disabled. |
| 34 | 34 | ||
| 35 | What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus | 35 | What: /sys/class/net/<iface>/queues/tx-<queue>/xps_cpus |
| 36 | Date: November 2010 | 36 | Date: November 2010 |
| 37 | KernelVersion: 2.6.38 | 37 | KernelVersion: 2.6.38 |
| 38 | Contact: netdev@vger.kernel.org | 38 | Contact: netdev@vger.kernel.org |
| @@ -42,7 +42,7 @@ Description: · 3 unmodified lines | |||
| 42 | network device transmit queue. Possible values depend on the | 42 | network device transmit queue. Possible values depend on the |
| 43 | number of available CPU(s) in the system. | 43 | number of available CPU(s) in the system. |
| 44 | 44 | ||
| 45 | What: /sys/class/<iface>/queues/tx-<queue>/xps_rxqs | 45 | What: /sys/class/net/<iface>/queues/tx-<queue>/xps_rxqs |
| 46 | Date: June 2018 | 46 | Date: June 2018 |
| 47 | KernelVersion: 4.18.0 | 47 | KernelVersion: 4.18.0 |
| 48 | Contact: netdev@vger.kernel.org | 48 | Contact: netdev@vger.kernel.org |
| @@ -53,7 +53,7 @@ Description: · 4 unmodified lines | |||
| 53 | number of available receive queue(s) in the network device. | 53 | number of available receive queue(s) in the network device. |
| 54 | Default is disabled. | 54 | Default is disabled. |
| 55 | 55 | ||
| 56 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time | 56 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time |
| 57 | Date: November 2011 | 57 | Date: November 2011 |
| 58 | KernelVersion: 3.3 | 58 | KernelVersion: 3.3 |
| 59 | Contact: netdev@vger.kernel.org | 59 | Contact: netdev@vger.kernel.org |
| @@ -62,7 +62,7 @@ Description: · 2 unmodified lines | |||
| 62 | of this particular network device transmit queue. | 62 | of this particular network device transmit queue. |
| 63 | Default value is 1000. | 63 | Default value is 1000. |
| 64 | 64 | ||
| 65 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/inflight | 65 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/inflight |
| 66 | Date: November 2011 | 66 | Date: November 2011 |
| 67 | KernelVersion: 3.3 | 67 | KernelVersion: 3.3 |
| 68 | Contact: netdev@vger.kernel.org | 68 | Contact: netdev@vger.kernel.org |
| @@ -70,7 +70,7 @@ Description: · 1 unmodified line | |||
| 70 | Indicates the number of bytes (objects) in flight on this | 70 | Indicates the number of bytes (objects) in flight on this |
| 71 | network device transmit queue. | 71 | network device transmit queue. |
| 72 | 72 | ||
| 73 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit | 73 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit |
| 74 | Date: November 2011 | 74 | Date: November 2011 |
| 75 | KernelVersion: 3.3 | 75 | KernelVersion: 3.3 |
| 76 | Contact: netdev@vger.kernel.org | 76 | Contact: netdev@vger.kernel.org |
| @@ -79,7 +79,7 @@ Description: · 2 unmodified lines | |||
| 79 | on this network device transmit queue. This value is clamped | 79 | on this network device transmit queue. This value is clamped |
| 80 | to be within the bounds defined by limit_max and limit_min. | 80 | to be within the bounds defined by limit_max and limit_min. |
| 81 | 81 | ||
| 82 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max | 82 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max |
| 83 | Date: November 2011 | 83 | Date: November 2011 |
| 84 | KernelVersion: 3.3 | 84 | KernelVersion: 3.3 |
| 85 | Contact: netdev@vger.kernel.org | 85 | Contact: netdev@vger.kernel.org |
| @@ -88,7 +88,7 @@ Description: · 2 unmodified lines | |||
| 88 | queued on this network device transmit queue. See | 88 | queued on this network device transmit queue. See |
| 89 | include/linux/dynamic_queue_limits.h for the default value. | 89 | include/linux/dynamic_queue_limits.h for the default value. |
| 90 | 90 | ||
| 91 | What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min | 91 | What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min |
| 92 | Date: November 2011 | 92 | Date: November 2011 |
| 93 | KernelVersion: 3.3 | 93 | KernelVersion: 3.3 |
| 94 | Contact: netdev@vger.kernel.org | 94 | Contact: netdev@vger.kernel.org |
| @@ -942,6 +942,10 @@ attribute-sets: · 941 unmodified lines | |||
| 942 | - | 942 | - |
| 943 | name: gro-ipv4-max-size | 943 | name: gro-ipv4-max-size |
| 944 | type: u32 | 944 | type: u32 |
| 945 | - | ||
| 946 | name: dpll-pin | ||
| 947 | type: nest | ||
| 948 | nested-attributes: link-dpll-pin-attrs | ||
| 945 | - | 949 | - |
| 946 | name: af-spec-attrs | 950 | name: af-spec-attrs |
| 947 | attributes: | 951 | attributes: |
| @@ -1627,6 +1631,12 @@ attribute-sets: · 679 unmodified lines | |||
| 1627 | - | 1631 | - |
| 1628 | name: used | 1632 | name: used |
| 1629 | type: u8 | 1633 | type: u8 |
| 1634 | - | ||
| 1635 | name: link-dpll-pin-attrs | ||
| 1636 | attributes: | ||
| 1637 | - | ||
| 1638 | name: id | ||
| 1639 | type: u32 | ||
| 1630 | 1640 | ||
| 1631 | sub-messages: | 1641 | sub-messages: |
| 1632 | - | 1642 | - |
| @@ -15181,6 +15181,7 @@ F: Documentation/networking/net_cachelines/net_device.rst · 15180 unmodified lines | |||
| 15181 | F: drivers/connector/ | 15181 | F: drivers/connector/ |
| 15182 | F: drivers/net/ | 15182 | F: drivers/net/ |
| 15183 | F: include/dt-bindings/net/ | 15183 | F: include/dt-bindings/net/ |
| 15184 | F: include/linux/cn_proc.h | ||
| 15184 | F: include/linux/etherdevice.h | 15185 | F: include/linux/etherdevice.h |
| 15185 | F: include/linux/fcdevice.h | 15186 | F: include/linux/fcdevice.h |
| 15186 | F: include/linux/fddidevice.h | 15187 | F: include/linux/fddidevice.h |
| @@ -15188,6 +15189,7 @@ F: include/linux/hippidevice.h · 1 unmodified line | |||
| 15188 | F: include/linux/if_* | 15189 | F: include/linux/if_* |
| 15189 | F: include/linux/inetdevice.h | 15190 | F: include/linux/inetdevice.h |
| 15190 | F: include/linux/netdevice.h | 15191 | F: include/linux/netdevice.h |
| 15192 | F: include/uapi/linux/cn_proc.h | ||
| 15191 | F: include/uapi/linux/if_* | 15193 | F: include/uapi/linux/if_* |
| 15192 | F: include/uapi/linux/netdevice.h | 15194 | F: include/uapi/linux/netdevice.h |
| 15193 | X: drivers/net/wireless/ | 15195 | X: drivers/net/wireless/ |
| @@ -18085,7 +18087,6 @@ F: drivers/net/ethernet/qualcomm/emac/ · 2891 unmodified lines | |||
| 18085 | 18087 | ||
| 18086 | QUALCOMM ETHQOS ETHERNET DRIVER | 18088 | QUALCOMM ETHQOS ETHERNET DRIVER |
| 18087 | M: Vinod Koul <vkoul@kernel.org> | 18089 | M: Vinod Koul <vkoul@kernel.org> |
| 18088 | R: Bhupesh Sharma <bhupesh.sharma@linaro.org> | ||
| 18089 | L: netdev@vger.kernel.org | 18090 | L: netdev@vger.kernel.org |
| 18090 | L: linux-arm-msm@vger.kernel.org | 18091 | L: linux-arm-msm@vger.kernel.org |
| 18091 | S: Maintained | 18092 | S: Maintained |
| @@ -2838,8 +2838,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, · 2837 unmodified lines | |||
| 2838 | /* MT753x MAC works in 1G full duplex mode for all up-clocked | 2838 | /* MT753x MAC works in 1G full duplex mode for all up-clocked |
| 2839 | * variants. | 2839 | * variants. |
| 2840 | */ | 2840 | */ |
| 2841 | if (interface == PHY_INTERFACE_MODE_INTERNAL || | 2841 | if (interface == PHY_INTERFACE_MODE_TRGMII || |
| 2842 | interface == PHY_INTERFACE_MODE_TRGMII || | ||
| 2843 | (phy_interface_mode_is_8023z(interface))) { | 2842 | (phy_interface_mode_is_8023z(interface))) { |
| 2844 | speed = SPEED_1000; | 2843 | speed = SPEED_1000; |
| 2845 | duplex = DUPLEX_FULL; | 2844 | duplex = DUPLEX_FULL; |
| @@ -3659,7 +3659,7 @@ static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad, · 3658 unmodified lines | |||
| 3659 | int err; | 3659 | int err; |
| 3660 | 3660 | ||
| 3661 | if (!chip->info->ops->phy_read_c45) | 3661 | if (!chip->info->ops->phy_read_c45) |
| 3662 | return -EOPNOTSUPP; | 3662 | return 0xffff; |
| 3663 | 3663 | ||
| 3664 | mv88e6xxx_reg_lock(chip); | 3664 | mv88e6xxx_reg_lock(chip); |
| 3665 | err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); | 3665 | err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); |
| @@ -2051,12 +2051,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev) · 2050 unmodified lines | |||
| 2051 | priv->info = of_device_get_match_data(priv->dev); | 2051 | priv->info = of_device_get_match_data(priv->dev); |
| 2052 | 2052 | ||
| 2053 | priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", | 2053 | priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", |
| 2054 | GPIOD_ASIS); | 2054 | GPIOD_OUT_HIGH); |
| 2055 | if (IS_ERR(priv->reset_gpio)) | 2055 | if (IS_ERR(priv->reset_gpio)) |
| 2056 | return PTR_ERR(priv->reset_gpio); | 2056 | return PTR_ERR(priv->reset_gpio); |
| 2057 | 2057 | ||
| 2058 | if (priv->reset_gpio) { | 2058 | if (priv->reset_gpio) { |
| 2059 | gpiod_set_value_cansleep(priv->reset_gpio, 1); | ||
| 2060 | /* The active low duration must be greater than 10 ms | 2059 | /* The active low duration must be greater than 10 ms |
| 2061 | * and checkpatch.pl wants 20 ms. | 2060 | * and checkpatch.pl wants 20 ms. |
| 2062 | */ | 2061 | */ |
| @@ -63,6 +63,15 @@ static int pdsc_process_notifyq(struct pdsc_qcq *qcq) · 62 unmodified lines | |||
| 63 | return nq_work; | 63 | return nq_work; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static bool pdsc_adminq_inc_if_up(struct pdsc *pdsc) | ||
| 67 | { | ||
| 68 | if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER) || | ||
| 69 | pdsc->state & BIT_ULL(PDSC_S_FW_DEAD)) | ||
| 70 | return false; | ||
| 71 | |||
| 72 | return refcount_inc_not_zero(&pdsc->adminq_refcnt); | ||
| 73 | } | ||
| 74 | |||
| 66 | void pdsc_process_adminq(struct pdsc_qcq *qcq) | 75 | void pdsc_process_adminq(struct pdsc_qcq *qcq) |
| 67 | { | 76 | { |
| 68 | union pds_core_adminq_comp *comp; | 77 | union pds_core_adminq_comp *comp; |
| @@ -75,9 +84,9 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq) · 6 unmodified lines | |||
| 75 | int aq_work = 0; | 84 | int aq_work = 0; |
| 76 | int credits; | 85 | int credits; |
| 77 | 86 | ||
| 78 | /* Don't process AdminQ when shutting down */ | 87 | /* Don't process AdminQ when it's not up */ |
| 79 | if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { | 88 | if (!pdsc_adminq_inc_if_up(pdsc)) { |
| 80 | dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", | 89 | dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", |
| 81 | __func__); | 90 | __func__); |
| 82 | return; | 91 | return; |
| 83 | } | 92 | } |
| @@ -124,6 +133,7 @@ credits: · 40 unmodified lines | |||
| 124 | pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], | 133 | pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], |
| 125 | credits, | 134 | credits, |
| 126 | PDS_CORE_INTR_CRED_REARM); | 135 | PDS_CORE_INTR_CRED_REARM); |
| 136 | refcount_dec(&pdsc->adminq_refcnt); | ||
| 127 | } | 137 | } |
| 128 | 138 | ||
| 129 | void pdsc_work_thread(struct work_struct *work) | 139 | void pdsc_work_thread(struct work_struct *work) |
| @@ -135,18 +145,20 @@ void pdsc_work_thread(struct work_struct *work) · 5 unmodified lines | |||
| 135 | 145 | ||
| 136 | irqreturn_t pdsc_adminq_isr(int irq, void *data) | 146 | irqreturn_t pdsc_adminq_isr(int irq, void *data) |
| 137 | { | 147 | { |
| 138 | struct pdsc_qcq *qcq = data; | 148 | struct pdsc *pdsc = data; |
| 139 | struct pdsc *pdsc = qcq->pdsc; | 149 | struct pdsc_qcq *qcq; |
| 140 | 150 | ||
| 141 | /* Don't process AdminQ when shutting down */ | 151 | /* Don't process AdminQ when it's not up */ |
| 142 | if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { | 152 | if (!pdsc_adminq_inc_if_up(pdsc)) { |
| 143 | dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", | 153 | dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", |
| 144 | __func__); | 154 | __func__); |
| 145 | return IRQ_HANDLED; | 155 | return IRQ_HANDLED; |
| 146 | } | 156 | } |
| 147 | 157 | ||
| 158 | qcq = &pdsc->adminqcq; | ||
| 148 | queue_work(pdsc->wq, &qcq->work); | 159 | queue_work(pdsc->wq, &qcq->work); |
| 149 | pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); | 160 | pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); |
| 161 | refcount_dec(&pdsc->adminq_refcnt); | ||
| 150 | 162 | ||
| 151 | return IRQ_HANDLED; | 163 | return IRQ_HANDLED; |
| 152 | } | 164 | } |
| @@ -179,10 +191,16 @@ static int __pdsc_adminq_post(struct pdsc *pdsc, · 26 unmodified lines | |||
| 179 | 191 | ||
| 180 | /* Check that the FW is running */ | 192 | /* Check that the FW is running */ |
| 181 | if (!pdsc_is_fw_running(pdsc)) { | 193 | if (!pdsc_is_fw_running(pdsc)) { |
| 182 | u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | 194 | if (pdsc->info_regs) { |
| 183 | 195 | u8 fw_status = | |
| 184 | dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", | 196 | ioread8(&pdsc->info_regs->fw_status); |
| 185 | __func__, fw_status); | 197 | |
| 198 | dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", | ||
| 199 | __func__, fw_status); | ||
| 200 | } else { | ||
| 201 | dev_info(pdsc->dev, "%s: post failed - BARs not setup\n", | ||
| 202 | __func__); | ||
| 203 | } | ||
| 186 | ret = -ENXIO; | 204 | ret = -ENXIO; |
| 187 | 205 | ||
| 188 | goto err_out_unlock; | 206 | goto err_out_unlock; |
| @@ -230,6 +248,12 @@ int pdsc_adminq_post(struct pdsc *pdsc, · 41 unmodified lines | |||
| 230 | int err = 0; | 248 | int err = 0; |
| 231 | int index; | 249 | int index; |
| 232 | 250 | ||
| 251 | if (!pdsc_adminq_inc_if_up(pdsc)) { | ||
| 252 | dev_dbg(pdsc->dev, "%s: preventing adminq cmd %u\n", | ||
| 253 | __func__, cmd->opcode); | ||
| 254 | return -ENXIO; | ||
| 255 | } | ||
| 256 | |||
| 233 | wc.qcq = &pdsc->adminqcq; | 257 | wc.qcq = &pdsc->adminqcq; |
| 234 | index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); | 258 | index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); |
| 235 | if (index < 0) { | 259 | if (index < 0) { |
| @@ -248,10 +272,16 @@ int pdsc_adminq_post(struct pdsc *pdsc, · 12 unmodified lines | |||
| 248 | break; | 272 | break; |
| 249 | 273 | ||
| 250 | if (!pdsc_is_fw_running(pdsc)) { | 274 | if (!pdsc_is_fw_running(pdsc)) { |
| 251 | u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | 275 | if (pdsc->info_regs) { |
| 252 | 276 | u8 fw_status = | |
| 253 | dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", | 277 | ioread8(&pdsc->info_regs->fw_status); |
| 254 | __func__, fw_status); | 278 | |
| 279 | dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", | ||
| 280 | __func__, fw_status); | ||
| 281 | } else { | ||
| 282 | dev_dbg(pdsc->dev, "%s: post wait failed - BARs not setup\n", | ||
| 283 | __func__); | ||
| 284 | } | ||
| 255 | err = -ENXIO; | 285 | err = -ENXIO; |
| 256 | break; | 286 | break; |
| 257 | } | 287 | } |
| @@ -285,6 +315,8 @@ err_out: · 27 unmodified lines | |||
| 285 | queue_work(pdsc->wq, &pdsc->health_work); | 315 | queue_work(pdsc->wq, &pdsc->health_work); |
| 286 | } | 316 | } |
| 287 | 317 | ||
| 318 | refcount_dec(&pdsc->adminq_refcnt); | ||
| 319 | |||
| 288 | return err; | 320 | return err; |
| 289 | } | 321 | } |
| 290 | EXPORT_SYMBOL_GPL(pdsc_adminq_post); | 322 | EXPORT_SYMBOL_GPL(pdsc_adminq_post); |
| @@ -125,7 +125,7 @@ static int pdsc_qcq_intr_alloc(struct pdsc *pdsc, struct pdsc_qcq *qcq) · 124 unmodified lines | |||
| 125 | 125 | ||
| 126 | snprintf(name, sizeof(name), "%s-%d-%s", | 126 | snprintf(name, sizeof(name), "%s-%d-%s", |
| 127 | PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name); | 127 | PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name); |
| 128 | index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, qcq); | 128 | index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, pdsc); |
| 129 | if (index < 0) | 129 | if (index < 0) |
| 130 | return index; | 130 | return index; |
| 131 | qcq->intx = index; | 131 | qcq->intx = index; |
| @@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) · 272 unmodified lines | |||
| 404 | int numdescs; | 404 | int numdescs; |
| 405 | int err; | 405 | int err; |
| 406 | 406 | ||
| 407 | if (init) | 407 | err = pdsc_dev_init(pdsc); |
| 408 | err = pdsc_dev_init(pdsc); | ||
| 409 | else | ||
| 410 | err = pdsc_dev_reinit(pdsc); | ||
| 411 | if (err) | 408 | if (err) |
| 412 | return err; | 409 | return err; |
| 413 | 410 | ||
| @@ -450,6 +447,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) · 36 unmodified lines | |||
| 450 | pdsc_debugfs_add_viftype(pdsc); | 447 | pdsc_debugfs_add_viftype(pdsc); |
| 451 | } | 448 | } |
| 452 | 449 | ||
| 450 | refcount_set(&pdsc->adminq_refcnt, 1); | ||
| 453 | clear_bit(PDSC_S_FW_DEAD, &pdsc->state); | 451 | clear_bit(PDSC_S_FW_DEAD, &pdsc->state); |
| 454 | return 0; | 452 | return 0; |
| 455 | 453 | ||
| @@ -464,6 +462,8 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 8 unmodified lines | |||
| 464 | 462 | ||
| 465 | if (!pdsc->pdev->is_virtfn) | 463 | if (!pdsc->pdev->is_virtfn) |
| 466 | pdsc_devcmd_reset(pdsc); | 464 | pdsc_devcmd_reset(pdsc); |
| 465 | if (pdsc->adminqcq.work.func) | ||
| 466 | cancel_work_sync(&pdsc->adminqcq.work); | ||
| 467 | pdsc_qcq_free(pdsc, &pdsc->notifyqcq); | 467 | pdsc_qcq_free(pdsc, &pdsc->notifyqcq); |
| 468 | pdsc_qcq_free(pdsc, &pdsc->adminqcq); | 468 | pdsc_qcq_free(pdsc, &pdsc->adminqcq); |
| 469 | 469 | ||
| @@ -476,10 +476,9 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 6 unmodified lines | |||
| 476 | for (i = 0; i < pdsc->nintrs; i++) | 476 | for (i = 0; i < pdsc->nintrs; i++) |
| 477 | pdsc_intr_free(pdsc, i); | 477 | pdsc_intr_free(pdsc, i); |
| 478 | 478 | ||
| 479 | if (removing) { | 479 | kfree(pdsc->intr_info); |
| 480 | kfree(pdsc->intr_info); | 480 | pdsc->intr_info = NULL; |
| 481 | pdsc->intr_info = NULL; | 481 | pdsc->nintrs = 0; |
| 482 | } | ||
| 483 | } | 482 | } |
| 484 | 483 | ||
| 485 | if (pdsc->kern_dbpage) { | 484 | if (pdsc->kern_dbpage) { |
| @@ -487,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 1 unmodified line | |||
| 487 | pdsc->kern_dbpage = NULL; | 486 | pdsc->kern_dbpage = NULL; |
| 488 | } | 487 | } |
| 489 | 488 | ||
| 489 | pci_free_irq_vectors(pdsc->pdev); | ||
| 490 | set_bit(PDSC_S_FW_DEAD, &pdsc->state); | 490 | set_bit(PDSC_S_FW_DEAD, &pdsc->state); |
| 491 | } | 491 | } |
| 492 | 492 | ||
| @@ -512,6 +512,24 @@ void pdsc_stop(struct pdsc *pdsc) · 19 unmodified lines | |||
| 512 | PDS_CORE_INTR_MASK_SET); | 512 | PDS_CORE_INTR_MASK_SET); |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | static void pdsc_adminq_wait_and_dec_once_unused(struct pdsc *pdsc) | ||
| 516 | { | ||
| 517 | /* The driver initializes the adminq_refcnt to 1 when the adminq is | ||
| 518 | * allocated and ready for use. Other users/requesters will increment | ||
| 519 | * the refcnt while in use. If the refcnt is down to 1 then the adminq | ||
| 520 | * is not in use and the refcnt can be cleared and adminq freed. Before | ||
| 521 | * calling this function the driver will set PDSC_S_FW_DEAD, which | ||
| 522 | * prevent subsequent attempts to use the adminq and increment the | ||
| 523 | * refcnt to fail. This guarantees that this function will eventually | ||
| 524 | * exit. | ||
| 525 | */ | ||
| 526 | while (!refcount_dec_if_one(&pdsc->adminq_refcnt)) { | ||
| 527 | dev_dbg_ratelimited(pdsc->dev, "%s: adminq in use\n", | ||
| 528 | __func__); | ||
| 529 | cpu_relax(); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 515 | void pdsc_fw_down(struct pdsc *pdsc) | 533 | void pdsc_fw_down(struct pdsc *pdsc) |
| 516 | { | 534 | { |
| 517 | union pds_core_notifyq_comp reset_event = { | 535 | union pds_core_notifyq_comp reset_event = { |
| @@ -527,6 +545,8 @@ void pdsc_fw_down(struct pdsc *pdsc) · 9 unmodified lines | |||
| 527 | if (pdsc->pdev->is_virtfn) | 545 | if (pdsc->pdev->is_virtfn) |
| 528 | return; | 546 | return; |
| 529 | 547 | ||
| 548 | pdsc_adminq_wait_and_dec_once_unused(pdsc); | ||
| 549 | |||
| 530 | /* Notify clients of fw_down */ | 550 | /* Notify clients of fw_down */ |
| 531 | if (pdsc->fw_reporter) | 551 | if (pdsc->fw_reporter) |
| 532 | devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); | 552 | devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); |
| @@ -577,7 +597,13 @@ err_out: · 44 unmodified lines | |||
| 577 | 597 | ||
| 578 | static void pdsc_check_pci_health(struct pdsc *pdsc) | 598 | static void pdsc_check_pci_health(struct pdsc *pdsc) |
| 579 | { | 599 | { |
| 580 | u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | 600 | u8 fw_status; |
| 601 | |||
| 602 | /* some sort of teardown already in progress */ | ||
| 603 | if (!pdsc->info_regs) | ||
| 604 | return; | ||
| 605 | |||
| 606 | fw_status = ioread8(&pdsc->info_regs->fw_status); | ||
| 581 | 607 | ||
| 582 | /* is PCI broken? */ | 608 | /* is PCI broken? */ |
| 583 | if (fw_status != PDS_RC_BAD_PCI) | 609 | if (fw_status != PDS_RC_BAD_PCI) |
| @@ -184,6 +184,7 @@ struct pdsc { · 183 unmodified lines | |||
| 184 | struct mutex devcmd_lock; /* lock for dev_cmd operations */ | 184 | struct mutex devcmd_lock; /* lock for dev_cmd operations */ |
| 185 | struct mutex config_lock; /* lock for configuration operations */ | 185 | struct mutex config_lock; /* lock for configuration operations */ |
| 186 | spinlock_t adminq_lock; /* lock for adminq operations */ | 186 | spinlock_t adminq_lock; /* lock for adminq operations */ |
| 187 | refcount_t adminq_refcnt; | ||
| 187 | struct pds_core_dev_info_regs __iomem *info_regs; | 188 | struct pds_core_dev_info_regs __iomem *info_regs; |
| 188 | struct pds_core_dev_cmd_regs __iomem *cmd_regs; | 189 | struct pds_core_dev_cmd_regs __iomem *cmd_regs; |
| 189 | struct pds_core_intr __iomem *intr_ctrl; | 190 | struct pds_core_intr __iomem *intr_ctrl; |
| @@ -280,7 +281,6 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, · 90 unmodified lines | |||
| 280 | union pds_core_dev_comp *comp, int max_seconds); | 281 | union pds_core_dev_comp *comp, int max_seconds); |
| 281 | int pdsc_devcmd_init(struct pdsc *pdsc); | 282 | int pdsc_devcmd_init(struct pdsc *pdsc); |
| 282 | int pdsc_devcmd_reset(struct pdsc *pdsc); | 283 | int pdsc_devcmd_reset(struct pdsc *pdsc); |
| 283 | int pdsc_dev_reinit(struct pdsc *pdsc); | ||
| 284 | int pdsc_dev_init(struct pdsc *pdsc); | 284 | int pdsc_dev_init(struct pdsc *pdsc); |
| 285 | 285 | ||
| 286 | void pdsc_reset_prepare(struct pci_dev *pdev); | 286 | void pdsc_reset_prepare(struct pci_dev *pdev); |
| @@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity); · 63 unmodified lines | |||
| 64 | 64 | ||
| 65 | void pdsc_debugfs_add_ident(struct pdsc *pdsc) | 65 | void pdsc_debugfs_add_ident(struct pdsc *pdsc) |
| 66 | { | 66 | { |
| 67 | /* This file will already exist in the reset flow */ | ||
| 68 | if (debugfs_lookup("identity", pdsc->dentry)) | ||
| 69 | return; | ||
| 70 | |||
| 67 | debugfs_create_file("identity", 0400, pdsc->dentry, | 71 | debugfs_create_file("identity", 0400, pdsc->dentry, |
| 68 | pdsc, &identity_fops); | 72 | pdsc, &identity_fops); |
| 69 | } | 73 | } |
| @@ -57,6 +57,9 @@ int pdsc_err_to_errno(enum pds_core_status_code code) · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | bool pdsc_is_fw_running(struct pdsc *pdsc) | 58 | bool pdsc_is_fw_running(struct pdsc *pdsc) |
| 59 | { | 59 | { |
| 60 | if (!pdsc->info_regs) | ||
| 61 | return false; | ||
| 62 | |||
| 60 | pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); | 63 | pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); |
| 61 | pdsc->last_fw_time = jiffies; | 64 | pdsc->last_fw_time = jiffies; |
| 62 | pdsc->last_hb = ioread32(&pdsc->info_regs->fw_heartbeat); | 65 | pdsc->last_hb = ioread32(&pdsc->info_regs->fw_heartbeat); |
| @@ -182,13 +185,17 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd, · 119 unmodified lines | |||
| 182 | { | 185 | { |
| 183 | int err; | 186 | int err; |
| 184 | 187 | ||
| 188 | if (!pdsc->cmd_regs) | ||
| 189 | return -ENXIO; | ||
| 190 | |||
| 185 | memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); | 191 | memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); |
| 186 | pdsc_devcmd_dbell(pdsc); | 192 | pdsc_devcmd_dbell(pdsc); |
| 187 | err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); | 193 | err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); |
| 188 | memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); | ||
| 189 | 194 | ||
| 190 | if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) | 195 | if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) |
| 191 | queue_work(pdsc->wq, &pdsc->health_work); | 196 | queue_work(pdsc->wq, &pdsc->health_work); |
| 197 | else | ||
| 198 | memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); | ||
| 192 | 199 | ||
| 193 | return err; | 200 | return err; |
| 194 | } | 201 | } |
| @@ -309,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc) · 114 unmodified lines | |||
| 309 | return 0; | 316 | return 0; |
| 310 | } | 317 | } |
| 311 | 318 | ||
| 312 | int pdsc_dev_reinit(struct pdsc *pdsc) | ||
| 313 | { | ||
| 314 | pdsc_init_devinfo(pdsc); | ||
| 315 | |||
| 316 | return pdsc_identify(pdsc); | ||
| 317 | } | ||
| 318 | |||
| 319 | int pdsc_dev_init(struct pdsc *pdsc) | 319 | int pdsc_dev_init(struct pdsc *pdsc) |
| 320 | { | 320 | { |
| 321 | unsigned int nintrs; | 321 | unsigned int nintrs; |
| @@ -111,7 +111,8 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | mutex_lock(&pdsc->devcmd_lock); | 112 | mutex_lock(&pdsc->devcmd_lock); |
| 113 | err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2); | 113 | err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2); |
| 114 | memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); | 114 | if (!err) |
| 115 | memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); | ||
| 115 | mutex_unlock(&pdsc->devcmd_lock); | 116 | mutex_unlock(&pdsc->devcmd_lock); |
| 116 | if (err && err != -EIO) | 117 | if (err && err != -EIO) |
| 117 | return err; | 118 | return err; |
| @@ -107,6 +107,9 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw, · 106 unmodified lines | |||
| 107 | 107 | ||
| 108 | dev_info(pdsc->dev, "Installing firmware\n"); | 108 | dev_info(pdsc->dev, "Installing firmware\n"); |
| 109 | 109 | ||
| 110 | if (!pdsc->cmd_regs) | ||
| 111 | return -ENXIO; | ||
| 112 | |||
| 110 | dl = priv_to_devlink(pdsc); | 113 | dl = priv_to_devlink(pdsc); |
| 111 | devlink_flash_update_status_notify(dl, "Preparing to flash", | 114 | devlink_flash_update_status_notify(dl, "Preparing to flash", |
| 112 | NULL, 0, 0); | 115 | NULL, 0, 0); |
| @@ -37,6 +37,11 @@ static void pdsc_unmap_bars(struct pdsc *pdsc) · 36 unmodified lines | |||
| 37 | struct pdsc_dev_bar *bars = pdsc->bars; | 37 | struct pdsc_dev_bar *bars = pdsc->bars; |
| 38 | unsigned int i; | 38 | unsigned int i; |
| 39 | 39 | ||
| 40 | pdsc->info_regs = NULL; | ||
| 41 | pdsc->cmd_regs = NULL; | ||
| 42 | pdsc->intr_status = NULL; | ||
| 43 | pdsc->intr_ctrl = NULL; | ||
| 44 | |||
| 40 | for (i = 0; i < PDS_CORE_BARS_MAX; i++) { | 45 | for (i = 0; i < PDS_CORE_BARS_MAX; i++) { |
| 41 | if (bars[i].vaddr) | 46 | if (bars[i].vaddr) |
| 42 | pci_iounmap(pdsc->pdev, bars[i].vaddr); | 47 | pci_iounmap(pdsc->pdev, bars[i].vaddr); |
| @@ -293,7 +298,7 @@ err_out_stop: · 250 unmodified lines | |||
| 293 | err_out_teardown: | 298 | err_out_teardown: |
| 294 | pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); | 299 | pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); |
| 295 | err_out_unmap_bars: | 300 | err_out_unmap_bars: |
| 296 | del_timer_sync(&pdsc->wdtimer); | 301 | timer_shutdown_sync(&pdsc->wdtimer); |
| 297 | if (pdsc->wq) | 302 | if (pdsc->wq) |
| 298 | destroy_workqueue(pdsc->wq); | 303 | destroy_workqueue(pdsc->wq); |
| 299 | mutex_destroy(&pdsc->config_lock); | 304 | mutex_destroy(&pdsc->config_lock); |
| @@ -420,7 +425,7 @@ static void pdsc_remove(struct pci_dev *pdev) · 120 unmodified lines | |||
| 420 | */ | 425 | */ |
| 421 | pdsc_sriov_configure(pdev, 0); | 426 | pdsc_sriov_configure(pdev, 0); |
| 422 | 427 | ||
| 423 | del_timer_sync(&pdsc->wdtimer); | 428 | timer_shutdown_sync(&pdsc->wdtimer); |
| 424 | if (pdsc->wq) | 429 | if (pdsc->wq) |
| 425 | destroy_workqueue(pdsc->wq); | 430 | destroy_workqueue(pdsc->wq); |
| 426 | 431 | ||
| @@ -433,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev) · 6 unmodified lines | |||
| 433 | mutex_destroy(&pdsc->config_lock); | 438 | mutex_destroy(&pdsc->config_lock); |
| 434 | mutex_destroy(&pdsc->devcmd_lock); | 439 | mutex_destroy(&pdsc->devcmd_lock); |
| 435 | 440 | ||
| 436 | pci_free_irq_vectors(pdev); | ||
| 437 | pdsc_unmap_bars(pdsc); | 441 | pdsc_unmap_bars(pdsc); |
| 438 | pci_release_regions(pdev); | 442 | pci_release_regions(pdev); |
| 439 | } | 443 | } |
| @@ -445,13 +449,26 @@ static void pdsc_remove(struct pci_dev *pdev) · 5 unmodified lines | |||
| 445 | devlink_free(dl); | 449 | devlink_free(dl); |
| 446 | } | 450 | } |
| 447 | 451 | ||
| 452 | static void pdsc_stop_health_thread(struct pdsc *pdsc) | ||
| 453 | { | ||
| 454 | timer_shutdown_sync(&pdsc->wdtimer); | ||
| 455 | if (pdsc->health_work.func) | ||
| 456 | cancel_work_sync(&pdsc->health_work); | ||
| 457 | } | ||
| 458 | |||
| 459 | static void pdsc_restart_health_thread(struct pdsc *pdsc) | ||
| 460 | { | ||
| 461 | timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0); | ||
| 462 | mod_timer(&pdsc->wdtimer, jiffies + 1); | ||
| 463 | } | ||
| 464 | |||
| 448 | void pdsc_reset_prepare(struct pci_dev *pdev) | 465 | void pdsc_reset_prepare(struct pci_dev *pdev) |
| 449 | { | 466 | { |
| 450 | struct pdsc *pdsc = pci_get_drvdata(pdev); | 467 | struct pdsc *pdsc = pci_get_drvdata(pdev); |
| 451 | 468 | ||
| 469 | pdsc_stop_health_thread(pdsc); | ||
| 452 | pdsc_fw_down(pdsc); | 470 | pdsc_fw_down(pdsc); |
| 453 | 471 | ||
| 454 | pci_free_irq_vectors(pdev); | ||
| 455 | pdsc_unmap_bars(pdsc); | 472 | pdsc_unmap_bars(pdsc); |
| 456 | pci_release_regions(pdev); | 473 | pci_release_regions(pdev); |
| 457 | pci_disable_device(pdev); | 474 | pci_disable_device(pdev); |
| @@ -486,6 +503,7 @@ void pdsc_reset_done(struct pci_dev *pdev) · 28 unmodified lines | |||
| 486 | } | 503 | } |
| 487 | 504 | ||
| 488 | pdsc_fw_up(pdsc); | 505 | pdsc_fw_up(pdsc); |
| 506 | pdsc_restart_health_thread(pdsc); | ||
| 489 | } | 507 | } |
| 490 | 508 | ||
| 491 | static const struct pci_error_handlers pdsc_err_handler = { | 509 | static const struct pci_error_handlers pdsc_err_handler = { |
| @@ -684,7 +684,7 @@ static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb) · 683 unmodified lines | |||
| 684 | timestamp.hwtstamp = ns_to_ktime(ns); | 684 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 685 | skb_tstamp_tx(ptp->tx_skb, ×tamp); | 685 | skb_tstamp_tx(ptp->tx_skb, ×tamp); |
| 686 | } else { | 686 | } else { |
| 687 | netdev_WARN_ONCE(bp->dev, | 687 | netdev_warn_once(bp->dev, |
| 688 | "TS query for TX timer failed rc = %x\n", rc); | 688 | "TS query for TX timer failed rc = %x\n", rc); |
| 689 | } | 689 | } |
| 690 | 690 | ||
| @@ -356,7 +356,7 @@ static enum pkt_hash_types gve_rss_type(__be16 pkt_flags) · 355 unmodified lines | |||
| 356 | 356 | ||
| 357 | static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, | 357 | static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, |
| 358 | struct gve_rx_slot_page_info *page_info, | 358 | struct gve_rx_slot_page_info *page_info, |
| 359 | u16 packet_buffer_size, u16 len, | 359 | unsigned int truesize, u16 len, |
| 360 | struct gve_rx_ctx *ctx) | 360 | struct gve_rx_ctx *ctx) |
| 361 | { | 361 | { |
| 362 | u32 offset = page_info->page_offset + page_info->pad; | 362 | u32 offset = page_info->page_offset + page_info->pad; |
| @@ -389,10 +389,10 @@ static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, · 26 unmodified lines | |||
| 389 | if (skb != ctx->skb_head) { | 389 | if (skb != ctx->skb_head) { |
| 390 | ctx->skb_head->len += len; | 390 | ctx->skb_head->len += len; |
| 391 | ctx->skb_head->data_len += len; | 391 | ctx->skb_head->data_len += len; |
| 392 | ctx->skb_head->truesize += packet_buffer_size; | 392 | ctx->skb_head->truesize += truesize; |
| 393 | } | 393 | } |
| 394 | skb_add_rx_frag(skb, num_frags, page_info->page, | 394 | skb_add_rx_frag(skb, num_frags, page_info->page, |
| 395 | offset, len, packet_buffer_size); | 395 | offset, len, truesize); |
| 396 | 396 | ||
| 397 | return ctx->skb_head; | 397 | return ctx->skb_head; |
| 398 | } | 398 | } |
| @@ -486,7 +486,7 @@ static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx, · 87 unmodified lines | |||
| 486 | 486 | ||
| 487 | memcpy(alloc_page_info.page_address, src, page_info->pad + len); | 487 | memcpy(alloc_page_info.page_address, src, page_info->pad + len); |
| 488 | skb = gve_rx_add_frags(napi, &alloc_page_info, | 488 | skb = gve_rx_add_frags(napi, &alloc_page_info, |
| 489 | rx->packet_buffer_size, | 489 | PAGE_SIZE, |
| 490 | len, ctx); | 490 | len, ctx); |
| 491 | 491 | ||
| 492 | u64_stats_update_begin(&rx->statss); | 492 | u64_stats_update_begin(&rx->statss); |
| @@ -360,23 +360,43 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca); · 359 unmodified lines | |||
| 360 | * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of | 360 | * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of |
| 361 | * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) | 361 | * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) |
| 362 | * bits to count nanoseconds leaving the rest for fractional nonseconds. | 362 | * bits to count nanoseconds leaving the rest for fractional nonseconds. |
| 363 | * | ||
| 364 | * Any given INCVALUE also has an associated maximum adjustment value. This | ||
| 365 | * maximum adjustment value is the largest increase (or decrease) which can be | ||
| 366 | * safely applied without overflowing the INCVALUE. Since INCVALUE has | ||
| 367 | * a maximum range of 24 bits, its largest value is 0xFFFFFF. | ||
| 368 | * | ||
| 369 | * To understand where the maximum value comes from, consider the following | ||
| 370 | * equation: | ||
| 371 | * | ||
| 372 | * new_incval = base_incval + (base_incval * adjustment) / 1billion | ||
| 373 | * | ||
| 374 | * To avoid overflow that means: | ||
| 375 | * max_incval = base_incval + (base_incval * max_adj) / billion | ||
| 376 | * | ||
| 377 | * Re-arranging: | ||
| 378 | * max_adj = floor(((max_incval - base_incval) * 1billion) / 1billion) | ||
| 363 | */ | 379 | */ |
| 364 | #define INCVALUE_96MHZ 125 | 380 | #define INCVALUE_96MHZ 125 |
| 365 | #define INCVALUE_SHIFT_96MHZ 17 | 381 | #define INCVALUE_SHIFT_96MHZ 17 |
| 366 | #define INCPERIOD_SHIFT_96MHZ 2 | 382 | #define INCPERIOD_SHIFT_96MHZ 2 |
| 367 | #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) | 383 | #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) |
| 384 | #define MAX_PPB_96MHZ 23999900 /* 23,999,900 ppb */ | ||
| 368 | 385 | ||
| 369 | #define INCVALUE_25MHZ 40 | 386 | #define INCVALUE_25MHZ 40 |
| 370 | #define INCVALUE_SHIFT_25MHZ 18 | 387 | #define INCVALUE_SHIFT_25MHZ 18 |
| 371 | #define INCPERIOD_25MHZ 1 | 388 | #define INCPERIOD_25MHZ 1 |
| 389 | #define MAX_PPB_25MHZ 599999900 /* 599,999,900 ppb */ | ||
| 372 | 390 | ||
| 373 | #define INCVALUE_24MHZ 125 | 391 | #define INCVALUE_24MHZ 125 |
| 374 | #define INCVALUE_SHIFT_24MHZ 14 | 392 | #define INCVALUE_SHIFT_24MHZ 14 |
| 375 | #define INCPERIOD_24MHZ 3 | 393 | #define INCPERIOD_24MHZ 3 |
| 394 | #define MAX_PPB_24MHZ 999999999 /* 999,999,999 ppb */ | ||
| 376 | 395 | ||
| 377 | #define INCVALUE_38400KHZ 26 | 396 | #define INCVALUE_38400KHZ 26 |
| 378 | #define INCVALUE_SHIFT_38400KHZ 19 | 397 | #define INCVALUE_SHIFT_38400KHZ 19 |
| 379 | #define INCPERIOD_38400KHZ 1 | 398 | #define INCPERIOD_38400KHZ 1 |
| 399 | #define MAX_PPB_38400KHZ 230769100 /* 230,769,100 ppb */ | ||
| 380 | 400 | ||
| 381 | /* Another drawback of scaling the incvalue by a large factor is the | 401 | /* Another drawback of scaling the incvalue by a large factor is the |
| 382 | * 64-bit SYSTIM register overflows more quickly. This is dealt with | 402 | * 64-bit SYSTIM register overflows more quickly. This is dealt with |
| @@ -280,8 +280,17 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) · 279 unmodified lines | |||
| 280 | 280 | ||
| 281 | switch (hw->mac.type) { | 281 | switch (hw->mac.type) { |
| 282 | case e1000_pch2lan: | 282 | case e1000_pch2lan: |
| 283 | adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; | ||
| 284 | break; | ||
| 283 | case e1000_pch_lpt: | 285 | case e1000_pch_lpt: |
| 286 | if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) | ||
| 287 | adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; | ||
| 288 | else | ||
| 289 | adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; | ||
| 290 | break; | ||
| 284 | case e1000_pch_spt: | 291 | case e1000_pch_spt: |
| 292 | adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; | ||
| 293 | break; | ||
| 285 | case e1000_pch_cnp: | 294 | case e1000_pch_cnp: |
| 286 | case e1000_pch_tgp: | 295 | case e1000_pch_tgp: |
| 287 | case e1000_pch_adp: | 296 | case e1000_pch_adp: |
| @@ -289,15 +298,14 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) · 1 unmodified line | |||
| 289 | case e1000_pch_lnp: | 298 | case e1000_pch_lnp: |
| 290 | case e1000_pch_ptp: | 299 | case e1000_pch_ptp: |
| 291 | case e1000_pch_nvp: | 300 | case e1000_pch_nvp: |
| 292 | if ((hw->mac.type < e1000_pch_lpt) || | 301 | if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) |
| 293 | (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) { | 302 | adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; |
| 294 | adapter->ptp_clock_info.max_adj = 24000000 - 1; | 303 | else |
| 295 | break; | 304 | adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; |
| 296 | } | 305 | break; |
| 297 | fallthrough; | ||
| 298 | case e1000_82574: | 306 | case e1000_82574: |
| 299 | case e1000_82583: | 307 | case e1000_82583: |
| 300 | adapter->ptp_clock_info.max_adj = 600000000 - 1; | 308 | adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; |
| 301 | break; | 309 | break; |
| 302 | default: | 310 | default: |
| 303 | break; | 311 | break; |
| @@ -978,7 +978,7 @@ struct virtchnl2_ptype { · 977 unmodified lines | |||
| 978 | u8 proto_id_count; | 978 | u8 proto_id_count; |
| 979 | __le16 pad; | 979 | __le16 pad; |
| 980 | __le16 proto_id[]; | 980 | __le16 proto_id[]; |
| 981 | }; | 981 | } __packed __aligned(2); |
| 982 | VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype); | 982 | VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype); |
| 983 | 983 | ||
| 984 | /** | 984 | /** |
| @@ -716,7 +716,8 @@ static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, · 715 unmodified lines | |||
| 716 | if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { | 716 | if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { |
| 717 | error = FIELD_GET(IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK, command); | 717 | error = FIELD_GET(IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK, command); |
| 718 | hw_dbg(hw, "Failed to read, error %x\n", error); | 718 | hw_dbg(hw, "Failed to read, error %x\n", error); |
| 719 | return -EIO; | 719 | ret = -EIO; |
| 720 | goto out; | ||
| 720 | } | 721 | } |
| 721 | 722 | ||
| 722 | if (!ret) | 723 | if (!ret) |
| @@ -314,7 +314,6 @@ static int otx2_set_channels(struct net_device *dev, · 313 unmodified lines | |||
| 314 | pfvf->hw.tx_queues = channel->tx_count; | 314 | pfvf->hw.tx_queues = channel->tx_count; |
| 315 | if (pfvf->xdp_prog) | 315 | if (pfvf->xdp_prog) |
| 316 | pfvf->hw.xdp_queues = channel->rx_count; | 316 | pfvf->hw.xdp_queues = channel->rx_count; |
| 317 | pfvf->hw.non_qos_queues = pfvf->hw.tx_queues + pfvf->hw.xdp_queues; | ||
| 318 | 317 | ||
| 319 | if (if_up) | 318 | if (if_up) |
| 320 | err = dev->netdev_ops->ndo_open(dev); | 319 | err = dev->netdev_ops->ndo_open(dev); |
| @@ -1744,6 +1744,7 @@ int otx2_open(struct net_device *netdev) · 1743 unmodified lines | |||
| 1744 | /* RQ and SQs are mapped to different CQs, | 1744 | /* RQ and SQs are mapped to different CQs, |
| 1745 | * so find out max CQ IRQs (i.e CINTs) needed. | 1745 | * so find out max CQ IRQs (i.e CINTs) needed. |
| 1746 | */ | 1746 | */ |
| 1747 | pf->hw.non_qos_queues = pf->hw.tx_queues + pf->hw.xdp_queues; | ||
| 1747 | pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, | 1748 | pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, |
| 1748 | pf->hw.tc_tx_queues); | 1749 | pf->hw.tc_tx_queues); |
| 1749 | 1750 | ||
| @@ -2643,8 +2644,6 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog) · 893 unmodified lines | |||
| 2643 | xdp_features_clear_redirect_target(dev); | 2644 | xdp_features_clear_redirect_target(dev); |
| 2644 | } | 2645 | } |
| 2645 | 2646 | ||
| 2646 | pf->hw.non_qos_queues += pf->hw.xdp_queues; | ||
| 2647 | |||
| 2648 | if (if_up) | 2647 | if (if_up) |
| 2649 | otx2_open(pf->netdev); | 2648 | otx2_open(pf->netdev); |
| 2650 | 2649 | ||
| @@ -1403,7 +1403,7 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, · 1402 unmodified lines | |||
| 1403 | struct otx2_cq_queue *cq, | 1403 | struct otx2_cq_queue *cq, |
| 1404 | bool *need_xdp_flush) | 1404 | bool *need_xdp_flush) |
| 1405 | { | 1405 | { |
| 1406 | unsigned char *hard_start, *data; | 1406 | unsigned char *hard_start; |
| 1407 | int qidx = cq->cq_idx; | 1407 | int qidx = cq->cq_idx; |
| 1408 | struct xdp_buff xdp; | 1408 | struct xdp_buff xdp; |
| 1409 | struct page *page; | 1409 | struct page *page; |
| @@ -1417,9 +1417,8 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, · 7 unmodified lines | |||
| 1417 | 1417 | ||
| 1418 | xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); | 1418 | xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); |
| 1419 | 1419 | ||
| 1420 | data = (unsigned char *)phys_to_virt(pa); | 1420 | hard_start = (unsigned char *)phys_to_virt(pa); |
| 1421 | hard_start = page_address(page); | 1421 | xdp_prepare_buff(&xdp, hard_start, OTX2_HEAD_ROOM, |
| 1422 | xdp_prepare_buff(&xdp, hard_start, data - hard_start, | ||
| 1423 | cqe->sg.seg_size, false); | 1422 | cqe->sg.seg_size, false); |
| 1424 | 1423 | ||
| 1425 | act = bpf_prog_run_xdp(prog, &xdp); | 1424 | act = bpf_prog_run_xdp(prog, &xdp); |
| @@ -4761,7 +4761,10 @@ static int mtk_probe(struct platform_device *pdev) · 4760 unmodified lines | |||
| 4761 | } | 4761 | } |
| 4762 | 4762 | ||
| 4763 | if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { | 4763 | if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { |
| 4764 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); | 4764 | err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); |
| 4765 | if (!err) | ||
| 4766 | err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); | ||
| 4767 | |||
| 4765 | if (err) { | 4768 | if (err) { |
| 4766 | dev_err(&pdev->dev, "Wrong DMA config\n"); | 4769 | dev_err(&pdev->dev, "Wrong DMA config\n"); |
| 4767 | return -EINVAL; | 4770 | return -EINVAL; |
| @@ -168,9 +168,10 @@ static void lan966x_port_link_up(struct lan966x_port *port) · 167 unmodified lines | |||
| 168 | lan966x_taprio_speed_set(port, config->speed); | 168 | lan966x_taprio_speed_set(port, config->speed); |
| 169 | 169 | ||
| 170 | /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the | 170 | /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the |
| 171 | * port speed for QSGMII ports. | 171 | * port speed for QSGMII or SGMII ports. |
| 172 | */ | 172 | */ |
| 173 | if (phy_interface_num_ports(config->portmode) == 4) | 173 | if (phy_interface_num_ports(config->portmode) == 4 || |
| 174 | config->portmode == PHY_INTERFACE_MODE_SGMII) | ||
| 174 | mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); | 175 | mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); |
| 175 | 176 | ||
| 176 | lan_wr(config->duplex | mode, | 177 | lan_wr(config->duplex | mode, |
| @@ -1424,10 +1424,30 @@ static void nfp_nft_ct_translate_mangle_action(struct flow_action_entry *mangle_ · 1423 unmodified lines | |||
| 1424 | mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask); | 1424 | mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask); |
| 1425 | return; | 1425 | return; |
| 1426 | 1426 | ||
| 1427 | /* Both struct tcphdr and struct udphdr start with | ||
| 1428 | * __be16 source; | ||
| 1429 | * __be16 dest; | ||
| 1430 | * so we can use the same code for both. | ||
| 1431 | */ | ||
| 1427 | case FLOW_ACT_MANGLE_HDR_TYPE_TCP: | 1432 | case FLOW_ACT_MANGLE_HDR_TYPE_TCP: |
| 1428 | case FLOW_ACT_MANGLE_HDR_TYPE_UDP: | 1433 | case FLOW_ACT_MANGLE_HDR_TYPE_UDP: |
| 1429 | mangle_action->mangle.val = (__force u16)cpu_to_be16(mangle_action->mangle.val); | 1434 | if (mangle_action->mangle.offset == offsetof(struct tcphdr, source)) { |
| 1430 | mangle_action->mangle.mask = (__force u16)cpu_to_be16(mangle_action->mangle.mask); | 1435 | mangle_action->mangle.val = |
| 1436 | (__force u32)cpu_to_be32(mangle_action->mangle.val << 16); | ||
| 1437 | /* The mask of mangle action is inverse mask, | ||
| 1438 | * so clear the dest tp port with 0xFFFF to | ||
| 1439 | * instead of rotate-left operation. | ||
| 1440 | */ | ||
| 1441 | mangle_action->mangle.mask = | ||
| 1442 | (__force u32)cpu_to_be32(mangle_action->mangle.mask << 16 | 0xFFFF); | ||
| 1443 | } | ||
| 1444 | if (mangle_action->mangle.offset == offsetof(struct tcphdr, dest)) { | ||
| 1445 | mangle_action->mangle.offset = 0; | ||
| 1446 | mangle_action->mangle.val = | ||
| 1447 | (__force u32)cpu_to_be32(mangle_action->mangle.val); | ||
| 1448 | mangle_action->mangle.mask = | ||
| 1449 | (__force u32)cpu_to_be32(mangle_action->mangle.mask); | ||
| 1450 | } | ||
| 1431 | return; | 1451 | return; |
| 1432 | 1452 | ||
| 1433 | default: | 1453 | default: |
| @@ -1864,10 +1884,30 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv, · 430 unmodified lines | |||
| 1864 | { | 1884 | { |
| 1865 | struct flow_rule *rule = flow_cls_offload_flow_rule(flow); | 1885 | struct flow_rule *rule = flow_cls_offload_flow_rule(flow); |
| 1866 | struct nfp_fl_ct_flow_entry *ct_entry; | 1886 | struct nfp_fl_ct_flow_entry *ct_entry; |
| 1887 | struct flow_action_entry *ct_goto; | ||
| 1867 | struct nfp_fl_ct_zone_entry *zt; | 1888 | struct nfp_fl_ct_zone_entry *zt; |
| 1889 | struct flow_action_entry *act; | ||
| 1868 | bool wildcarded = false; | 1890 | bool wildcarded = false; |
| 1869 | struct flow_match_ct ct; | 1891 | struct flow_match_ct ct; |
| 1870 | struct flow_action_entry *ct_goto; | 1892 | int i; |
| 1893 | |||
| 1894 | flow_action_for_each(i, act, &rule->action) { | ||
| 1895 | switch (act->id) { | ||
| 1896 | case FLOW_ACTION_REDIRECT: | ||
| 1897 | case FLOW_ACTION_REDIRECT_INGRESS: | ||
| 1898 | case FLOW_ACTION_MIRRED: | ||
| 1899 | case FLOW_ACTION_MIRRED_INGRESS: | ||
| 1900 | if (act->dev->rtnl_link_ops && | ||
| 1901 | !strcmp(act->dev->rtnl_link_ops->kind, "openvswitch")) { | ||
| 1902 | NL_SET_ERR_MSG_MOD(extack, | ||
| 1903 | "unsupported offload: out port is openvswitch internal port"); | ||
| 1904 | return -EOPNOTSUPP; | ||
| 1905 | } | ||
| 1906 | break; | ||
| 1907 | default: | ||
| 1908 | break; | ||
| 1909 | } | ||
| 1910 | } | ||
| 1871 | 1911 | ||
| 1872 | flow_rule_match_ct(rule, &ct); | 1912 | flow_rule_match_ct(rule, &ct); |
| 1873 | if (!ct.mask->ct_zone) { | 1913 | if (!ct.mask->ct_zone) { |
| @@ -353,6 +353,10 @@ static int imx_dwmac_probe(struct platform_device *pdev) · 352 unmodified lines | |||
| 353 | if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) | 353 | if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) |
| 354 | plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; | 354 | plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; |
| 355 | 355 | ||
| 356 | /* Default TX Q0 to use TSO and rest TXQ for TBS */ | ||
| 357 | for (int i = 1; i < plat_dat->tx_queues_to_use; i++) | ||
| 358 | plat_dat->tx_queues_cfg[i].tbs_en = 1; | ||
| 359 | |||
| 356 | plat_dat->host_dma_width = dwmac->ops->addr_width; | 360 | plat_dat->host_dma_width = dwmac->ops->addr_width; |
| 357 | plat_dat->init = imx_dwmac_init; | 361 | plat_dat->init = imx_dwmac_init; |
| 358 | plat_dat->exit = imx_dwmac_exit; | 362 | plat_dat->exit = imx_dwmac_exit; |
| @@ -3932,6 +3932,9 @@ static int __stmmac_open(struct net_device *dev, · 3931 unmodified lines | |||
| 3932 | priv->rx_copybreak = STMMAC_RX_COPYBREAK; | 3932 | priv->rx_copybreak = STMMAC_RX_COPYBREAK; |
| 3933 | 3933 | ||
| 3934 | buf_sz = dma_conf->dma_buf_sz; | 3934 | buf_sz = dma_conf->dma_buf_sz; |
| 3935 | for (int i = 0; i < MTL_MAX_TX_QUEUES; i++) | ||
| 3936 | if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN) | ||
| 3937 | dma_conf->tx_queue[i].tbs = priv->dma_conf.tx_queue[i].tbs; | ||
| 3935 | memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); | 3938 | memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); |
| 3936 | 3939 | ||
| 3937 | stmmac_reset_queues_param(priv); | 3940 | stmmac_reset_queues_param(priv); |
| @@ -708,7 +708,10 @@ void netvsc_device_remove(struct hv_device *device) · 707 unmodified lines | |||
| 708 | /* Disable NAPI and disassociate its context from the device. */ | 708 | /* Disable NAPI and disassociate its context from the device. */ |
| 709 | for (i = 0; i < net_device->num_chn; i++) { | 709 | for (i = 0; i < net_device->num_chn; i++) { |
| 710 | /* See also vmbus_reset_channel_cb(). */ | 710 | /* See also vmbus_reset_channel_cb(). */ |
| 711 | napi_disable(&net_device->chan_table[i].napi); | 711 | /* only disable enabled NAPI channel */ |
| 712 | if (i < ndev->real_num_rx_queues) | ||
| 713 | napi_disable(&net_device->chan_table[i].napi); | ||
| 714 | |||
| 712 | netif_napi_del(&net_device->chan_table[i].napi); | 715 | netif_napi_del(&net_device->chan_table[i].napi); |
| 713 | } | 716 | } |
| 714 | 717 | ||
| @@ -489,7 +489,7 @@ static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val, · 488 unmodified lines | |||
| 489 | u16 reg, val; | 489 | u16 reg, val; |
| 490 | 490 | ||
| 491 | if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) | 491 | if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) |
| 492 | bias = -2; | 492 | bias = -1; |
| 493 | 493 | ||
| 494 | val = clamp_val(bias + tx_r50_cal_val, 0, 63); | 494 | val = clamp_val(bias + tx_r50_cal_val, 0, 63); |
| 495 | 495 | ||
| @@ -705,6 +705,11 @@ restore: · 209 unmodified lines | |||
| 705 | static void mt798x_phy_common_finetune(struct phy_device *phydev) | 705 | static void mt798x_phy_common_finetune(struct phy_device *phydev) |
| 706 | { | 706 | { |
| 707 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | 707 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); |
| 708 | /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ | ||
| 709 | __phy_write(phydev, 0x11, 0xc71); | ||
| 710 | __phy_write(phydev, 0x12, 0xc); | ||
| 711 | __phy_write(phydev, 0x10, 0x8fae); | ||
| 712 | |||
| 708 | /* EnabRandUpdTrig = 1 */ | 713 | /* EnabRandUpdTrig = 1 */ |
| 709 | __phy_write(phydev, 0x11, 0x2f00); | 714 | __phy_write(phydev, 0x11, 0x2f00); |
| 710 | __phy_write(phydev, 0x12, 0xe); | 715 | __phy_write(phydev, 0x12, 0xe); |
| @@ -715,15 +720,56 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 4 unmodified lines | |||
| 715 | __phy_write(phydev, 0x12, 0x0); | 720 | __phy_write(phydev, 0x12, 0x0); |
| 716 | __phy_write(phydev, 0x10, 0x83aa); | 721 | __phy_write(phydev, 0x10, 0x83aa); |
| 717 | 722 | ||
| 718 | /* TrFreeze = 0 */ | 723 | /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ |
| 724 | __phy_write(phydev, 0x11, 0x240); | ||
| 725 | __phy_write(phydev, 0x12, 0x0); | ||
| 726 | __phy_write(phydev, 0x10, 0x9680); | ||
| 727 | |||
| 728 | /* TrFreeze = 0 (mt7988 default) */ | ||
| 719 | __phy_write(phydev, 0x11, 0x0); | 729 | __phy_write(phydev, 0x11, 0x0); |
| 720 | __phy_write(phydev, 0x12, 0x0); | 730 | __phy_write(phydev, 0x12, 0x0); |
| 721 | __phy_write(phydev, 0x10, 0x9686); | 731 | __phy_write(phydev, 0x10, 0x9686); |
| 722 | 732 | ||
| 733 | /* SSTrKp100 = 5 */ | ||
| 734 | /* SSTrKf100 = 6 */ | ||
| 735 | /* SSTrKp1000Mas = 5 */ | ||
| 736 | /* SSTrKf1000Mas = 6 */ | ||
| 723 | /* SSTrKp1000Slv = 5 */ | 737 | /* SSTrKp1000Slv = 5 */ |
| 738 | /* SSTrKf1000Slv = 6 */ | ||
| 724 | __phy_write(phydev, 0x11, 0xbaef); | 739 | __phy_write(phydev, 0x11, 0xbaef); |
| 725 | __phy_write(phydev, 0x12, 0x2e); | 740 | __phy_write(phydev, 0x12, 0x2e); |
| 726 | __phy_write(phydev, 0x10, 0x968c); | 741 | __phy_write(phydev, 0x10, 0x968c); |
| 742 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | ||
| 743 | } | ||
| 744 | |||
| 745 | static void mt7981_phy_finetune(struct phy_device *phydev) | ||
| 746 | { | ||
| 747 | u16 val[8] = { 0x01ce, 0x01c1, | ||
| 748 | 0x020f, 0x0202, | ||
| 749 | 0x03d0, 0x03c0, | ||
| 750 | 0x0013, 0x0005 }; | ||
| 751 | int i, k; | ||
| 752 | |||
| 753 | /* 100M eye finetune: | ||
| 754 | * Keep middle level of TX MLT3 shapper as default. | ||
| 755 | * Only change TX MLT3 overshoot level here. | ||
| 756 | */ | ||
| 757 | for (k = 0, i = 1; i < 12; i++) { | ||
| 758 | if (i % 3 == 0) | ||
| 759 | continue; | ||
| 760 | phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); | ||
| 761 | } | ||
| 762 | |||
| 763 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | ||
| 764 | /* ResetSyncOffset = 6 */ | ||
| 765 | __phy_write(phydev, 0x11, 0x600); | ||
| 766 | __phy_write(phydev, 0x12, 0x0); | ||
| 767 | __phy_write(phydev, 0x10, 0x8fc0); | ||
| 768 | |||
| 769 | /* VgaDecRate = 1 */ | ||
| 770 | __phy_write(phydev, 0x11, 0x4c2a); | ||
| 771 | __phy_write(phydev, 0x12, 0x3e); | ||
| 772 | __phy_write(phydev, 0x10, 0x8fa4); | ||
| 727 | 773 | ||
| 728 | /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, | 774 | /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, |
| 729 | * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 | 775 | * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 |
| @@ -738,7 +784,7 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 8 unmodified lines | |||
| 738 | __phy_write(phydev, 0x10, 0x8ec0); | 784 | __phy_write(phydev, 0x10, 0x8ec0); |
| 739 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | 785 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); |
| 740 | 786 | ||
| 741 | /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/ | 787 | /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ |
| 742 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, | 788 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, |
| 743 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, | 789 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, |
| 744 | BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); | 790 | BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); |
| @@ -771,48 +817,6 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 26 unmodified lines | |||
| 771 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); | 817 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); |
| 772 | } | 818 | } |
| 773 | 819 | ||
| 774 | static void mt7981_phy_finetune(struct phy_device *phydev) | ||
| 775 | { | ||
| 776 | u16 val[8] = { 0x01ce, 0x01c1, | ||
| 777 | 0x020f, 0x0202, | ||
| 778 | 0x03d0, 0x03c0, | ||
| 779 | 0x0013, 0x0005 }; | ||
| 780 | int i, k; | ||
| 781 | |||
| 782 | /* 100M eye finetune: | ||
| 783 | * Keep middle level of TX MLT3 shapper as default. | ||
| 784 | * Only change TX MLT3 overshoot level here. | ||
| 785 | */ | ||
| 786 | for (k = 0, i = 1; i < 12; i++) { | ||
| 787 | if (i % 3 == 0) | ||
| 788 | continue; | ||
| 789 | phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); | ||
| 790 | } | ||
| 791 | |||
| 792 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | ||
| 793 | /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ | ||
| 794 | __phy_write(phydev, 0x11, 0xc71); | ||
| 795 | __phy_write(phydev, 0x12, 0xc); | ||
| 796 | __phy_write(phydev, 0x10, 0x8fae); | ||
| 797 | |||
| 798 | /* ResetSyncOffset = 6 */ | ||
| 799 | __phy_write(phydev, 0x11, 0x600); | ||
| 800 | __phy_write(phydev, 0x12, 0x0); | ||
| 801 | __phy_write(phydev, 0x10, 0x8fc0); | ||
| 802 | |||
| 803 | /* VgaDecRate = 1 */ | ||
| 804 | __phy_write(phydev, 0x11, 0x4c2a); | ||
| 805 | __phy_write(phydev, 0x12, 0x3e); | ||
| 806 | __phy_write(phydev, 0x10, 0x8fa4); | ||
| 807 | |||
| 808 | /* FfeUpdGainForce = 4 */ | ||
| 809 | __phy_write(phydev, 0x11, 0x240); | ||
| 810 | __phy_write(phydev, 0x12, 0x0); | ||
| 811 | __phy_write(phydev, 0x10, 0x9680); | ||
| 812 | |||
| 813 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | ||
| 814 | } | ||
| 815 | |||
| 816 | static void mt7988_phy_finetune(struct phy_device *phydev) | 820 | static void mt7988_phy_finetune(struct phy_device *phydev) |
| 817 | { | 821 | { |
| 818 | u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, | 822 | u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, |
| @@ -827,17 +831,7 @@ static void mt7988_phy_finetune(struct phy_device *phydev) · 8 unmodified lines | |||
| 827 | /* TCT finetune */ | 831 | /* TCT finetune */ |
| 828 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); | 832 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); |
| 829 | 833 | ||
| 830 | /* Disable TX power saving */ | ||
| 831 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, | ||
| 832 | MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); | ||
| 833 | |||
| 834 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); | 834 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); |
| 835 | |||
| 836 | /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */ | ||
| 837 | __phy_write(phydev, 0x11, 0x671); | ||
| 838 | __phy_write(phydev, 0x12, 0xc); | ||
| 839 | __phy_write(phydev, 0x10, 0x8fae); | ||
| 840 | |||
| 841 | /* ResetSyncOffset = 5 */ | 835 | /* ResetSyncOffset = 5 */ |
| 842 | __phy_write(phydev, 0x11, 0x500); | 836 | __phy_write(phydev, 0x11, 0x500); |
| 843 | __phy_write(phydev, 0x12, 0x0); | 837 | __phy_write(phydev, 0x12, 0x0); |
| @@ -845,13 +839,27 @@ static void mt7988_phy_finetune(struct phy_device *phydev) · 1 unmodified line | |||
| 845 | 839 | ||
| 846 | /* VgaDecRate is 1 at default on mt7988 */ | 840 | /* VgaDecRate is 1 at default on mt7988 */ |
| 847 | 841 | ||
| 848 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | 842 | /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, |
| 843 | * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 | ||
| 844 | */ | ||
| 845 | __phy_write(phydev, 0x11, 0xb90a); | ||
| 846 | __phy_write(phydev, 0x12, 0x6f); | ||
| 847 | __phy_write(phydev, 0x10, 0x8f82); | ||
| 848 | |||
| 849 | /* RemAckCntLimitCtrl = 1 */ | ||
| 850 | __phy_write(phydev, 0x11, 0xfbba); | ||
| 851 | __phy_write(phydev, 0x12, 0xc3); | ||
| 852 | __phy_write(phydev, 0x10, 0x87f8); | ||
| 849 | 853 | ||
| 850 | phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30); | ||
| 851 | /* TxClkOffset = 2 */ | ||
| 852 | __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK, | ||
| 853 | FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2)); | ||
| 854 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); | 854 | phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); |
| 855 | |||
| 856 | /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ | ||
| 857 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, | ||
| 858 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, | ||
| 859 | BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); | ||
| 860 | |||
| 861 | /* rg_tr_lpf_cnt_val = 1023 */ | ||
| 862 | phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); | ||
| 855 | } | 863 | } |
| 856 | 864 | ||
| 857 | static void mt798x_phy_eee(struct phy_device *phydev) | 865 | static void mt798x_phy_eee(struct phy_device *phydev) |
| @@ -884,11 +892,11 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 26 unmodified lines | |||
| 884 | MTK_PHY_LPI_SLV_SEND_TX_EN, | 892 | MTK_PHY_LPI_SLV_SEND_TX_EN, |
| 885 | FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); | 893 | FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); |
| 886 | 894 | ||
| 887 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, | 895 | /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ |
| 888 | MTK_PHY_LPI_SEND_LOC_TIMER_MASK | | 896 | phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, |
| 889 | MTK_PHY_LPI_TXPCS_LOC_RCV, | 897 | MTK_PHY_LPI_TXPCS_LOC_RCV); |
| 890 | FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); | ||
| 891 | 898 | ||
| 899 | /* This also fixes some IoT issues, such as CH340 */ | ||
| 892 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, | 900 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, |
| 893 | MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, | 901 | MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, |
| 894 | FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | | 902 | FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | |
| @@ -922,7 +930,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 27 unmodified lines | |||
| 922 | __phy_write(phydev, 0x12, 0x0); | 930 | __phy_write(phydev, 0x12, 0x0); |
| 923 | __phy_write(phydev, 0x10, 0x9690); | 931 | __phy_write(phydev, 0x10, 0x9690); |
| 924 | 932 | ||
| 925 | /* REG_EEE_st2TrKf1000 = 3 */ | 933 | /* REG_EEE_st2TrKf1000 = 2 */ |
| 926 | __phy_write(phydev, 0x11, 0x114f); | 934 | __phy_write(phydev, 0x11, 0x114f); |
| 927 | __phy_write(phydev, 0x12, 0x2); | 935 | __phy_write(phydev, 0x12, 0x2); |
| 928 | __phy_write(phydev, 0x10, 0x969a); | 936 | __phy_write(phydev, 0x10, 0x969a); |
| @@ -947,7 +955,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 18 unmodified lines | |||
| 947 | __phy_write(phydev, 0x12, 0x0); | 955 | __phy_write(phydev, 0x12, 0x0); |
| 948 | __phy_write(phydev, 0x10, 0x96b8); | 956 | __phy_write(phydev, 0x10, 0x96b8); |
| 949 | 957 | ||
| 950 | /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */ | 958 | /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ |
| 951 | __phy_write(phydev, 0x11, 0x1463); | 959 | __phy_write(phydev, 0x11, 0x1463); |
| 952 | __phy_write(phydev, 0x12, 0x0); | 960 | __phy_write(phydev, 0x12, 0x0); |
| 953 | __phy_write(phydev, 0x10, 0x96ca); | 961 | __phy_write(phydev, 0x10, 0x96ca); |
| @@ -1459,6 +1467,13 @@ static int mt7988_phy_probe(struct phy_device *phydev) · 505 unmodified lines | |||
| 1459 | if (err) | 1467 | if (err) |
| 1460 | return err; | 1468 | return err; |
| 1461 | 1469 | ||
| 1470 | /* Disable TX power saving at probing to: | ||
| 1471 | * 1. Meet common mode compliance test criteria | ||
| 1472 | * 2. Make sure that TX-VCM calibration works fine | ||
| 1473 | */ | ||
| 1474 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, | ||
| 1475 | MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); | ||
| 1476 | |||
| 1462 | return mt798x_phy_calibration(phydev); | 1477 | return mt798x_phy_calibration(phydev); |
| 1463 | } | 1478 | } |
| 1464 | 1479 | ||
| @@ -104,13 +104,12 @@ bool provides_xdp_headroom = true; · 103 unmodified lines | |||
| 104 | module_param(provides_xdp_headroom, bool, 0644); | 104 | module_param(provides_xdp_headroom, bool, 0644); |
| 105 | 105 | ||
| 106 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | 106 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, |
| 107 | u8 status); | 107 | s8 status); |
| 108 | 108 | ||
| 109 | static void make_tx_response(struct xenvif_queue *queue, | 109 | static void make_tx_response(struct xenvif_queue *queue, |
| 110 | struct xen_netif_tx_request *txp, | 110 | const struct xen_netif_tx_request *txp, |
| 111 | unsigned int extra_count, | 111 | unsigned int extra_count, |
| 112 | s8 st); | 112 | s8 status); |
| 113 | static void push_tx_responses(struct xenvif_queue *queue); | ||
| 114 | 113 | ||
| 115 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); | 114 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); |
| 116 | 115 | ||
| @@ -208,13 +207,9 @@ static void xenvif_tx_err(struct xenvif_queue *queue, · 91 unmodified lines | |||
| 208 | unsigned int extra_count, RING_IDX end) | 207 | unsigned int extra_count, RING_IDX end) |
| 209 | { | 208 | { |
| 210 | RING_IDX cons = queue->tx.req_cons; | 209 | RING_IDX cons = queue->tx.req_cons; |
| 211 | unsigned long flags; | ||
| 212 | 210 | ||
| 213 | do { | 211 | do { |
| 214 | spin_lock_irqsave(&queue->response_lock, flags); | ||
| 215 | make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); | 212 | make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); |
| 216 | push_tx_responses(queue); | ||
| 217 | spin_unlock_irqrestore(&queue->response_lock, flags); | ||
| 218 | if (cons == end) | 213 | if (cons == end) |
| 219 | break; | 214 | break; |
| 220 | RING_COPY_REQUEST(&queue->tx, cons++, txp); | 215 | RING_COPY_REQUEST(&queue->tx, cons++, txp); |
| @@ -465,12 +460,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 244 unmodified lines | |||
| 465 | for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; | 460 | for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; |
| 466 | nr_slots--) { | 461 | nr_slots--) { |
| 467 | if (unlikely(!txp->size)) { | 462 | if (unlikely(!txp->size)) { |
| 468 | unsigned long flags; | ||
| 469 | |||
| 470 | spin_lock_irqsave(&queue->response_lock, flags); | ||
| 471 | make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); | 463 | make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); |
| 472 | push_tx_responses(queue); | ||
| 473 | spin_unlock_irqrestore(&queue->response_lock, flags); | ||
| 474 | ++txp; | 464 | ++txp; |
| 475 | continue; | 465 | continue; |
| 476 | } | 466 | } |
| @@ -496,14 +486,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 19 unmodified lines | |||
| 496 | 486 | ||
| 497 | for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { | 487 | for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { |
| 498 | if (unlikely(!txp->size)) { | 488 | if (unlikely(!txp->size)) { |
| 499 | unsigned long flags; | ||
| 500 | |||
| 501 | spin_lock_irqsave(&queue->response_lock, flags); | ||
| 502 | make_tx_response(queue, txp, 0, | 489 | make_tx_response(queue, txp, 0, |
| 503 | XEN_NETIF_RSP_OKAY); | 490 | XEN_NETIF_RSP_OKAY); |
| 504 | push_tx_responses(queue); | ||
| 505 | spin_unlock_irqrestore(&queue->response_lock, | ||
| 506 | flags); | ||
| 507 | continue; | 491 | continue; |
| 508 | } | 492 | } |
| 509 | 493 | ||
| @@ -995,7 +979,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 485 unmodified lines | |||
| 995 | (ret == 0) ? | 979 | (ret == 0) ? |
| 996 | XEN_NETIF_RSP_OKAY : | 980 | XEN_NETIF_RSP_OKAY : |
| 997 | XEN_NETIF_RSP_ERROR); | 981 | XEN_NETIF_RSP_ERROR); |
| 998 | push_tx_responses(queue); | ||
| 999 | continue; | 982 | continue; |
| 1000 | } | 983 | } |
| 1001 | 984 | ||
| @@ -1007,7 +990,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 5 unmodified lines | |||
| 1007 | 990 | ||
| 1008 | make_tx_response(queue, &txreq, extra_count, | 991 | make_tx_response(queue, &txreq, extra_count, |
| 1009 | XEN_NETIF_RSP_OKAY); | 992 | XEN_NETIF_RSP_OKAY); |
| 1010 | push_tx_responses(queue); | ||
| 1011 | continue; | 993 | continue; |
| 1012 | } | 994 | } |
| 1013 | 995 | ||
| @@ -1433,8 +1415,35 @@ int xenvif_tx_action(struct xenvif_queue *queue, int budget) · 419 unmodified lines | |||
| 1433 | return work_done; | 1415 | return work_done; |
| 1434 | } | 1416 | } |
| 1435 | 1417 | ||
| 1418 | static void _make_tx_response(struct xenvif_queue *queue, | ||
| 1419 | const struct xen_netif_tx_request *txp, | ||
| 1420 | unsigned int extra_count, | ||
| 1421 | s8 status) | ||
| 1422 | { | ||
| 1423 | RING_IDX i = queue->tx.rsp_prod_pvt; | ||
| 1424 | struct xen_netif_tx_response *resp; | ||
| 1425 | |||
| 1426 | resp = RING_GET_RESPONSE(&queue->tx, i); | ||
| 1427 | resp->id = txp->id; | ||
| 1428 | resp->status = status; | ||
| 1429 | |||
| 1430 | while (extra_count-- != 0) | ||
| 1431 | RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; | ||
| 1432 | |||
| 1433 | queue->tx.rsp_prod_pvt = ++i; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | static void push_tx_responses(struct xenvif_queue *queue) | ||
| 1437 | { | ||
| 1438 | int notify; | ||
| 1439 | |||
| 1440 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | ||
| 1441 | if (notify) | ||
| 1442 | notify_remote_via_irq(queue->tx_irq); | ||
| 1443 | } | ||
| 1444 | |||
| 1436 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, | 1445 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, |
| 1437 | u8 status) | 1446 | s8 status) |
| 1438 | { | 1447 | { |
| 1439 | struct pending_tx_info *pending_tx_info; | 1448 | struct pending_tx_info *pending_tx_info; |
| 1440 | pending_ring_idx_t index; | 1449 | pending_ring_idx_t index; |
| @@ -1444,8 +1453,8 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 3 unmodified lines | |||
| 1444 | 1453 | ||
| 1445 | spin_lock_irqsave(&queue->response_lock, flags); | 1454 | spin_lock_irqsave(&queue->response_lock, flags); |
| 1446 | 1455 | ||
| 1447 | make_tx_response(queue, &pending_tx_info->req, | 1456 | _make_tx_response(queue, &pending_tx_info->req, |
| 1448 | pending_tx_info->extra_count, status); | 1457 | pending_tx_info->extra_count, status); |
| 1449 | 1458 | ||
| 1450 | /* Release the pending index before pusing the Tx response so | 1459 | /* Release the pending index before pusing the Tx response so |
| 1451 | * its available before a new Tx request is pushed by the | 1460 | * its available before a new Tx request is pushed by the |
| @@ -1459,32 +1468,19 @@ static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, · 7 unmodified lines | |||
| 1459 | spin_unlock_irqrestore(&queue->response_lock, flags); | 1468 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 1460 | } | 1469 | } |
| 1461 | 1470 | ||
| 1462 | |||
| 1463 | static void make_tx_response(struct xenvif_queue *queue, | 1471 | static void make_tx_response(struct xenvif_queue *queue, |
| 1464 | struct xen_netif_tx_request *txp, | 1472 | const struct xen_netif_tx_request *txp, |
| 1465 | unsigned int extra_count, | 1473 | unsigned int extra_count, |
| 1466 | s8 st) | 1474 | s8 status) |
| 1467 | { | 1475 | { |
| 1468 | RING_IDX i = queue->tx.rsp_prod_pvt; | 1476 | unsigned long flags; |
| 1469 | struct xen_netif_tx_response *resp; | ||
| 1470 | |||
| 1471 | resp = RING_GET_RESPONSE(&queue->tx, i); | ||
| 1472 | resp->id = txp->id; | ||
| 1473 | resp->status = st; | ||
| 1474 | |||
| 1475 | while (extra_count-- != 0) | ||
| 1476 | RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; | ||
| 1477 | 1477 | ||
| 1478 | queue->tx.rsp_prod_pvt = ++i; | 1478 | spin_lock_irqsave(&queue->response_lock, flags); |
| 1479 | } | ||
| 1480 | 1479 | ||
| 1481 | static void push_tx_responses(struct xenvif_queue *queue) | 1480 | _make_tx_response(queue, txp, extra_count, status); |
| 1482 | { | 1481 | push_tx_responses(queue); |
| 1483 | int notify; | ||
| 1484 | 1482 | ||
| 1485 | RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | 1483 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 1486 | if (notify) | ||
| 1487 | notify_remote_via_irq(queue->tx_irq); | ||
| 1488 | } | 1484 | } |
| 1489 | 1485 | ||
| 1490 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) | 1486 | static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) |
| @@ -186,6 +186,8 @@ struct ip_set_type_variant { · 185 unmodified lines | |||
| 186 | /* Return true if "b" set is the same as "a" | 186 | /* Return true if "b" set is the same as "a" |
| 187 | * according to the create set parameters */ | 187 | * according to the create set parameters */ |
| 188 | bool (*same_set)(const struct ip_set *a, const struct ip_set *b); | 188 | bool (*same_set)(const struct ip_set *a, const struct ip_set *b); |
| 189 | /* Cancel ongoing garbage collectors before destroying the set*/ | ||
| 190 | void (*cancel_gc)(struct ip_set *set); | ||
| 189 | /* Region-locking is used */ | 191 | /* Region-locking is used */ |
| 190 | bool region_lock; | 192 | bool region_lock; |
| 191 | }; | 193 | }; |
| @@ -242,6 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type); · 50 unmodified lines | |||
| 242 | 244 | ||
| 243 | /* A generic IP set */ | 245 | /* A generic IP set */ |
| 244 | struct ip_set { | 246 | struct ip_set { |
| 247 | /* For call_cru in destroy */ | ||
| 248 | struct rcu_head rcu; | ||
| 245 | /* The name of the set */ | 249 | /* The name of the set */ |
| 246 | char name[IPSET_MAXNAMELEN]; | 250 | char name[IPSET_MAXNAMELEN]; |
| 247 | /* Lock protecting the set data */ | 251 | /* Lock protecting the set data */ |
| @@ -46,12 +46,6 @@ struct scm_stat { · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) | 47 | #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) |
| 48 | 48 | ||
| 49 | #define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) | ||
| 50 | #define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock) | ||
| 51 | #define unix_state_lock_nested(s) \ | ||
| 52 | spin_lock_nested(&unix_sk(s)->lock, \ | ||
| 53 | SINGLE_DEPTH_NESTING) | ||
| 54 | |||
| 55 | /* The AF_UNIX socket */ | 49 | /* The AF_UNIX socket */ |
| 56 | struct unix_sock { | 50 | struct unix_sock { |
| 57 | /* WARNING: sk has to be the first member */ | 51 | /* WARNING: sk has to be the first member */ |
| @@ -77,6 +71,20 @@ struct unix_sock { · 19 unmodified lines | |||
| 77 | #define unix_sk(ptr) container_of_const(ptr, struct unix_sock, sk) | 71 | #define unix_sk(ptr) container_of_const(ptr, struct unix_sock, sk) |
| 78 | #define unix_peer(sk) (unix_sk(sk)->peer) | 72 | #define unix_peer(sk) (unix_sk(sk)->peer) |
| 79 | 73 | ||
| 74 | #define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) | ||
| 75 | #define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock) | ||
| 76 | enum unix_socket_lock_class { | ||
| 77 | U_LOCK_NORMAL, | ||
| 78 | U_LOCK_SECOND, /* for double locking, see unix_state_double_lock(). */ | ||
| 79 | U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */ | ||
| 80 | }; | ||
| 81 | |||
| 82 | static inline void unix_state_lock_nested(struct sock *sk, | ||
| 83 | enum unix_socket_lock_class subclass) | ||
| 84 | { | ||
| 85 | spin_lock_nested(&unix_sk(sk)->lock, subclass); | ||
| 86 | } | ||
| 87 | |||
| 80 | #define peer_wait peer_wq.wait | 88 | #define peer_wait peer_wq.wait |
| 81 | 89 | ||
| 82 | long unix_inq_len(struct sock *sk); | 90 | long unix_inq_len(struct sock *sk); |
| @@ -767,7 +767,7 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); · 766 unmodified lines | |||
| 767 | * Functions provided by ip_sockglue.c | 767 | * Functions provided by ip_sockglue.c |
| 768 | */ | 768 | */ |
| 769 | 769 | ||
| 770 | void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb); | 770 | void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst); |
| 771 | void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, | 771 | void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, |
| 772 | struct sk_buff *skb, int tlen, int offset); | 772 | struct sk_buff *skb, int tlen, int offset); |
| 773 | int ip_cmsg_send(struct sock *sk, struct msghdr *msg, | 773 | int ip_cmsg_send(struct sock *sk, struct msghdr *msg, |
| @@ -1351,6 +1351,7 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, · 1350 unmodified lines | |||
| 1351 | * @type: stateful object numeric type | 1351 | * @type: stateful object numeric type |
| 1352 | * @owner: module owner | 1352 | * @owner: module owner |
| 1353 | * @maxattr: maximum netlink attribute | 1353 | * @maxattr: maximum netlink attribute |
| 1354 | * @family: address family for AF-specific object types | ||
| 1354 | * @policy: netlink attribute policy | 1355 | * @policy: netlink attribute policy |
| 1355 | */ | 1356 | */ |
| 1356 | struct nft_object_type { | 1357 | struct nft_object_type { |
| @@ -1360,6 +1361,7 @@ struct nft_object_type { · 3 unmodified lines | |||
| 1360 | struct list_head list; | 1361 | struct list_head list; |
| 1361 | u32 type; | 1362 | u32 type; |
| 1362 | unsigned int maxattr; | 1363 | unsigned int maxattr; |
| 1364 | u8 family; | ||
| 1363 | struct module *owner; | 1365 | struct module *owner; |
| 1364 | const struct nla_policy *policy; | 1366 | const struct nla_policy *policy; |
| 1365 | }; | 1367 | }; |
| @@ -2175,6 +2175,7 @@ void batadv_mcast_free(struct batadv_priv *bat_priv) · 2174 unmodified lines | |||
| 2175 | cancel_delayed_work_sync(&bat_priv->mcast.work); | 2175 | cancel_delayed_work_sync(&bat_priv->mcast.work); |
| 2176 | 2176 | ||
| 2177 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2); | 2177 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2); |
| 2178 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST_TRACKER, 1); | ||
| 2178 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2); | 2179 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2); |
| 2179 | 2180 | ||
| 2180 | /* safely calling outside of worker, as worker was canceled above */ | 2181 | /* safely calling outside of worker, as worker was canceled above */ |
| @@ -2198,6 +2199,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig) · 17 unmodified lines | |||
| 2198 | BATADV_MCAST_WANT_NO_RTR4); | 2199 | BATADV_MCAST_WANT_NO_RTR4); |
| 2199 | batadv_mcast_want_rtr6_update(bat_priv, orig, | 2200 | batadv_mcast_want_rtr6_update(bat_priv, orig, |
| 2200 | BATADV_MCAST_WANT_NO_RTR6); | 2201 | BATADV_MCAST_WANT_NO_RTR6); |
| 2202 | batadv_mcast_have_mc_ptype_update(bat_priv, orig, | ||
| 2203 | BATADV_MCAST_HAVE_MC_PTYPE_CAPA); | ||
| 2201 | 2204 | ||
| 2202 | spin_unlock_bh(&orig->mcast_handler_lock); | 2205 | spin_unlock_bh(&orig->mcast_handler_lock); |
| 2203 | } | 2206 | } |
| @@ -1762,6 +1762,10 @@ static void br_ip6_multicast_querier_expired(struct timer_list *t) · 1761 unmodified lines | |||
| 1762 | } | 1762 | } |
| 1763 | #endif | 1763 | #endif |
| 1764 | 1764 | ||
| 1765 | static void br_multicast_query_delay_expired(struct timer_list *t) | ||
| 1766 | { | ||
| 1767 | } | ||
| 1768 | |||
| 1765 | static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx, | 1769 | static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx, |
| 1766 | struct br_ip *ip, | 1770 | struct br_ip *ip, |
| 1767 | struct sk_buff *skb) | 1771 | struct sk_buff *skb) |
| @@ -3198,7 +3202,7 @@ br_multicast_update_query_timer(struct net_bridge_mcast *brmctx, · 1430 unmodified lines | |||
| 3198 | unsigned long max_delay) | 3202 | unsigned long max_delay) |
| 3199 | { | 3203 | { |
| 3200 | if (!timer_pending(&query->timer)) | 3204 | if (!timer_pending(&query->timer)) |
| 3201 | query->delay_time = jiffies + max_delay; | 3205 | mod_timer(&query->delay_timer, jiffies + max_delay); |
| 3202 | 3206 | ||
| 3203 | mod_timer(&query->timer, jiffies + brmctx->multicast_querier_interval); | 3207 | mod_timer(&query->timer, jiffies + brmctx->multicast_querier_interval); |
| 3204 | } | 3208 | } |
| @@ -4041,13 +4045,11 @@ void br_multicast_ctx_init(struct net_bridge *br, · 836 unmodified lines | |||
| 4041 | brmctx->multicast_querier_interval = 255 * HZ; | 4045 | brmctx->multicast_querier_interval = 255 * HZ; |
| 4042 | brmctx->multicast_membership_interval = 260 * HZ; | 4046 | brmctx->multicast_membership_interval = 260 * HZ; |
| 4043 | 4047 | ||
| 4044 | brmctx->ip4_other_query.delay_time = 0; | ||
| 4045 | brmctx->ip4_querier.port_ifidx = 0; | 4048 | brmctx->ip4_querier.port_ifidx = 0; |
| 4046 | seqcount_spinlock_init(&brmctx->ip4_querier.seq, &br->multicast_lock); | 4049 | seqcount_spinlock_init(&brmctx->ip4_querier.seq, &br->multicast_lock); |
| 4047 | brmctx->multicast_igmp_version = 2; | 4050 | brmctx->multicast_igmp_version = 2; |
| 4048 | #if IS_ENABLED(CONFIG_IPV6) | 4051 | #if IS_ENABLED(CONFIG_IPV6) |
| 4049 | brmctx->multicast_mld_version = 1; | 4052 | brmctx->multicast_mld_version = 1; |
| 4050 | brmctx->ip6_other_query.delay_time = 0; | ||
| 4051 | brmctx->ip6_querier.port_ifidx = 0; | 4053 | brmctx->ip6_querier.port_ifidx = 0; |
| 4052 | seqcount_spinlock_init(&brmctx->ip6_querier.seq, &br->multicast_lock); | 4054 | seqcount_spinlock_init(&brmctx->ip6_querier.seq, &br->multicast_lock); |
| 4053 | #endif | 4055 | #endif |
| @@ -4056,6 +4058,8 @@ void br_multicast_ctx_init(struct net_bridge *br, · 2 unmodified lines | |||
| 4056 | br_ip4_multicast_local_router_expired, 0); | 4058 | br_ip4_multicast_local_router_expired, 0); |
| 4057 | timer_setup(&brmctx->ip4_other_query.timer, | 4059 | timer_setup(&brmctx->ip4_other_query.timer, |
| 4058 | br_ip4_multicast_querier_expired, 0); | 4060 | br_ip4_multicast_querier_expired, 0); |
| 4061 | timer_setup(&brmctx->ip4_other_query.delay_timer, | ||
| 4062 | br_multicast_query_delay_expired, 0); | ||
| 4059 | timer_setup(&brmctx->ip4_own_query.timer, | 4063 | timer_setup(&brmctx->ip4_own_query.timer, |
| 4060 | br_ip4_multicast_query_expired, 0); | 4064 | br_ip4_multicast_query_expired, 0); |
| 4061 | #if IS_ENABLED(CONFIG_IPV6) | 4065 | #if IS_ENABLED(CONFIG_IPV6) |
| @@ -4063,6 +4067,8 @@ void br_multicast_ctx_init(struct net_bridge *br, · 1 unmodified line | |||
| 4063 | br_ip6_multicast_local_router_expired, 0); | 4067 | br_ip6_multicast_local_router_expired, 0); |
| 4064 | timer_setup(&brmctx->ip6_other_query.timer, | 4068 | timer_setup(&brmctx->ip6_other_query.timer, |
| 4065 | br_ip6_multicast_querier_expired, 0); | 4069 | br_ip6_multicast_querier_expired, 0); |
| 4070 | timer_setup(&brmctx->ip6_other_query.delay_timer, | ||
| 4071 | br_multicast_query_delay_expired, 0); | ||
| 4066 | timer_setup(&brmctx->ip6_own_query.timer, | 4072 | timer_setup(&brmctx->ip6_own_query.timer, |
| 4067 | br_ip6_multicast_query_expired, 0); | 4073 | br_ip6_multicast_query_expired, 0); |
| 4068 | #endif | 4074 | #endif |
| @@ -4197,10 +4203,12 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx) · 128 unmodified lines | |||
| 4197 | { | 4203 | { |
| 4198 | del_timer_sync(&brmctx->ip4_mc_router_timer); | 4204 | del_timer_sync(&brmctx->ip4_mc_router_timer); |
| 4199 | del_timer_sync(&brmctx->ip4_other_query.timer); | 4205 | del_timer_sync(&brmctx->ip4_other_query.timer); |
| 4206 | del_timer_sync(&brmctx->ip4_other_query.delay_timer); | ||
| 4200 | del_timer_sync(&brmctx->ip4_own_query.timer); | 4207 | del_timer_sync(&brmctx->ip4_own_query.timer); |
| 4201 | #if IS_ENABLED(CONFIG_IPV6) | 4208 | #if IS_ENABLED(CONFIG_IPV6) |
| 4202 | del_timer_sync(&brmctx->ip6_mc_router_timer); | 4209 | del_timer_sync(&brmctx->ip6_mc_router_timer); |
| 4203 | del_timer_sync(&brmctx->ip6_other_query.timer); | 4210 | del_timer_sync(&brmctx->ip6_other_query.timer); |
| 4211 | del_timer_sync(&brmctx->ip6_other_query.delay_timer); | ||
| 4204 | del_timer_sync(&brmctx->ip6_own_query.timer); | 4212 | del_timer_sync(&brmctx->ip6_own_query.timer); |
| 4205 | #endif | 4213 | #endif |
| 4206 | } | 4214 | } |
| @@ -4643,13 +4651,15 @@ int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val) · 436 unmodified lines | |||
| 4643 | max_delay = brmctx->multicast_query_response_interval; | 4651 | max_delay = brmctx->multicast_query_response_interval; |
| 4644 | 4652 | ||
| 4645 | if (!timer_pending(&brmctx->ip4_other_query.timer)) | 4653 | if (!timer_pending(&brmctx->ip4_other_query.timer)) |
| 4646 | brmctx->ip4_other_query.delay_time = jiffies + max_delay; | 4654 | mod_timer(&brmctx->ip4_other_query.delay_timer, |
| 4655 | jiffies + max_delay); | ||
| 4647 | 4656 | ||
| 4648 | br_multicast_start_querier(brmctx, &brmctx->ip4_own_query); | 4657 | br_multicast_start_querier(brmctx, &brmctx->ip4_own_query); |
| 4649 | 4658 | ||
| 4650 | #if IS_ENABLED(CONFIG_IPV6) | 4659 | #if IS_ENABLED(CONFIG_IPV6) |
| 4651 | if (!timer_pending(&brmctx->ip6_other_query.timer)) | 4660 | if (!timer_pending(&brmctx->ip6_other_query.timer)) |
| 4652 | brmctx->ip6_other_query.delay_time = jiffies + max_delay; | 4661 | mod_timer(&brmctx->ip6_other_query.delay_timer, |
| 4662 | jiffies + max_delay); | ||
| 4653 | 4663 | ||
| 4654 | br_multicast_start_querier(brmctx, &brmctx->ip6_own_query); | 4664 | br_multicast_start_querier(brmctx, &brmctx->ip6_own_query); |
| 4655 | #endif | 4665 | #endif |
| @@ -78,7 +78,7 @@ struct bridge_mcast_own_query { · 77 unmodified lines | |||
| 78 | /* other querier */ | 78 | /* other querier */ |
| 79 | struct bridge_mcast_other_query { | 79 | struct bridge_mcast_other_query { |
| 80 | struct timer_list timer; | 80 | struct timer_list timer; |
| 81 | unsigned long delay_time; | 81 | struct timer_list delay_timer; |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | /* selected querier */ | 84 | /* selected querier */ |
| @@ -1159,7 +1159,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx, · 1074 unmodified lines | |||
| 1159 | own_querier_enabled = false; | 1159 | own_querier_enabled = false; |
| 1160 | } | 1160 | } |
| 1161 | 1161 | ||
| 1162 | return time_is_before_jiffies(querier->delay_time) && | 1162 | return !timer_pending(&querier->delay_timer) && |
| 1163 | (own_querier_enabled || timer_pending(&querier->timer)); | 1163 | (own_querier_enabled || timer_pending(&querier->timer)); |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| @@ -674,7 +674,7 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port, · 673 unmodified lines | |||
| 674 | return -EOPNOTSUPP; | 674 | return -EOPNOTSUPP; |
| 675 | } | 675 | } |
| 676 | if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) { | 676 | if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) { |
| 677 | NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR], | 677 | NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FN_ATTR_STATE], |
| 678 | "Function does not support state setting"); | 678 | "Function does not support state setting"); |
| 679 | return -EOPNOTSUPP; | 679 | return -EOPNOTSUPP; |
| 680 | } | 680 | } |
| @@ -308,7 +308,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master, · 307 unmodified lines | |||
| 308 | 308 | ||
| 309 | skb = hsr_init_skb(master); | 309 | skb = hsr_init_skb(master); |
| 310 | if (!skb) { | 310 | if (!skb) { |
| 311 | WARN_ONCE(1, "HSR: Could not send supervision frame\n"); | 311 | netdev_warn_once(master->dev, "HSR: Could not send supervision frame\n"); |
| 312 | return; | 312 | return; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| @@ -355,7 +355,7 @@ static void send_prp_supervision_frame(struct hsr_port *master, · 40 unmodified lines | |||
| 355 | 355 | ||
| 356 | skb = hsr_init_skb(master); | 356 | skb = hsr_init_skb(master); |
| 357 | if (!skb) { | 357 | if (!skb) { |
| 358 | WARN_ONCE(1, "PRP: Could not send supervision frame\n"); | 358 | netdev_warn_once(master->dev, "PRP: Could not send supervision frame\n"); |
| 359 | return; | 359 | return; |
| 360 | } | 360 | } |
| 361 | 361 | ||
| @@ -1287,6 +1287,12 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, · 1286 unmodified lines | |||
| 1287 | if (unlikely(!rt)) | 1287 | if (unlikely(!rt)) |
| 1288 | return -EFAULT; | 1288 | return -EFAULT; |
| 1289 | 1289 | ||
| 1290 | cork->fragsize = ip_sk_use_pmtu(sk) ? | ||
| 1291 | dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); | ||
| 1292 | |||
| 1293 | if (!inetdev_valid_mtu(cork->fragsize)) | ||
| 1294 | return -ENETUNREACH; | ||
| 1295 | |||
| 1290 | /* | 1296 | /* |
| 1291 | * setup for corking. | 1297 | * setup for corking. |
| 1292 | */ | 1298 | */ |
| @@ -1303,12 +1309,6 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, · 10 unmodified lines | |||
| 1303 | cork->addr = ipc->addr; | 1309 | cork->addr = ipc->addr; |
| 1304 | } | 1310 | } |
| 1305 | 1311 | ||
| 1306 | cork->fragsize = ip_sk_use_pmtu(sk) ? | ||
| 1307 | dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); | ||
| 1308 | |||
| 1309 | if (!inetdev_valid_mtu(cork->fragsize)) | ||
| 1310 | return -ENETUNREACH; | ||
| 1311 | |||
| 1312 | cork->gso_size = ipc->gso_size; | 1312 | cork->gso_size = ipc->gso_size; |
| 1313 | 1313 | ||
| 1314 | cork->dst = &rt->dst; | 1314 | cork->dst = &rt->dst; |
| @@ -1363,12 +1363,13 @@ e_inval: · 1362 unmodified lines | |||
| 1363 | * ipv4_pktinfo_prepare - transfer some info from rtable to skb | 1363 | * ipv4_pktinfo_prepare - transfer some info from rtable to skb |
| 1364 | * @sk: socket | 1364 | * @sk: socket |
| 1365 | * @skb: buffer | 1365 | * @skb: buffer |
| 1366 | * @drop_dst: if true, drops skb dst | ||
| 1366 | * | 1367 | * |
| 1367 | * To support IP_CMSG_PKTINFO option, we store rt_iif and specific | 1368 | * To support IP_CMSG_PKTINFO option, we store rt_iif and specific |
| 1368 | * destination in skb->cb[] before dst drop. | 1369 | * destination in skb->cb[] before dst drop. |
| 1369 | * This way, receiver doesn't make cache line misses to read rtable. | 1370 | * This way, receiver doesn't make cache line misses to read rtable. |
| 1370 | */ | 1371 | */ |
| 1371 | void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) | 1372 | void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst) |
| 1372 | { | 1373 | { |
| 1373 | struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb); | 1374 | struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb); |
| 1374 | bool prepare = inet_test_bit(PKTINFO, sk) || | 1375 | bool prepare = inet_test_bit(PKTINFO, sk) || |
| @@ -1397,7 +1398,8 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) · 22 unmodified lines | |||
| 1397 | pktinfo->ipi_ifindex = 0; | 1398 | pktinfo->ipi_ifindex = 0; |
| 1398 | pktinfo->ipi_spec_dst.s_addr = 0; | 1399 | pktinfo->ipi_spec_dst.s_addr = 0; |
| 1399 | } | 1400 | } |
| 1400 | skb_dst_drop(skb); | 1401 | if (drop_dst) |
| 1402 | skb_dst_drop(skb); | ||
| 1401 | } | 1403 | } |
| 1402 | 1404 | ||
| 1403 | int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, | 1405 | int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, |
| @@ -1073,7 +1073,7 @@ static int ipmr_cache_report(const struct mr_table *mrt, · 1072 unmodified lines | |||
| 1073 | msg = (struct igmpmsg *)skb_network_header(skb); | 1073 | msg = (struct igmpmsg *)skb_network_header(skb); |
| 1074 | msg->im_vif = vifi; | 1074 | msg->im_vif = vifi; |
| 1075 | msg->im_vif_hi = vifi >> 8; | 1075 | msg->im_vif_hi = vifi >> 8; |
| 1076 | ipv4_pktinfo_prepare(mroute_sk, pkt); | 1076 | ipv4_pktinfo_prepare(mroute_sk, pkt, false); |
| 1077 | memcpy(skb->cb, pkt->cb, sizeof(skb->cb)); | 1077 | memcpy(skb->cb, pkt->cb, sizeof(skb->cb)); |
| 1078 | /* Add our header */ | 1078 | /* Add our header */ |
| 1079 | igmp = skb_put(skb, sizeof(struct igmphdr)); | 1079 | igmp = skb_put(skb, sizeof(struct igmphdr)); |
| @@ -292,7 +292,7 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) · 291 unmodified lines | |||
| 292 | 292 | ||
| 293 | /* Charge it to the socket. */ | 293 | /* Charge it to the socket. */ |
| 294 | 294 | ||
| 295 | ipv4_pktinfo_prepare(sk, skb); | 295 | ipv4_pktinfo_prepare(sk, skb, true); |
| 296 | if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { | 296 | if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { |
| 297 | kfree_skb_reason(skb, reason); | 297 | kfree_skb_reason(skb, reason); |
| 298 | return NET_RX_DROP; | 298 | return NET_RX_DROP; |
| @@ -1786,7 +1786,17 @@ static skb_frag_t *skb_advance_to_frag(struct sk_buff *skb, u32 offset_skb, · 1785 unmodified lines | |||
| 1786 | 1786 | ||
| 1787 | static bool can_map_frag(const skb_frag_t *frag) | 1787 | static bool can_map_frag(const skb_frag_t *frag) |
| 1788 | { | 1788 | { |
| 1789 | return skb_frag_size(frag) == PAGE_SIZE && !skb_frag_off(frag); | 1789 | struct page *page; |
| 1790 | |||
| 1791 | if (skb_frag_size(frag) != PAGE_SIZE || skb_frag_off(frag)) | ||
| 1792 | return false; | ||
| 1793 | |||
| 1794 | page = skb_frag_page(frag); | ||
| 1795 | |||
| 1796 | if (PageCompound(page) || page->mapping) | ||
| 1797 | return false; | ||
| 1798 | |||
| 1799 | return true; | ||
| 1790 | } | 1800 | } |
| 1791 | 1801 | ||
| 1792 | static int find_next_mappable_frag(const skb_frag_t *frag, | 1802 | static int find_next_mappable_frag(const skb_frag_t *frag, |
| @@ -2169,7 +2169,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) · 2168 unmodified lines | |||
| 2169 | 2169 | ||
| 2170 | udp_csum_pull_header(skb); | 2170 | udp_csum_pull_header(skb); |
| 2171 | 2171 | ||
| 2172 | ipv4_pktinfo_prepare(sk, skb); | 2172 | ipv4_pktinfo_prepare(sk, skb, true); |
| 2173 | return __udp_queue_rcv_skb(sk, skb); | 2173 | return __udp_queue_rcv_skb(sk, skb); |
| 2174 | 2174 | ||
| 2175 | csum_error: | 2175 | csum_error: |
| @@ -220,19 +220,26 @@ const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) { · 219 unmodified lines | |||
| 220 | EXPORT_SYMBOL_GPL(ipv6_stub); | 220 | EXPORT_SYMBOL_GPL(ipv6_stub); |
| 221 | 221 | ||
| 222 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ | 222 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ |
| 223 | const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; | 223 | const struct in6_addr in6addr_loopback __aligned(BITS_PER_LONG/8) |
| 224 | = IN6ADDR_LOOPBACK_INIT; | ||
| 224 | EXPORT_SYMBOL(in6addr_loopback); | 225 | EXPORT_SYMBOL(in6addr_loopback); |
| 225 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; | 226 | const struct in6_addr in6addr_any __aligned(BITS_PER_LONG/8) |
| 227 | = IN6ADDR_ANY_INIT; | ||
| 226 | EXPORT_SYMBOL(in6addr_any); | 228 | EXPORT_SYMBOL(in6addr_any); |
| 227 | const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; | 229 | const struct in6_addr in6addr_linklocal_allnodes __aligned(BITS_PER_LONG/8) |
| 230 | = IN6ADDR_LINKLOCAL_ALLNODES_INIT; | ||
| 228 | EXPORT_SYMBOL(in6addr_linklocal_allnodes); | 231 | EXPORT_SYMBOL(in6addr_linklocal_allnodes); |
| 229 | const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; | 232 | const struct in6_addr in6addr_linklocal_allrouters __aligned(BITS_PER_LONG/8) |
| 233 | = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; | ||
| 230 | EXPORT_SYMBOL(in6addr_linklocal_allrouters); | 234 | EXPORT_SYMBOL(in6addr_linklocal_allrouters); |
| 231 | const struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT; | 235 | const struct in6_addr in6addr_interfacelocal_allnodes __aligned(BITS_PER_LONG/8) |
| 236 | = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT; | ||
| 232 | EXPORT_SYMBOL(in6addr_interfacelocal_allnodes); | 237 | EXPORT_SYMBOL(in6addr_interfacelocal_allnodes); |
| 233 | const struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT; | 238 | const struct in6_addr in6addr_interfacelocal_allrouters __aligned(BITS_PER_LONG/8) |
| 239 | = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT; | ||
| 234 | EXPORT_SYMBOL(in6addr_interfacelocal_allrouters); | 240 | EXPORT_SYMBOL(in6addr_interfacelocal_allrouters); |
| 235 | const struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT; | 241 | const struct in6_addr in6addr_sitelocal_allrouters __aligned(BITS_PER_LONG/8) |
| 242 | = IN6ADDR_SITELOCAL_ALLROUTERS_INIT; | ||
| 236 | EXPORT_SYMBOL(in6addr_sitelocal_allrouters); | 243 | EXPORT_SYMBOL(in6addr_sitelocal_allrouters); |
| 237 | 244 | ||
| 238 | static void snmp6_free_dev(struct inet6_dev *idev) | 245 | static void snmp6_free_dev(struct inet6_dev *idev) |
| @@ -796,8 +796,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, · 795 unmodified lines | |||
| 796 | struct sk_buff *skb), | 796 | struct sk_buff *skb), |
| 797 | bool log_ecn_err) | 797 | bool log_ecn_err) |
| 798 | { | 798 | { |
| 799 | const struct ipv6hdr *ipv6h = ipv6_hdr(skb); | 799 | const struct ipv6hdr *ipv6h; |
| 800 | int err; | 800 | int nh, err; |
| 801 | 801 | ||
| 802 | if ((!(tpi->flags & TUNNEL_CSUM) && | 802 | if ((!(tpi->flags & TUNNEL_CSUM) && |
| 803 | (tunnel->parms.i_flags & TUNNEL_CSUM)) || | 803 | (tunnel->parms.i_flags & TUNNEL_CSUM)) || |
| @@ -829,7 +829,6 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, · 25 unmodified lines | |||
| 829 | goto drop; | 829 | goto drop; |
| 830 | } | 830 | } |
| 831 | 831 | ||
| 832 | ipv6h = ipv6_hdr(skb); | ||
| 833 | skb->protocol = eth_type_trans(skb, tunnel->dev); | 832 | skb->protocol = eth_type_trans(skb, tunnel->dev); |
| 834 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | 833 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
| 835 | } else { | 834 | } else { |
| @@ -837,7 +836,23 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, · 1 unmodified line | |||
| 837 | skb_reset_mac_header(skb); | 836 | skb_reset_mac_header(skb); |
| 838 | } | 837 | } |
| 839 | 838 | ||
| 839 | /* Save offset of outer header relative to skb->head, | ||
| 840 | * because we are going to reset the network header to the inner header | ||
| 841 | * and might change skb->head. | ||
| 842 | */ | ||
| 843 | nh = skb_network_header(skb) - skb->head; | ||
| 844 | |||
| 840 | skb_reset_network_header(skb); | 845 | skb_reset_network_header(skb); |
| 846 | |||
| 847 | if (!pskb_inet_may_pull(skb)) { | ||
| 848 | DEV_STATS_INC(tunnel->dev, rx_length_errors); | ||
| 849 | DEV_STATS_INC(tunnel->dev, rx_errors); | ||
| 850 | goto drop; | ||
| 851 | } | ||
| 852 | |||
| 853 | /* Get the outer header. */ | ||
| 854 | ipv6h = (struct ipv6hdr *)(skb->head + nh); | ||
| 855 | |||
| 841 | memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); | 856 | memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); |
| 842 | 857 | ||
| 843 | __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); | 858 | __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); |
| @@ -226,6 +226,8 @@ static int llc_ui_release(struct socket *sock) · 225 unmodified lines | |||
| 226 | } | 226 | } |
| 227 | netdev_put(llc->dev, &llc->dev_tracker); | 227 | netdev_put(llc->dev, &llc->dev_tracker); |
| 228 | sock_put(sk); | 228 | sock_put(sk); |
| 229 | sock_orphan(sk); | ||
| 230 | sock->sk = NULL; | ||
| 229 | llc_sk_free(sk); | 231 | llc_sk_free(sk); |
| 230 | out: | 232 | out: |
| 231 | return 0; | 233 | return 0; |
| @@ -2314,9 +2314,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) · 2313 unmodified lines | |||
| 2314 | if (__mptcp_check_fallback(msk)) | 2314 | if (__mptcp_check_fallback(msk)) |
| 2315 | return false; | 2315 | return false; |
| 2316 | 2316 | ||
| 2317 | if (tcp_rtx_and_write_queues_empty(sk)) | ||
| 2318 | return false; | ||
| 2319 | |||
| 2320 | /* the closing socket has some data untransmitted and/or unacked: | 2317 | /* the closing socket has some data untransmitted and/or unacked: |
| 2321 | * some data in the mptcp rtx queue has not really xmitted yet. | 2318 | * some data in the mptcp rtx queue has not really xmitted yet. |
| 2322 | * keep it simple and re-inject the whole mptcp level rtx queue | 2319 | * keep it simple and re-inject the whole mptcp level rtx queue |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | #define mtype_del IPSET_TOKEN(MTYPE, _del) | 30 | #define mtype_del IPSET_TOKEN(MTYPE, _del) |
| 31 | #define mtype_list IPSET_TOKEN(MTYPE, _list) | 31 | #define mtype_list IPSET_TOKEN(MTYPE, _list) |
| 32 | #define mtype_gc IPSET_TOKEN(MTYPE, _gc) | 32 | #define mtype_gc IPSET_TOKEN(MTYPE, _gc) |
| 33 | #define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc) | ||
| 33 | #define mtype MTYPE | 34 | #define mtype MTYPE |
| 34 | 35 | ||
| 35 | #define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id))) | 36 | #define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id))) |
| @@ -59,9 +60,6 @@ mtype_destroy(struct ip_set *set) · 23 unmodified lines | |||
| 59 | { | 60 | { |
| 60 | struct mtype *map = set->data; | 61 | struct mtype *map = set->data; |
| 61 | 62 | ||
| 62 | if (SET_WITH_TIMEOUT(set)) | ||
| 63 | del_timer_sync(&map->gc); | ||
| 64 | |||
| 65 | if (set->dsize && set->extensions & IPSET_EXT_DESTROY) | 63 | if (set->dsize && set->extensions & IPSET_EXT_DESTROY) |
| 66 | mtype_ext_cleanup(set); | 64 | mtype_ext_cleanup(set); |
| 67 | ip_set_free(map->members); | 65 | ip_set_free(map->members); |
| @@ -290,6 +288,15 @@ mtype_gc(struct timer_list *t) · 222 unmodified lines | |||
| 290 | add_timer(&map->gc); | 288 | add_timer(&map->gc); |
| 291 | } | 289 | } |
| 292 | 290 | ||
| 291 | static void | ||
| 292 | mtype_cancel_gc(struct ip_set *set) | ||
| 293 | { | ||
| 294 | struct mtype *map = set->data; | ||
| 295 | |||
| 296 | if (SET_WITH_TIMEOUT(set)) | ||
| 297 | del_timer_sync(&map->gc); | ||
| 298 | } | ||
| 299 | |||
| 293 | static const struct ip_set_type_variant mtype = { | 300 | static const struct ip_set_type_variant mtype = { |
| 294 | .kadt = mtype_kadt, | 301 | .kadt = mtype_kadt, |
| 295 | .uadt = mtype_uadt, | 302 | .uadt = mtype_uadt, |
| @@ -303,6 +310,7 @@ static const struct ip_set_type_variant mtype = { · 7 unmodified lines | |||
| 303 | .head = mtype_head, | 310 | .head = mtype_head, |
| 304 | .list = mtype_list, | 311 | .list = mtype_list, |
| 305 | .same_set = mtype_same_set, | 312 | .same_set = mtype_same_set, |
| 313 | .cancel_gc = mtype_cancel_gc, | ||
| 306 | }; | 314 | }; |
| 307 | 315 | ||
| 308 | #endif /* __IP_SET_BITMAP_IP_GEN_H */ | 316 | #endif /* __IP_SET_BITMAP_IP_GEN_H */ |
| @@ -1182,6 +1182,14 @@ ip_set_destroy_set(struct ip_set *set) · 1181 unmodified lines | |||
| 1182 | kfree(set); | 1182 | kfree(set); |
| 1183 | } | 1183 | } |
| 1184 | 1184 | ||
| 1185 | static void | ||
| 1186 | ip_set_destroy_set_rcu(struct rcu_head *head) | ||
| 1187 | { | ||
| 1188 | struct ip_set *set = container_of(head, struct ip_set, rcu); | ||
| 1189 | |||
| 1190 | ip_set_destroy_set(set); | ||
| 1191 | } | ||
| 1192 | |||
| 1185 | static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, | 1193 | static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, |
| 1186 | const struct nlattr * const attr[]) | 1194 | const struct nlattr * const attr[]) |
| 1187 | { | 1195 | { |
| @@ -1193,8 +1201,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, · 5 unmodified lines | |||
| 1193 | if (unlikely(protocol_min_failed(attr))) | 1201 | if (unlikely(protocol_min_failed(attr))) |
| 1194 | return -IPSET_ERR_PROTOCOL; | 1202 | return -IPSET_ERR_PROTOCOL; |
| 1195 | 1203 | ||
| 1196 | /* Must wait for flush to be really finished in list:set */ | ||
| 1197 | rcu_barrier(); | ||
| 1198 | 1204 | ||
| 1199 | /* Commands are serialized and references are | 1205 | /* Commands are serialized and references are |
| 1200 | * protected by the ip_set_ref_lock. | 1206 | * protected by the ip_set_ref_lock. |
| @@ -1206,8 +1212,10 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, · 5 unmodified lines | |||
| 1206 | * counter, so if it's already zero, we can proceed | 1212 | * counter, so if it's already zero, we can proceed |
| 1207 | * without holding the lock. | 1213 | * without holding the lock. |
| 1208 | */ | 1214 | */ |
| 1209 | read_lock_bh(&ip_set_ref_lock); | ||
| 1210 | if (!attr[IPSET_ATTR_SETNAME]) { | 1215 | if (!attr[IPSET_ATTR_SETNAME]) { |
| 1216 | /* Must wait for flush to be really finished in list:set */ | ||
| 1217 | rcu_barrier(); | ||
| 1218 | read_lock_bh(&ip_set_ref_lock); | ||
| 1211 | for (i = 0; i < inst->ip_set_max; i++) { | 1219 | for (i = 0; i < inst->ip_set_max; i++) { |
| 1212 | s = ip_set(inst, i); | 1220 | s = ip_set(inst, i); |
| 1213 | if (s && (s->ref || s->ref_netlink)) { | 1221 | if (s && (s->ref || s->ref_netlink)) { |
| @@ -1221,6 +1229,8 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, · 7 unmodified lines | |||
| 1221 | s = ip_set(inst, i); | 1229 | s = ip_set(inst, i); |
| 1222 | if (s) { | 1230 | if (s) { |
| 1223 | ip_set(inst, i) = NULL; | 1231 | ip_set(inst, i) = NULL; |
| 1232 | /* Must cancel garbage collectors */ | ||
| 1233 | s->variant->cancel_gc(s); | ||
| 1224 | ip_set_destroy_set(s); | 1234 | ip_set_destroy_set(s); |
| 1225 | } | 1235 | } |
| 1226 | } | 1236 | } |
| @@ -1228,6 +1238,9 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, · 1 unmodified line | |||
| 1228 | inst->is_destroyed = false; | 1238 | inst->is_destroyed = false; |
| 1229 | } else { | 1239 | } else { |
| 1230 | u32 flags = flag_exist(info->nlh); | 1240 | u32 flags = flag_exist(info->nlh); |
| 1241 | u16 features = 0; | ||
| 1242 | |||
| 1243 | read_lock_bh(&ip_set_ref_lock); | ||
| 1231 | s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]), | 1244 | s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]), |
| 1232 | &i); | 1245 | &i); |
| 1233 | if (!s) { | 1246 | if (!s) { |
| @@ -1238,10 +1251,16 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, · 4 unmodified lines | |||
| 1238 | ret = -IPSET_ERR_BUSY; | 1251 | ret = -IPSET_ERR_BUSY; |
| 1239 | goto out; | 1252 | goto out; |
| 1240 | } | 1253 | } |
| 1254 | features = s->type->features; | ||
| 1241 | ip_set(inst, i) = NULL; | 1255 | ip_set(inst, i) = NULL; |
| 1242 | read_unlock_bh(&ip_set_ref_lock); | 1256 | read_unlock_bh(&ip_set_ref_lock); |
| 1243 | 1257 | if (features & IPSET_TYPE_NAME) { | |
| 1244 | ip_set_destroy_set(s); | 1258 | /* Must wait for flush to be really finished */ |
| 1259 | rcu_barrier(); | ||
| 1260 | } | ||
| 1261 | /* Must cancel garbage collectors */ | ||
| 1262 | s->variant->cancel_gc(s); | ||
| 1263 | call_rcu(&s->rcu, ip_set_destroy_set_rcu); | ||
| 1245 | } | 1264 | } |
| 1246 | return 0; | 1265 | return 0; |
| 1247 | out: | 1266 | out: |
| @@ -1394,9 +1413,6 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info, · 146 unmodified lines | |||
| 1394 | ip_set(inst, to_id) = from; | 1413 | ip_set(inst, to_id) = from; |
| 1395 | write_unlock_bh(&ip_set_ref_lock); | 1414 | write_unlock_bh(&ip_set_ref_lock); |
| 1396 | 1415 | ||
| 1397 | /* Make sure all readers of the old set pointers are completed. */ | ||
| 1398 | synchronize_rcu(); | ||
| 1399 | |||
| 1400 | return 0; | 1416 | return 0; |
| 1401 | } | 1417 | } |
| 1402 | 1418 | ||
| @@ -2409,8 +2425,11 @@ ip_set_fini(void) · 1006 unmodified lines | |||
| 2409 | { | 2425 | { |
| 2410 | nf_unregister_sockopt(&so_set); | 2426 | nf_unregister_sockopt(&so_set); |
| 2411 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); | 2427 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); |
| 2412 | |||
| 2413 | unregister_pernet_subsys(&ip_set_net_ops); | 2428 | unregister_pernet_subsys(&ip_set_net_ops); |
| 2429 | |||
| 2430 | /* Wait for call_rcu() in destroy */ | ||
| 2431 | rcu_barrier(); | ||
| 2432 | |||
| 2414 | pr_debug("these are the famous last words\n"); | 2433 | pr_debug("these are the famous last words\n"); |
| 2415 | } | 2434 | } |
| 2416 | 2435 | ||
| @@ -222,6 +222,7 @@ static const union nf_inet_addr zeromask = {}; · 221 unmodified lines | |||
| 222 | #undef mtype_gc_do | 222 | #undef mtype_gc_do |
| 223 | #undef mtype_gc | 223 | #undef mtype_gc |
| 224 | #undef mtype_gc_init | 224 | #undef mtype_gc_init |
| 225 | #undef mtype_cancel_gc | ||
| 225 | #undef mtype_variant | 226 | #undef mtype_variant |
| 226 | #undef mtype_data_match | 227 | #undef mtype_data_match |
| 227 | 228 | ||
| @@ -266,6 +267,7 @@ static const union nf_inet_addr zeromask = {}; · 38 unmodified lines | |||
| 266 | #define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do) | 267 | #define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do) |
| 267 | #define mtype_gc IPSET_TOKEN(MTYPE, _gc) | 268 | #define mtype_gc IPSET_TOKEN(MTYPE, _gc) |
| 268 | #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) | 269 | #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) |
| 270 | #define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc) | ||
| 269 | #define mtype_variant IPSET_TOKEN(MTYPE, _variant) | 271 | #define mtype_variant IPSET_TOKEN(MTYPE, _variant) |
| 270 | #define mtype_data_match IPSET_TOKEN(MTYPE, _data_match) | 272 | #define mtype_data_match IPSET_TOKEN(MTYPE, _data_match) |
| 271 | 273 | ||
| @@ -450,9 +452,6 @@ mtype_destroy(struct ip_set *set) · 178 unmodified lines | |||
| 450 | struct htype *h = set->data; | 452 | struct htype *h = set->data; |
| 451 | struct list_head *l, *lt; | 453 | struct list_head *l, *lt; |
| 452 | 454 | ||
| 453 | if (SET_WITH_TIMEOUT(set)) | ||
| 454 | cancel_delayed_work_sync(&h->gc.dwork); | ||
| 455 | |||
| 456 | mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true); | 455 | mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true); |
| 457 | list_for_each_safe(l, lt, &h->ad) { | 456 | list_for_each_safe(l, lt, &h->ad) { |
| 458 | list_del(l); | 457 | list_del(l); |
| @@ -599,6 +598,15 @@ mtype_gc_init(struct htable_gc *gc) · 140 unmodified lines | |||
| 599 | queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ); | 598 | queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ); |
| 600 | } | 599 | } |
| 601 | 600 | ||
| 601 | static void | ||
| 602 | mtype_cancel_gc(struct ip_set *set) | ||
| 603 | { | ||
| 604 | struct htype *h = set->data; | ||
| 605 | |||
| 606 | if (SET_WITH_TIMEOUT(set)) | ||
| 607 | cancel_delayed_work_sync(&h->gc.dwork); | ||
| 608 | } | ||
| 609 | |||
| 602 | static int | 610 | static int |
| 603 | mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, | 611 | mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, |
| 604 | struct ip_set_ext *mext, u32 flags); | 612 | struct ip_set_ext *mext, u32 flags); |
| @@ -1441,6 +1449,7 @@ static const struct ip_set_type_variant mtype_variant = { · 836 unmodified lines | |||
| 1441 | .uref = mtype_uref, | 1449 | .uref = mtype_uref, |
| 1442 | .resize = mtype_resize, | 1450 | .resize = mtype_resize, |
| 1443 | .same_set = mtype_same_set, | 1451 | .same_set = mtype_same_set, |
| 1452 | .cancel_gc = mtype_cancel_gc, | ||
| 1444 | .region_lock = true, | 1453 | .region_lock = true, |
| 1445 | }; | 1454 | }; |
| 1446 | 1455 | ||
| @@ -426,9 +426,6 @@ list_set_destroy(struct ip_set *set) · 425 unmodified lines | |||
| 426 | struct list_set *map = set->data; | 426 | struct list_set *map = set->data; |
| 427 | struct set_elem *e, *n; | 427 | struct set_elem *e, *n; |
| 428 | 428 | ||
| 429 | if (SET_WITH_TIMEOUT(set)) | ||
| 430 | timer_shutdown_sync(&map->gc); | ||
| 431 | |||
| 432 | list_for_each_entry_safe(e, n, &map->members, list) { | 429 | list_for_each_entry_safe(e, n, &map->members, list) { |
| 433 | list_del(&e->list); | 430 | list_del(&e->list); |
| 434 | ip_set_put_byindex(map->net, e->id); | 431 | ip_set_put_byindex(map->net, e->id); |
| @@ -545,6 +542,15 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b) · 110 unmodified lines | |||
| 545 | a->extensions == b->extensions; | 542 | a->extensions == b->extensions; |
| 546 | } | 543 | } |
| 547 | 544 | ||
| 545 | static void | ||
| 546 | list_set_cancel_gc(struct ip_set *set) | ||
| 547 | { | ||
| 548 | struct list_set *map = set->data; | ||
| 549 | |||
| 550 | if (SET_WITH_TIMEOUT(set)) | ||
| 551 | timer_shutdown_sync(&map->gc); | ||
| 552 | } | ||
| 553 | |||
| 548 | static const struct ip_set_type_variant set_variant = { | 554 | static const struct ip_set_type_variant set_variant = { |
| 549 | .kadt = list_set_kadt, | 555 | .kadt = list_set_kadt, |
| 550 | .uadt = list_set_uadt, | 556 | .uadt = list_set_uadt, |
| @@ -558,6 +564,7 @@ static const struct ip_set_type_variant set_variant = { · 7 unmodified lines | |||
| 558 | .head = list_set_head, | 564 | .head = list_set_head, |
| 559 | .list = list_set_list, | 565 | .list = list_set_list, |
| 560 | .same_set = list_set_same_set, | 566 | .same_set = list_set_same_set, |
| 567 | .cancel_gc = list_set_cancel_gc, | ||
| 561 | }; | 568 | }; |
| 562 | 569 | ||
| 563 | static void | 570 | static void |
| @@ -283,7 +283,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb, · 282 unmodified lines | |||
| 283 | pr_debug("Setting vtag %x for secondary conntrack\n", | 283 | pr_debug("Setting vtag %x for secondary conntrack\n", |
| 284 | sh->vtag); | 284 | sh->vtag); |
| 285 | ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag; | 285 | ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag; |
| 286 | } else { | 286 | } else if (sch->type == SCTP_CID_SHUTDOWN_ACK) { |
| 287 | /* If it is a shutdown ack OOTB packet, we expect a return | 287 | /* If it is a shutdown ack OOTB packet, we expect a return |
| 288 | shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ | 288 | shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ |
| 289 | pr_debug("Setting vtag %x for new conn OOTB\n", | 289 | pr_debug("Setting vtag %x for new conn OOTB\n", |
| @@ -457,7 +457,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender, · 456 unmodified lines | |||
| 457 | const struct sk_buff *skb, | 457 | const struct sk_buff *skb, |
| 458 | unsigned int dataoff, | 458 | unsigned int dataoff, |
| 459 | const struct tcphdr *tcph, | 459 | const struct tcphdr *tcph, |
| 460 | u32 end, u32 win) | 460 | u32 end, u32 win, |
| 461 | enum ip_conntrack_dir dir) | ||
| 461 | { | 462 | { |
| 462 | /* SYN-ACK in reply to a SYN | 463 | /* SYN-ACK in reply to a SYN |
| 463 | * or SYN from reply direction in simultaneous open. | 464 | * or SYN from reply direction in simultaneous open. |
| @@ -471,7 +472,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender, · 7 unmodified lines | |||
| 471 | * Both sides must send the Window Scale option | 472 | * Both sides must send the Window Scale option |
| 472 | * to enable window scaling in either direction. | 473 | * to enable window scaling in either direction. |
| 473 | */ | 474 | */ |
| 474 | if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && | 475 | if (dir == IP_CT_DIR_REPLY && |
| 476 | !(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE && | ||
| 475 | receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) { | 477 | receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) { |
| 476 | sender->td_scale = 0; | 478 | sender->td_scale = 0; |
| 477 | receiver->td_scale = 0; | 479 | receiver->td_scale = 0; |
| @@ -542,7 +544,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, · 64 unmodified lines | |||
| 542 | if (tcph->syn) { | 544 | if (tcph->syn) { |
| 543 | tcp_init_sender(sender, receiver, | 545 | tcp_init_sender(sender, receiver, |
| 544 | skb, dataoff, tcph, | 546 | skb, dataoff, tcph, |
| 545 | end, win); | 547 | end, win, dir); |
| 546 | if (!tcph->ack) | 548 | if (!tcph->ack) |
| 547 | /* Simultaneous open */ | 549 | /* Simultaneous open */ |
| 548 | return NFCT_TCP_ACCEPT; | 550 | return NFCT_TCP_ACCEPT; |
| @@ -585,7 +587,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir, · 36 unmodified lines | |||
| 585 | */ | 587 | */ |
| 586 | tcp_init_sender(sender, receiver, | 588 | tcp_init_sender(sender, receiver, |
| 587 | skb, dataoff, tcph, | 589 | skb, dataoff, tcph, |
| 588 | end, win); | 590 | end, win, dir); |
| 589 | 591 | ||
| 590 | if (dir == IP_CT_DIR_REPLY && !tcph->ack) | 592 | if (dir == IP_CT_DIR_REPLY && !tcph->ack) |
| 591 | return NFCT_TCP_ACCEPT; | 593 | return NFCT_TCP_ACCEPT; |
| @@ -193,11 +193,12 @@ void nf_logger_put(int pf, enum nf_log_type type) · 192 unmodified lines | |||
| 193 | return; | 193 | return; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | BUG_ON(loggers[pf][type] == NULL); | ||
| 197 | |||
| 198 | rcu_read_lock(); | 196 | rcu_read_lock(); |
| 199 | logger = rcu_dereference(loggers[pf][type]); | 197 | logger = rcu_dereference(loggers[pf][type]); |
| 200 | module_put(logger->me); | 198 | if (!logger) |
| 199 | WARN_ON_ONCE(1); | ||
| 200 | else | ||
| 201 | module_put(logger->me); | ||
| 201 | rcu_read_unlock(); | 202 | rcu_read_unlock(); |
| 202 | } | 203 | } |
| 203 | EXPORT_SYMBOL_GPL(nf_logger_put); | 204 | EXPORT_SYMBOL_GPL(nf_logger_put); |
| @@ -7551,11 +7551,15 @@ nla_put_failure: · 7550 unmodified lines | |||
| 7551 | return -1; | 7551 | return -1; |
| 7552 | } | 7552 | } |
| 7553 | 7553 | ||
| 7554 | static const struct nft_object_type *__nft_obj_type_get(u32 objtype) | 7554 | static const struct nft_object_type *__nft_obj_type_get(u32 objtype, u8 family) |
| 7555 | { | 7555 | { |
| 7556 | const struct nft_object_type *type; | 7556 | const struct nft_object_type *type; |
| 7557 | 7557 | ||
| 7558 | list_for_each_entry(type, &nf_tables_objects, list) { | 7558 | list_for_each_entry(type, &nf_tables_objects, list) { |
| 7559 | if (type->family != NFPROTO_UNSPEC && | ||
| 7560 | type->family != family) | ||
| 7561 | continue; | ||
| 7562 | |||
| 7559 | if (objtype == type->type) | 7563 | if (objtype == type->type) |
| 7560 | return type; | 7564 | return type; |
| 7561 | } | 7565 | } |
| @@ -7563,11 +7567,11 @@ static const struct nft_object_type *__nft_obj_type_get(u32 objtype) · 1 unmodified line | |||
| 7563 | } | 7567 | } |
| 7564 | 7568 | ||
| 7565 | static const struct nft_object_type * | 7569 | static const struct nft_object_type * |
| 7566 | nft_obj_type_get(struct net *net, u32 objtype) | 7570 | nft_obj_type_get(struct net *net, u32 objtype, u8 family) |
| 7567 | { | 7571 | { |
| 7568 | const struct nft_object_type *type; | 7572 | const struct nft_object_type *type; |
| 7569 | 7573 | ||
| 7570 | type = __nft_obj_type_get(objtype); | 7574 | type = __nft_obj_type_get(objtype, family); |
| 7571 | if (type != NULL && try_module_get(type->owner)) | 7575 | if (type != NULL && try_module_get(type->owner)) |
| 7572 | return type; | 7576 | return type; |
| 7573 | 7577 | ||
| @@ -7660,7 +7664,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, · 86 unmodified lines | |||
| 7660 | if (info->nlh->nlmsg_flags & NLM_F_REPLACE) | 7664 | if (info->nlh->nlmsg_flags & NLM_F_REPLACE) |
| 7661 | return -EOPNOTSUPP; | 7665 | return -EOPNOTSUPP; |
| 7662 | 7666 | ||
| 7663 | type = __nft_obj_type_get(objtype); | 7667 | type = __nft_obj_type_get(objtype, family); |
| 7664 | if (WARN_ON_ONCE(!type)) | 7668 | if (WARN_ON_ONCE(!type)) |
| 7665 | return -ENOENT; | 7669 | return -ENOENT; |
| 7666 | 7670 | ||
| @@ -7674,7 +7678,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, · 7 unmodified lines | |||
| 7674 | if (!nft_use_inc(&table->use)) | 7678 | if (!nft_use_inc(&table->use)) |
| 7675 | return -EMFILE; | 7679 | return -EMFILE; |
| 7676 | 7680 | ||
| 7677 | type = nft_obj_type_get(net, objtype); | 7681 | type = nft_obj_type_get(net, objtype, family); |
| 7678 | if (IS_ERR(type)) { | 7682 | if (IS_ERR(type)) { |
| 7679 | err = PTR_ERR(type); | 7683 | err = PTR_ERR(type); |
| 7680 | goto err_type; | 7684 | goto err_type; |
| @@ -1250,7 +1250,31 @@ static int nft_ct_expect_obj_init(const struct nft_ctx *ctx, · 1249 unmodified lines | |||
| 1250 | if (tb[NFTA_CT_EXPECT_L3PROTO]) | 1250 | if (tb[NFTA_CT_EXPECT_L3PROTO]) |
| 1251 | priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO])); | 1251 | priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO])); |
| 1252 | 1252 | ||
| 1253 | switch (priv->l3num) { | ||
| 1254 | case NFPROTO_IPV4: | ||
| 1255 | case NFPROTO_IPV6: | ||
| 1256 | if (priv->l3num != ctx->family) | ||
| 1257 | return -EINVAL; | ||
| 1258 | |||
| 1259 | fallthrough; | ||
| 1260 | case NFPROTO_INET: | ||
| 1261 | break; | ||
| 1262 | default: | ||
| 1263 | return -EOPNOTSUPP; | ||
| 1264 | } | ||
| 1265 | |||
| 1253 | priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]); | 1266 | priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]); |
| 1267 | switch (priv->l4proto) { | ||
| 1268 | case IPPROTO_TCP: | ||
| 1269 | case IPPROTO_UDP: | ||
| 1270 | case IPPROTO_UDPLITE: | ||
| 1271 | case IPPROTO_DCCP: | ||
| 1272 | case IPPROTO_SCTP: | ||
| 1273 | break; | ||
| 1274 | default: | ||
| 1275 | return -EOPNOTSUPP; | ||
| 1276 | } | ||
| 1277 | |||
| 1254 | priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]); | 1278 | priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]); |
| 1255 | priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]); | 1279 | priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]); |
| 1256 | priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]); | 1280 | priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]); |
| @@ -713,6 +713,7 @@ static const struct nft_object_ops nft_tunnel_obj_ops = { · 712 unmodified lines | |||
| 713 | 713 | ||
| 714 | static struct nft_object_type nft_tunnel_obj_type __read_mostly = { | 714 | static struct nft_object_type nft_tunnel_obj_type __read_mostly = { |
| 715 | .type = NFT_OBJECT_TUNNEL, | 715 | .type = NFT_OBJECT_TUNNEL, |
| 716 | .family = NFPROTO_NETDEV, | ||
| 716 | .ops = &nft_tunnel_obj_ops, | 717 | .ops = &nft_tunnel_obj_ops, |
| 717 | .maxattr = NFTA_TUNNEL_KEY_MAX, | 718 | .maxattr = NFTA_TUNNEL_KEY_MAX, |
| 718 | .policy = nft_tunnel_key_policy, | 719 | .policy = nft_tunnel_key_policy, |
| @@ -1208,6 +1208,10 @@ void nci_free_device(struct nci_dev *ndev) · 1207 unmodified lines | |||
| 1208 | { | 1208 | { |
| 1209 | nfc_free_device(ndev->nfc_dev); | 1209 | nfc_free_device(ndev->nfc_dev); |
| 1210 | nci_hci_deallocate(ndev); | 1210 | nci_hci_deallocate(ndev); |
| 1211 | |||
| 1212 | /* drop partial rx data packet if present */ | ||
| 1213 | if (ndev->rx_data_reassembly) | ||
| 1214 | kfree_skb(ndev->rx_data_reassembly); | ||
| 1211 | kfree(ndev); | 1215 | kfree(ndev); |
| 1212 | } | 1216 | } |
| 1213 | EXPORT_SYMBOL(nci_free_device); | 1217 | EXPORT_SYMBOL(nci_free_device); |
| @@ -1877,9 +1877,15 @@ static bool smcd_lgr_match(struct smc_link_group *lgr, · 1876 unmodified lines | |||
| 1877 | struct smcd_dev *smcismdev, | 1877 | struct smcd_dev *smcismdev, |
| 1878 | struct smcd_gid *peer_gid) | 1878 | struct smcd_gid *peer_gid) |
| 1879 | { | 1879 | { |
| 1880 | return lgr->peer_gid.gid == peer_gid->gid && lgr->smcd == smcismdev && | 1880 | if (lgr->peer_gid.gid != peer_gid->gid || |
| 1881 | smc_ism_is_virtual(smcismdev) ? | 1881 | lgr->smcd != smcismdev) |
| 1882 | (lgr->peer_gid.gid_ext == peer_gid->gid_ext) : 1; | 1882 | return false; |
| 1883 | |||
| 1884 | if (smc_ism_is_virtual(smcismdev) && | ||
| 1885 | lgr->peer_gid.gid_ext != peer_gid->gid_ext) | ||
| 1886 | return false; | ||
| 1887 | |||
| 1888 | return true; | ||
| 1883 | } | 1889 | } |
| 1884 | 1890 | ||
| 1885 | /* create a new SMC connection (and a new link group if necessary) */ | 1891 | /* create a new SMC connection (and a new link group if necessary) */ |
| @@ -1344,13 +1344,11 @@ static void unix_state_double_lock(struct sock *sk1, struct sock *sk2) · 1343 unmodified lines | |||
| 1344 | unix_state_lock(sk1); | 1344 | unix_state_lock(sk1); |
| 1345 | return; | 1345 | return; |
| 1346 | } | 1346 | } |
| 1347 | if (sk1 < sk2) { | 1347 | if (sk1 > sk2) |
| 1348 | unix_state_lock(sk1); | 1348 | swap(sk1, sk2); |
| 1349 | unix_state_lock_nested(sk2); | 1349 | |
| 1350 | } else { | 1350 | unix_state_lock(sk1); |
| 1351 | unix_state_lock(sk2); | 1351 | unix_state_lock_nested(sk2, U_LOCK_SECOND); |
| 1352 | unix_state_lock_nested(sk1); | ||
| 1353 | } | ||
| 1354 | } | 1352 | } |
| 1355 | 1353 | ||
| 1356 | static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) | 1354 | static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) |
| @@ -1591,7 +1589,7 @@ restart: · 234 unmodified lines | |||
| 1591 | goto out_unlock; | 1589 | goto out_unlock; |
| 1592 | } | 1590 | } |
| 1593 | 1591 | ||
| 1594 | unix_state_lock_nested(sk); | 1592 | unix_state_lock_nested(sk, U_LOCK_SECOND); |
| 1595 | 1593 | ||
| 1596 | if (sk->sk_state != st) { | 1594 | if (sk->sk_state != st) { |
| 1597 | unix_state_unlock(sk); | 1595 | unix_state_unlock(sk); |
| @@ -84,7 +84,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) · 83 unmodified lines | |||
| 84 | * queue lock. With the other's queue locked it's | 84 | * queue lock. With the other's queue locked it's |
| 85 | * OK to lock the state. | 85 | * OK to lock the state. |
| 86 | */ | 86 | */ |
| 87 | unix_state_lock_nested(req); | 87 | unix_state_lock_nested(req, U_LOCK_DIAG); |
| 88 | peer = unix_sk(req)->peer; | 88 | peer = unix_sk(req)->peer; |
| 89 | buf[i++] = (peer ? sock_i_ino(peer) : 0); | 89 | buf[i++] = (peer ? sock_i_ino(peer) : 0); |
| 90 | unix_state_unlock(req); | 90 | unix_state_unlock(req); |
| @@ -48,6 +48,17 @@ test_LAG_cleanup() · 47 unmodified lines | |||
| 48 | ip link add mv0 link "$name" up address "$ucaddr" type macvlan | 48 | ip link add mv0 link "$name" up address "$ucaddr" type macvlan |
| 49 | # Used to test dev->mc handling | 49 | # Used to test dev->mc handling |
| 50 | ip address add "$addr6" dev "$name" | 50 | ip address add "$addr6" dev "$name" |
| 51 | |||
| 52 | # Check that addresses were added as expected | ||
| 53 | (grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy1 || | ||
| 54 | grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy2) >/dev/null | ||
| 55 | check_err $? "macvlan unicast address not found on a slave" | ||
| 56 | |||
| 57 | # mcaddr is added asynchronously by addrconf_dad_work(), use busywait | ||
| 58 | (busywait 10000 grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy1 || | ||
| 59 | grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy2) >/dev/null | ||
| 60 | check_err $? "IPv6 solicited-node multicast mac address not found on a slave" | ||
| 61 | |||
| 51 | ip link set dev "$name" down | 62 | ip link set dev "$name" down |
| 52 | ip link del "$name" | 63 | ip link del "$name" |
| 53 | 64 | ||
| @@ -1,3 +1,5 @@ | |||
| 1 | CONFIG_DUMMY=y | ||
| 2 | CONFIG_IPV6=y | ||
| 3 | CONFIG_MACVLAN=y | ||
| 1 | CONFIG_NET_TEAM=y | 4 | CONFIG_NET_TEAM=y |
| 2 | CONFIG_NET_TEAM_MODE_LOADBALANCE=y | 5 | CONFIG_NET_TEAM_MODE_LOADBALANCE=y |
| 3 | CONFIG_MACVLAN=y | ||
| @@ -53,8 +53,7 @@ TEST_PROGS += bind_bhash.sh · 52 unmodified lines | |||
| 53 | TEST_PROGS += ip_local_port_range.sh | 53 | TEST_PROGS += ip_local_port_range.sh |
| 54 | TEST_PROGS += rps_default_mask.sh | 54 | TEST_PROGS += rps_default_mask.sh |
| 55 | TEST_PROGS += big_tcp.sh | 55 | TEST_PROGS += big_tcp.sh |
| 56 | TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh | 56 | TEST_PROGS_EXTENDED := toeplitz_client.sh toeplitz.sh |
| 57 | TEST_PROGS_EXTENDED += toeplitz_client.sh toeplitz.sh lib.sh | ||
| 58 | TEST_GEN_FILES = socket nettest | 57 | TEST_GEN_FILES = socket nettest |
| 59 | TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any | 58 | TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any |
| 60 | TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite | 59 | TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite |
| @@ -84,6 +83,7 @@ TEST_PROGS += sctp_vrf.sh · 23 unmodified lines | |||
| 84 | TEST_GEN_FILES += sctp_hello | 83 | TEST_GEN_FILES += sctp_hello |
| 85 | TEST_GEN_FILES += csum | 84 | TEST_GEN_FILES += csum |
| 86 | TEST_GEN_FILES += nat6to4.o | 85 | TEST_GEN_FILES += nat6to4.o |
| 86 | TEST_GEN_FILES += xdp_dummy.o | ||
| 87 | TEST_GEN_FILES += ip_local_port_range | 87 | TEST_GEN_FILES += ip_local_port_range |
| 88 | TEST_GEN_FILES += bind_wildcard | 88 | TEST_GEN_FILES += bind_wildcard |
| 89 | TEST_PROGS += test_vxlan_mdb.sh | 89 | TEST_PROGS += test_vxlan_mdb.sh |
| @@ -95,6 +95,7 @@ TEST_PROGS += fq_band_pktlimit.sh · 5 unmodified lines | |||
| 95 | TEST_PROGS += vlan_hw_filter.sh | 95 | TEST_PROGS += vlan_hw_filter.sh |
| 96 | 96 | ||
| 97 | TEST_FILES := settings | 97 | TEST_FILES := settings |
| 98 | TEST_FILES += in_netns.sh lib.sh net_helper.sh setup_loopback.sh setup_veth.sh | ||
| 98 | 99 | ||
| 99 | include ../lib.mk | 100 | include ../lib.mk |
| 100 | 101 | ||
| @@ -104,7 +105,7 @@ $(OUTPUT)/tcp_inq: LDLIBS += -lpthread · 3 unmodified lines | |||
| 104 | $(OUTPUT)/bind_bhash: LDLIBS += -lpthread | 105 | $(OUTPUT)/bind_bhash: LDLIBS += -lpthread |
| 105 | $(OUTPUT)/io_uring_zerocopy_tx: CFLAGS += -I../../../include/ | 106 | $(OUTPUT)/io_uring_zerocopy_tx: CFLAGS += -I../../../include/ |
| 106 | 107 | ||
| 107 | # Rules to generate bpf obj nat6to4.o | 108 | # Rules to generate bpf objs |
| 108 | CLANG ?= clang | 109 | CLANG ?= clang |
| 109 | SCRATCH_DIR := $(OUTPUT)/tools | 110 | SCRATCH_DIR := $(OUTPUT)/tools |
| 110 | BUILD_DIR := $(SCRATCH_DIR)/build | 111 | BUILD_DIR := $(SCRATCH_DIR)/build |
| @@ -139,7 +140,7 @@ endif · 28 unmodified lines | |||
| 139 | 140 | ||
| 140 | CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH)) | 141 | CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH)) |
| 141 | 142 | ||
| 142 | $(OUTPUT)/nat6to4.o: nat6to4.c $(BPFOBJ) | $(MAKE_DIRS) | 143 | $(OUTPUT)/nat6to4.o $(OUTPUT)/xdp_dummy.o: $(OUTPUT)/%.o : %.c $(BPFOBJ) | $(MAKE_DIRS) |
| 143 | $(CLANG) -O2 --target=bpf -c $< $(CCINCLUDE) $(CLANG_SYS_INCLUDES) -o $@ | 144 | $(CLANG) -O2 --target=bpf -c $< $(CCINCLUDE) $(CLANG_SYS_INCLUDES) -o $@ |
| 144 | 145 | ||
| 145 | $(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ | 146 | $(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ |
| @@ -19,8 +19,11 @@ CONFIG_BRIDGE_VLAN_FILTERING=y · 18 unmodified lines | |||
| 19 | CONFIG_BRIDGE=y | 19 | CONFIG_BRIDGE=y |
| 20 | CONFIG_CRYPTO_CHACHA20POLY1305=m | 20 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| 21 | CONFIG_VLAN_8021Q=y | 21 | CONFIG_VLAN_8021Q=y |
| 22 | CONFIG_GENEVE=m | ||
| 22 | CONFIG_IFB=y | 23 | CONFIG_IFB=y |
| 23 | CONFIG_INET_DIAG=y | 24 | CONFIG_INET_DIAG=y |
| 25 | CONFIG_INET_ESP=y | ||
| 26 | CONFIG_INET_ESP_OFFLOAD=y | ||
| 24 | CONFIG_IP_GRE=m | 27 | CONFIG_IP_GRE=m |
| 25 | CONFIG_NETFILTER=y | 28 | CONFIG_NETFILTER=y |
| 26 | CONFIG_NETFILTER_ADVANCED=y | 29 | CONFIG_NETFILTER_ADVANCED=y |
| @@ -29,7 +32,10 @@ CONFIG_NF_NAT=m · 2 unmodified lines | |||
| 29 | CONFIG_IP6_NF_IPTABLES=m | 32 | CONFIG_IP6_NF_IPTABLES=m |
| 30 | CONFIG_IP_NF_IPTABLES=m | 33 | CONFIG_IP_NF_IPTABLES=m |
| 31 | CONFIG_IP6_NF_NAT=m | 34 | CONFIG_IP6_NF_NAT=m |
| 35 | CONFIG_IP6_NF_RAW=m | ||
| 32 | CONFIG_IP_NF_NAT=m | 36 | CONFIG_IP_NF_NAT=m |
| 37 | CONFIG_IP_NF_RAW=m | ||
| 38 | CONFIG_IP_NF_TARGET_TTL=m | ||
| 33 | CONFIG_IPV6_GRE=m | 39 | CONFIG_IPV6_GRE=m |
| 34 | CONFIG_IPV6_SEG6_LWTUNNEL=y | 40 | CONFIG_IPV6_SEG6_LWTUNNEL=y |
| 35 | CONFIG_L2TP_ETH=m | 41 | CONFIG_L2TP_ETH=m |
| @@ -45,8 +51,14 @@ CONFIG_NF_TABLES=m · 9 unmodified lines | |||
| 45 | CONFIG_NF_TABLES_IPV6=y | 51 | CONFIG_NF_TABLES_IPV6=y |
| 46 | CONFIG_NF_TABLES_IPV4=y | 52 | CONFIG_NF_TABLES_IPV4=y |
| 47 | CONFIG_NFT_NAT=m | 53 | CONFIG_NFT_NAT=m |
| 54 | CONFIG_NETFILTER_XT_MATCH_LENGTH=m | ||
| 55 | CONFIG_NET_ACT_CSUM=m | ||
| 56 | CONFIG_NET_ACT_CT=m | ||
| 48 | CONFIG_NET_ACT_GACT=m | 57 | CONFIG_NET_ACT_GACT=m |
| 58 | CONFIG_NET_ACT_PEDIT=m | ||
| 49 | CONFIG_NET_CLS_BASIC=m | 59 | CONFIG_NET_CLS_BASIC=m |
| 60 | CONFIG_NET_CLS_BPF=m | ||
| 61 | CONFIG_NET_CLS_MATCHALL=m | ||
| 50 | CONFIG_NET_CLS_U32=m | 62 | CONFIG_NET_CLS_U32=m |
| 51 | CONFIG_NET_IPGRE_DEMUX=m | 63 | CONFIG_NET_IPGRE_DEMUX=m |
| 52 | CONFIG_NET_IPGRE=m | 64 | CONFIG_NET_IPGRE=m |
| @@ -55,6 +67,9 @@ CONFIG_NET_SCH_HTB=m · 2 unmodified lines | |||
| 55 | CONFIG_NET_SCH_FQ=m | 67 | CONFIG_NET_SCH_FQ=m |
| 56 | CONFIG_NET_SCH_ETF=m | 68 | CONFIG_NET_SCH_ETF=m |
| 57 | CONFIG_NET_SCH_NETEM=y | 69 | CONFIG_NET_SCH_NETEM=y |
| 70 | CONFIG_NET_SCH_PRIO=m | ||
| 71 | CONFIG_NFT_COMPAT=m | ||
| 72 | CONFIG_NF_FLOW_TABLE=m | ||
| 58 | CONFIG_PSAMPLE=m | 73 | CONFIG_PSAMPLE=m |
| 59 | CONFIG_TCP_MD5SIG=y | 74 | CONFIG_TCP_MD5SIG=y |
| 60 | CONFIG_TEST_BLACKHOLE_DEV=m | 75 | CONFIG_TEST_BLACKHOLE_DEV=m |
| @@ -80,3 +95,4 @@ CONFIG_IP_SCTP=m · 19 unmodified lines | |||
| 80 | CONFIG_NETFILTER_XT_MATCH_POLICY=m | 95 | CONFIG_NETFILTER_XT_MATCH_POLICY=m |
| 81 | CONFIG_CRYPTO_ARIA=y | 96 | CONFIG_CRYPTO_ARIA=y |
| 82 | CONFIG_XFRM_INTERFACE=m | 97 | CONFIG_XFRM_INTERFACE=m |
| 98 | CONFIG_XFRM_USER=m | ||
| @@ -112,7 +112,7 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \ · 111 unmodified lines | |||
| 112 | vxlan_symmetric_ipv6.sh \ | 112 | vxlan_symmetric_ipv6.sh \ |
| 113 | vxlan_symmetric.sh | 113 | vxlan_symmetric.sh |
| 114 | 114 | ||
| 115 | TEST_PROGS_EXTENDED := devlink_lib.sh \ | 115 | TEST_FILES := devlink_lib.sh \ |
| 116 | ethtool_lib.sh \ | 116 | ethtool_lib.sh \ |
| 117 | fib_offload_lib.sh \ | 117 | fib_offload_lib.sh \ |
| 118 | forwarding.config.sample \ | 118 | forwarding.config.sample \ |
| @@ -4,6 +4,9 @@ · 3 unmodified lines | |||
| 4 | ############################################################################## | 4 | ############################################################################## |
| 5 | # Defines | 5 | # Defines |
| 6 | 6 | ||
| 7 | WAIT_TIMEOUT=${WAIT_TIMEOUT:=20} | ||
| 8 | BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms | ||
| 9 | |||
| 7 | # Kselftest framework requirement - SKIP code is 4. | 10 | # Kselftest framework requirement - SKIP code is 4. |
| 8 | ksft_skip=4 | 11 | ksft_skip=4 |
| 9 | # namespace list created by setup_ns | 12 | # namespace list created by setup_ns |
| @@ -48,7 +51,7 @@ cleanup_ns() · 38 unmodified lines | |||
| 48 | 51 | ||
| 49 | for ns in "$@"; do | 52 | for ns in "$@"; do |
| 50 | ip netns delete "${ns}" &> /dev/null | 53 | ip netns delete "${ns}" &> /dev/null |
| 51 | if ! busywait 2 ip netns list \| grep -vq "^$ns$" &> /dev/null; then | 54 | if ! busywait $BUSYWAIT_TIMEOUT ip netns list \| grep -vq "^$ns$" &> /dev/null; then |
| 52 | echo "Warn: Failed to remove namespace $ns" | 55 | echo "Warn: Failed to remove namespace $ns" |
| 53 | ret=1 | 56 | ret=1 |
| 54 | fi | 57 | fi |
| @@ -22,8 +22,11 @@ CONFIG_NFT_TPROXY=m · 21 unmodified lines | |||
| 22 | CONFIG_NFT_SOCKET=m | 22 | CONFIG_NFT_SOCKET=m |
| 23 | CONFIG_IP_ADVANCED_ROUTER=y | 23 | CONFIG_IP_ADVANCED_ROUTER=y |
| 24 | CONFIG_IP_MULTIPLE_TABLES=y | 24 | CONFIG_IP_MULTIPLE_TABLES=y |
| 25 | CONFIG_IP_NF_FILTER=m | ||
| 26 | CONFIG_IP_NF_MANGLE=m | ||
| 25 | CONFIG_IP_NF_TARGET_REJECT=m | 27 | CONFIG_IP_NF_TARGET_REJECT=m |
| 26 | CONFIG_IPV6_MULTIPLE_TABLES=y | 28 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 29 | CONFIG_IP6_NF_FILTER=m | ||
| 27 | CONFIG_NET_ACT_CSUM=m | 30 | CONFIG_NET_ACT_CSUM=m |
| 28 | CONFIG_NET_ACT_PEDIT=m | 31 | CONFIG_NET_ACT_PEDIT=m |
| 29 | CONFIG_NET_CLS_ACT=y | 32 | CONFIG_NET_CLS_ACT=y |
| @@ -643,13 +643,6 @@ kill_events_pids() · 642 unmodified lines | |||
| 643 | mptcp_lib_kill_wait $evts_ns2_pid | 643 | mptcp_lib_kill_wait $evts_ns2_pid |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | kill_tests_wait() | ||
| 647 | { | ||
| 648 | #shellcheck disable=SC2046 | ||
| 649 | kill -SIGUSR1 $(ip netns pids $ns2) $(ip netns pids $ns1) | ||
| 650 | wait | ||
| 651 | } | ||
| 652 | |||
| 653 | pm_nl_set_limits() | 646 | pm_nl_set_limits() |
| 654 | { | 647 | { |
| 655 | local ns=$1 | 648 | local ns=$1 |
| @@ -3453,7 +3446,7 @@ userspace_tests() · 2797 unmodified lines | |||
| 3453 | chk_mptcp_info subflows 0 subflows 0 | 3446 | chk_mptcp_info subflows 0 subflows 0 |
| 3454 | chk_subflows_total 1 1 | 3447 | chk_subflows_total 1 1 |
| 3455 | kill_events_pids | 3448 | kill_events_pids |
| 3456 | wait $tests_pid | 3449 | mptcp_lib_kill_wait $tests_pid |
| 3457 | fi | 3450 | fi |
| 3458 | 3451 | ||
| 3459 | # userspace pm create destroy subflow | 3452 | # userspace pm create destroy subflow |
| @@ -3475,7 +3468,7 @@ userspace_tests() · 15 unmodified lines | |||
| 3475 | chk_mptcp_info subflows 0 subflows 0 | 3468 | chk_mptcp_info subflows 0 subflows 0 |
| 3476 | chk_subflows_total 1 1 | 3469 | chk_subflows_total 1 1 |
| 3477 | kill_events_pids | 3470 | kill_events_pids |
| 3478 | wait $tests_pid | 3471 | mptcp_lib_kill_wait $tests_pid |
| 3479 | fi | 3472 | fi |
| 3480 | 3473 | ||
| 3481 | # userspace pm create id 0 subflow | 3474 | # userspace pm create id 0 subflow |
| @@ -3494,7 +3487,7 @@ userspace_tests() · 12 unmodified lines | |||
| 3494 | chk_mptcp_info subflows 1 subflows 1 | 3487 | chk_mptcp_info subflows 1 subflows 1 |
| 3495 | chk_subflows_total 2 2 | 3488 | chk_subflows_total 2 2 |
| 3496 | kill_events_pids | 3489 | kill_events_pids |
| 3497 | wait $tests_pid | 3490 | mptcp_lib_kill_wait $tests_pid |
| 3498 | fi | 3491 | fi |
| 3499 | 3492 | ||
| 3500 | # userspace pm remove initial subflow | 3493 | # userspace pm remove initial subflow |
| @@ -3518,7 +3511,7 @@ userspace_tests() · 17 unmodified lines | |||
| 3518 | chk_mptcp_info subflows 1 subflows 1 | 3511 | chk_mptcp_info subflows 1 subflows 1 |
| 3519 | chk_subflows_total 1 1 | 3512 | chk_subflows_total 1 1 |
| 3520 | kill_events_pids | 3513 | kill_events_pids |
| 3521 | wait $tests_pid | 3514 | mptcp_lib_kill_wait $tests_pid |
| 3522 | fi | 3515 | fi |
| 3523 | 3516 | ||
| 3524 | # userspace pm send RM_ADDR for ID 0 | 3517 | # userspace pm send RM_ADDR for ID 0 |
| @@ -3544,7 +3537,7 @@ userspace_tests() · 19 unmodified lines | |||
| 3544 | chk_mptcp_info subflows 1 subflows 1 | 3537 | chk_mptcp_info subflows 1 subflows 1 |
| 3545 | chk_subflows_total 1 1 | 3538 | chk_subflows_total 1 1 |
| 3546 | kill_events_pids | 3539 | kill_events_pids |
| 3547 | wait $tests_pid | 3540 | mptcp_lib_kill_wait $tests_pid |
| 3548 | fi | 3541 | fi |
| 3549 | } | 3542 | } |
| 3550 | 3543 | ||
| @@ -3558,7 +3551,8 @@ endpoint_tests() · 7 unmodified lines | |||
| 3558 | pm_nl_set_limits $ns2 2 2 | 3551 | pm_nl_set_limits $ns2 2 2 |
| 3559 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 3552 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| 3560 | speed=slow \ | 3553 | speed=slow \ |
| 3561 | run_tests $ns1 $ns2 10.0.1.1 2>/dev/null & | 3554 | run_tests $ns1 $ns2 10.0.1.1 & |
| 3555 | local tests_pid=$! | ||
| 3562 | 3556 | ||
| 3563 | wait_mpj $ns1 | 3557 | wait_mpj $ns1 |
| 3564 | pm_nl_check_endpoint "creation" \ | 3558 | pm_nl_check_endpoint "creation" \ |
| @@ -3573,7 +3567,7 @@ endpoint_tests() · 8 unmodified lines | |||
| 3573 | pm_nl_add_endpoint $ns2 10.0.2.2 flags signal | 3567 | pm_nl_add_endpoint $ns2 10.0.2.2 flags signal |
| 3574 | pm_nl_check_endpoint "modif is allowed" \ | 3568 | pm_nl_check_endpoint "modif is allowed" \ |
| 3575 | $ns2 10.0.2.2 id 1 flags signal | 3569 | $ns2 10.0.2.2 id 1 flags signal |
| 3576 | kill_tests_wait | 3570 | mptcp_lib_kill_wait $tests_pid |
| 3577 | fi | 3571 | fi |
| 3578 | 3572 | ||
| 3579 | if reset "delete and re-add" && | 3573 | if reset "delete and re-add" && |
| @@ -3582,7 +3576,8 @@ endpoint_tests() · 2 unmodified lines | |||
| 3582 | pm_nl_set_limits $ns2 1 1 | 3576 | pm_nl_set_limits $ns2 1 1 |
| 3583 | pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow | 3577 | pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow |
| 3584 | test_linkfail=4 speed=20 \ | 3578 | test_linkfail=4 speed=20 \ |
| 3585 | run_tests $ns1 $ns2 10.0.1.1 2>/dev/null & | 3579 | run_tests $ns1 $ns2 10.0.1.1 & |
| 3580 | local tests_pid=$! | ||
| 3586 | 3581 | ||
| 3587 | wait_mpj $ns2 | 3582 | wait_mpj $ns2 |
| 3588 | chk_subflow_nr "before delete" 2 | 3583 | chk_subflow_nr "before delete" 2 |
| @@ -3597,7 +3592,7 @@ endpoint_tests() · 8 unmodified lines | |||
| 3597 | wait_mpj $ns2 | 3592 | wait_mpj $ns2 |
| 3598 | chk_subflow_nr "after re-add" 2 | 3593 | chk_subflow_nr "after re-add" 2 |
| 3599 | chk_mptcp_info subflows 1 subflows 1 | 3594 | chk_mptcp_info subflows 1 subflows 1 |
| 3600 | kill_tests_wait | 3595 | mptcp_lib_kill_wait $tests_pid |
| 3601 | fi | 3596 | fi |
| 3602 | } | 3597 | } |
| 3603 | 3598 | ||
| @@ -6,7 +6,7 @@ readonly KSFT_FAIL=1 · 5 unmodified lines | |||
| 6 | readonly KSFT_SKIP=4 | 6 | readonly KSFT_SKIP=4 |
| 7 | 7 | ||
| 8 | # shellcheck disable=SC2155 # declare and assign separately | 8 | # shellcheck disable=SC2155 # declare and assign separately |
| 9 | readonly KSFT_TEST=$(basename "${0}" | sed 's/\.sh$//g') | 9 | readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}" |
| 10 | 10 | ||
| 11 | MPTCP_LIB_SUBTESTS=() | 11 | MPTCP_LIB_SUBTESTS=() |
| 12 | 12 | ||
| @@ -1 +1 @@ | |||
| 1 | timeout=1200 | 1 | timeout=1800 |
| @@ -284,12 +284,12 @@ done · 283 unmodified lines | |||
| 284 | 284 | ||
| 285 | setup | 285 | setup |
| 286 | run_test 10 10 0 0 "balanced bwidth" | 286 | run_test 10 10 0 0 "balanced bwidth" |
| 287 | run_test 10 10 1 50 "balanced bwidth with unbalanced delay" | 287 | run_test 10 10 1 25 "balanced bwidth with unbalanced delay" |
| 288 | 288 | ||
| 289 | # we still need some additional infrastructure to pass the following test-cases | 289 | # we still need some additional infrastructure to pass the following test-cases |
| 290 | run_test 30 10 0 0 "unbalanced bwidth" | 290 | run_test 10 3 0 0 "unbalanced bwidth" |
| 291 | run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay" | 291 | run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay" |
| 292 | run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay" | 292 | run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay" |
| 293 | 293 | ||
| 294 | mptcp_lib_result_print_all_tap | 294 | mptcp_lib_result_print_all_tap |
| 295 | exit $ret | 295 | exit $ret |
File mode changed from 100755 to 100644.
| @@ -707,23 +707,23 @@ setup_xfrm6() { · 706 unmodified lines | |||
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | setup_xfrm4udp() { | 709 | setup_xfrm4udp() { |
| 710 | setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" | 710 | setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ |
| 711 | setup_nettest_xfrm 4 4500 | 711 | setup_nettest_xfrm 4 4500 |
| 712 | } | 712 | } |
| 713 | 713 | ||
| 714 | setup_xfrm6udp() { | 714 | setup_xfrm6udp() { |
| 715 | setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" | 715 | setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ |
| 716 | setup_nettest_xfrm 6 4500 | 716 | setup_nettest_xfrm 6 4500 |
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | setup_xfrm4udprouted() { | 719 | setup_xfrm4udprouted() { |
| 720 | setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" | 720 | setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" && \ |
| 721 | setup_nettest_xfrm 4 4500 | 721 | setup_nettest_xfrm 4 4500 |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | setup_xfrm6udprouted() { | 724 | setup_xfrm6udprouted() { |
| 725 | setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" | 725 | setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" && \ |
| 726 | setup_nettest_xfrm 6 4500 | 726 | setup_nettest_xfrm 6 4500 |
| 727 | } | 727 | } |
| 728 | 728 | ||
| 729 | setup_routing_old() { | 729 | setup_routing_old() { |
| @@ -1339,7 +1339,7 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() { · 609 unmodified lines | |||
| 1339 | 1339 | ||
| 1340 | sleep 1 | 1340 | sleep 1 |
| 1341 | 1341 | ||
| 1342 | dd if=/dev/zero of=/dev/stdout status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3 | 1342 | dd if=/dev/zero status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3 |
| 1343 | 1343 | ||
| 1344 | size=$(du -sb $tmpoutfile) | 1344 | size=$(du -sb $tmpoutfile) |
| 1345 | size=${size%%/tmp/*} | 1345 | size=${size%%/tmp/*} |
File mode changed from 100755 to 100644.
| @@ -11,7 +11,7 @@ setup_veth_ns() { · 10 unmodified lines | |||
| 11 | local -r ns_mac="$4" | 11 | local -r ns_mac="$4" |
| 12 | 12 | ||
| 13 | [[ -e /var/run/netns/"${ns_name}" ]] || ip netns add "${ns_name}" | 13 | [[ -e /var/run/netns/"${ns_name}" ]] || ip netns add "${ns_name}" |
| 14 | echo 100000 > "/sys/class/net/${ns_dev}/gro_flush_timeout" | 14 | echo 1000000 > "/sys/class/net/${ns_dev}/gro_flush_timeout" |
| 15 | ip link set dev "${ns_dev}" netns "${ns_name}" mtu 65535 | 15 | ip link set dev "${ns_dev}" netns "${ns_name}" mtu 65535 |
| 16 | ip -netns "${ns_name}" link set dev "${ns_dev}" up | 16 | ip -netns "${ns_name}" link set dev "${ns_dev}" up |
| 17 | 17 | ||
| @@ -0,0 +1,10 @@ | |||
| 1 | CONFIG_CRYPTO_HMAC=y | ||
| 2 | CONFIG_CRYPTO_RMD160=y | ||
| 3 | CONFIG_CRYPTO_SHA1=y | ||
| 4 | CONFIG_IPV6_MULTIPLE_TABLES=y | ||
| 5 | CONFIG_IPV6=y | ||
| 6 | CONFIG_NET_L3_MASTER_DEV=y | ||
| 7 | CONFIG_NET_VRF=y | ||
| 8 | CONFIG_TCP_AO=y | ||
| 9 | CONFIG_TCP_MD5SIG=y | ||
| 10 | CONFIG_VETH=m | ||
| @@ -417,9 +417,9 @@ struct test_key { · 416 unmodified lines | |||
| 417 | matches_vrf : 1, | 417 | matches_vrf : 1, |
| 418 | is_current : 1, | 418 | is_current : 1, |
| 419 | is_rnext : 1, | 419 | is_rnext : 1, |
| 420 | used_on_handshake : 1, | 420 | used_on_server_tx : 1, |
| 421 | used_after_accept : 1, | 421 | used_on_client_tx : 1, |
| 422 | used_on_client : 1; | 422 | skip_counters_checks : 1; |
| 423 | }; | 423 | }; |
| 424 | 424 | ||
| 425 | struct key_collection { | 425 | struct key_collection { |
| @@ -609,16 +609,14 @@ static int key_collection_socket(bool server, unsigned int port) · 183 unmodified lines | |||
| 609 | addr = &this_ip_dest; | 609 | addr = &this_ip_dest; |
| 610 | sndid = key->client_keyid; | 610 | sndid = key->client_keyid; |
| 611 | rcvid = key->server_keyid; | 611 | rcvid = key->server_keyid; |
| 612 | set_current = key->is_current; | 612 | key->used_on_client_tx = set_current = key->is_current; |
| 613 | set_rnext = key->is_rnext; | 613 | key->used_on_server_tx = set_rnext = key->is_rnext; |
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | if (test_add_key_cr(sk, key->password, key->len, | 616 | if (test_add_key_cr(sk, key->password, key->len, |
| 617 | *addr, vrf, sndid, rcvid, key->maclen, | 617 | *addr, vrf, sndid, rcvid, key->maclen, |
| 618 | key->alg, set_current, set_rnext)) | 618 | key->alg, set_current, set_rnext)) |
| 619 | test_key_error("setsockopt(TCP_AO_ADD_KEY)", key); | 619 | test_key_error("setsockopt(TCP_AO_ADD_KEY)", key); |
| 620 | if (set_current || set_rnext) | ||
| 621 | key->used_on_handshake = 1; | ||
| 622 | #ifdef DEBUG | 620 | #ifdef DEBUG |
| 623 | test_print("%s [%u/%u] key: { %s, %u:%u, %u, %u:%u:%u:%u (%u)}", | 621 | test_print("%s [%u/%u] key: { %s, %u:%u, %u, %u:%u:%u:%u (%u)}", |
| 624 | server ? "server" : "client", i, collection.nr_keys, | 622 | server ? "server" : "client", i, collection.nr_keys, |
| @@ -640,22 +638,22 @@ static void verify_counters(const char *tst_name, bool is_listen_sk, bool server · 15 unmodified lines | |||
| 640 | for (i = 0; i < collection.nr_keys; i++) { | 638 | for (i = 0; i < collection.nr_keys; i++) { |
| 641 | struct test_key *key = &collection.keys[i]; | 639 | struct test_key *key = &collection.keys[i]; |
| 642 | uint8_t sndid, rcvid; | 640 | uint8_t sndid, rcvid; |
| 643 | bool was_used; | 641 | bool rx_cnt_expected; |
| 644 | 642 | ||
| 643 | if (key->skip_counters_checks) | ||
| 644 | continue; | ||
| 645 | if (server) { | 645 | if (server) { |
| 646 | sndid = key->server_keyid; | 646 | sndid = key->server_keyid; |
| 647 | rcvid = key->client_keyid; | 647 | rcvid = key->client_keyid; |
| 648 | if (is_listen_sk) | 648 | rx_cnt_expected = key->used_on_client_tx; |
| 649 | was_used = key->used_on_handshake; | ||
| 650 | else | ||
| 651 | was_used = key->used_after_accept; | ||
| 652 | } else { | 649 | } else { |
| 653 | sndid = key->client_keyid; | 650 | sndid = key->client_keyid; |
| 654 | rcvid = key->server_keyid; | 651 | rcvid = key->server_keyid; |
| 655 | was_used = key->used_on_client; | 652 | rx_cnt_expected = key->used_on_server_tx; |
| 656 | } | 653 | } |
| 657 | 654 | ||
| 658 | test_tcp_ao_key_counters_cmp(tst_name, a, b, was_used, | 655 | test_tcp_ao_key_counters_cmp(tst_name, a, b, |
| 656 | rx_cnt_expected ? TEST_CNT_KEY_GOOD : 0, | ||
| 659 | sndid, rcvid); | 657 | sndid, rcvid); |
| 660 | } | 658 | } |
| 661 | test_tcp_ao_counters_free(a); | 659 | test_tcp_ao_counters_free(a); |
| @@ -843,7 +841,7 @@ static void end_server(const char *tst_name, int sk, · 181 unmodified lines | |||
| 843 | synchronize_threads(); /* 4: verified => closed */ | 841 | synchronize_threads(); /* 4: verified => closed */ |
| 844 | close(sk); | 842 | close(sk); |
| 845 | 843 | ||
| 846 | verify_counters(tst_name, true, false, begin, &end); | 844 | verify_counters(tst_name, false, true, begin, &end); |
| 847 | synchronize_threads(); /* 5: counters */ | 845 | synchronize_threads(); /* 5: counters */ |
| 848 | } | 846 | } |
| 849 | 847 | ||
| @@ -916,9 +914,8 @@ static int run_client(const char *tst_name, unsigned int port, · 66 unmodified lines | |||
| 916 | current_index = nr_keys - 1; | 914 | current_index = nr_keys - 1; |
| 917 | if (rnext_index < 0) | 915 | if (rnext_index < 0) |
| 918 | rnext_index = nr_keys - 1; | 916 | rnext_index = nr_keys - 1; |
| 919 | collection.keys[current_index].used_on_handshake = 1; | 917 | collection.keys[current_index].used_on_client_tx = 1; |
| 920 | collection.keys[rnext_index].used_after_accept = 1; | 918 | collection.keys[rnext_index].used_on_server_tx = 1; |
| 921 | collection.keys[rnext_index].used_on_client = 1; | ||
| 922 | 919 | ||
| 923 | synchronize_threads(); /* 3: accepted => send data */ | 920 | synchronize_threads(); /* 3: accepted => send data */ |
| 924 | if (test_client_verify(sk, msg_sz, msg_nr, TEST_TIMEOUT_SEC)) { | 921 | if (test_client_verify(sk, msg_sz, msg_nr, TEST_TIMEOUT_SEC)) { |
| @@ -1059,7 +1056,16 @@ static void check_current_back(const char *tst_name, unsigned int port, · 134 unmodified lines | |||
| 1059 | test_error("Can't change the current key"); | 1056 | test_error("Can't change the current key"); |
| 1060 | if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) | 1057 | if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) |
| 1061 | test_fail("verify failed"); | 1058 | test_fail("verify failed"); |
| 1062 | collection.keys[rotate_to_index].used_after_accept = 1; | 1059 | /* There is a race here: between setting the current_key with |
| 1060 | * setsockopt(TCP_AO_INFO) and starting to send some data - there | ||
| 1061 | * might have been a segment received with the desired | ||
| 1062 | * RNext_key set. In turn that would mean that the first outgoing | ||
| 1063 | * segment will have the desired current_key (flipped back). | ||
| 1064 | * Which is what the user/test wants. As it's racy, skip checking | ||
| 1065 | * the counters, yet check what are the resulting current/rnext | ||
| 1066 | * keys on both sides. | ||
| 1067 | */ | ||
| 1068 | collection.keys[rotate_to_index].skip_counters_checks = 1; | ||
| 1063 | 1069 | ||
| 1064 | end_client(tst_name, sk, nr_keys, current_index, rnext_index, &tmp); | 1070 | end_client(tst_name, sk, nr_keys, current_index, rnext_index, &tmp); |
| 1065 | } | 1071 | } |
| @@ -1089,7 +1095,7 @@ static void roll_over_keys(const char *tst_name, unsigned int port, · 23 unmodified lines | |||
| 1089 | } | 1095 | } |
| 1090 | verify_current_rnext(tst_name, sk, -1, | 1096 | verify_current_rnext(tst_name, sk, -1, |
| 1091 | collection.keys[i].server_keyid); | 1097 | collection.keys[i].server_keyid); |
| 1092 | collection.keys[i].used_on_client = 1; | 1098 | collection.keys[i].used_on_server_tx = 1; |
| 1093 | synchronize_threads(); /* verify current/rnext */ | 1099 | synchronize_threads(); /* verify current/rnext */ |
| 1094 | } | 1100 | } |
| 1095 | end_client(tst_name, sk, nr_keys, current_index, rnext_index, &tmp); | 1101 | end_client(tst_name, sk, nr_keys, current_index, rnext_index, &tmp); |
| @@ -62,7 +62,9 @@ int test_wait_fd(int sk, time_t sec, bool write) · 61 unmodified lines | |||
| 62 | return -ETIMEDOUT; | 62 | return -ETIMEDOUT; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &slen) || ret) | 65 | if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &slen)) |
| 66 | return -errno; | ||
| 67 | if (ret) | ||
| 66 | return -ret; | 68 | return -ret; |
| 67 | return 0; | 69 | return 0; |
| 68 | } | 70 | } |
| @@ -584,9 +586,11 @@ int test_client_verify(int sk, const size_t msg_len, const size_t nr, · 515 unmodified lines | |||
| 584 | { | 586 | { |
| 585 | size_t buf_sz = msg_len * nr; | 587 | size_t buf_sz = msg_len * nr; |
| 586 | char *buf = alloca(buf_sz); | 588 | char *buf = alloca(buf_sz); |
| 589 | ssize_t ret; | ||
| 587 | 590 | ||
| 588 | randomize_buffer(buf, buf_sz); | 591 | randomize_buffer(buf, buf_sz); |
| 589 | if (test_client_loop(sk, buf, buf_sz, msg_len, timeout_sec) != buf_sz) | 592 | ret = test_client_loop(sk, buf, buf_sz, msg_len, timeout_sec); |
| 590 | return -1; | 593 | if (ret < 0) |
| 591 | return 0; | 594 | return (int)ret; |
| 595 | return ret != buf_sz ? -1 : 0; | ||
| 592 | } | 596 | } |
| @@ -1,10 +1,33 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* Author: Dmitry Safonov <dima@arista.com> */ | 2 | /* |
| 3 | * The test checks that both active and passive reset have correct TCP-AO | ||
| 4 | * signature. An "active" reset (abort) here is procured from closing | ||
| 5 | * listen() socket with non-accepted connections in the queue: | ||
| 6 | * inet_csk_listen_stop() => inet_child_forget() => | ||
| 7 | * => tcp_disconnect() => tcp_send_active_reset() | ||
| 8 | * | ||
| 9 | * The passive reset is quite hard to get on established TCP connections. | ||
| 10 | * It could be procured from non-established states, but the synchronization | ||
| 11 | * part from userspace in order to reliably get RST seems uneasy. | ||
| 12 | * So, instead it's procured by corrupting SEQ number on TIMED-WAIT state. | ||
| 13 | * | ||
| 14 | * It's important to test both passive and active RST as they go through | ||
| 15 | * different code-paths: | ||
| 16 | * - tcp_send_active_reset() makes no-data skb, sends it with tcp_transmit_skb() | ||
| 17 | * - tcp_v*_send_reset() create their reply skbs and send them with | ||
| 18 | * ip_send_unicast_reply() | ||
| 19 | * | ||
| 20 | * In both cases TCP-AO signatures have to be correct, which is verified by | ||
| 21 | * (1) checking that the TCP-AO connection was reset and (2) TCP-AO counters. | ||
| 22 | * | ||
| 23 | * Author: Dmitry Safonov <dima@arista.com> | ||
| 24 | */ | ||
| 3 | #include <inttypes.h> | 25 | #include <inttypes.h> |
| 4 | #include "../../../../include/linux/kernel.h" | 26 | #include "../../../../include/linux/kernel.h" |
| 5 | #include "aolib.h" | 27 | #include "aolib.h" |
| 6 | 28 | ||
| 7 | const size_t quota = 1000; | 29 | const size_t quota = 1000; |
| 30 | const size_t packet_sz = 100; | ||
| 8 | /* | 31 | /* |
| 9 | * Backlog == 0 means 1 connection in queue, see: | 32 | * Backlog == 0 means 1 connection in queue, see: |
| 10 | * commit 64a146513f8f ("[NET]: Revert incorrect accept queue...") | 33 | * commit 64a146513f8f ("[NET]: Revert incorrect accept queue...") |
| @@ -59,26 +82,6 @@ static void close_forced(int sk) · 48 unmodified lines | |||
| 59 | close(sk); | 82 | close(sk); |
| 60 | } | 83 | } |
| 61 | 84 | ||
| 62 | static int test_wait_for_exception(int sk, time_t sec) | ||
| 63 | { | ||
| 64 | struct timeval tv = { .tv_sec = sec }; | ||
| 65 | struct timeval *ptv = NULL; | ||
| 66 | fd_set efds; | ||
| 67 | int ret; | ||
| 68 | |||
| 69 | FD_ZERO(&efds); | ||
| 70 | FD_SET(sk, &efds); | ||
| 71 | |||
| 72 | if (sec) | ||
| 73 | ptv = &tv; | ||
| 74 | |||
| 75 | errno = 0; | ||
| 76 | ret = select(sk + 1, NULL, NULL, &efds, ptv); | ||
| 77 | if (ret < 0) | ||
| 78 | return -errno; | ||
| 79 | return ret ? sk : 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | static void test_server_active_rst(unsigned int port) | 85 | static void test_server_active_rst(unsigned int port) |
| 83 | { | 86 | { |
| 84 | struct tcp_ao_counters cnt1, cnt2; | 87 | struct tcp_ao_counters cnt1, cnt2; |
| @@ -155,17 +158,16 @@ static void test_server_passive_rst(unsigned int port) · 70 unmodified lines | |||
| 155 | test_fail("server returned %zd", bytes); | 158 | test_fail("server returned %zd", bytes); |
| 156 | } | 159 | } |
| 157 | 160 | ||
| 158 | synchronize_threads(); /* 3: chekpoint/restore the connection */ | 161 | synchronize_threads(); /* 3: checkpoint the client */ |
| 162 | synchronize_threads(); /* 4: close the server, creating twsk */ | ||
| 159 | if (test_get_tcp_ao_counters(sk, &ao2)) | 163 | if (test_get_tcp_ao_counters(sk, &ao2)) |
| 160 | test_error("test_get_tcp_ao_counters()"); | 164 | test_error("test_get_tcp_ao_counters()"); |
| 161 | |||
| 162 | synchronize_threads(); /* 4: terminate server + send more on client */ | ||
| 163 | bytes = test_server_run(sk, quota, TEST_RETRANSMIT_SEC); | ||
| 164 | close(sk); | 165 | close(sk); |
| 166 | |||
| 167 | synchronize_threads(); /* 5: restore the socket, send more data */ | ||
| 165 | test_tcp_ao_counters_cmp("passive RST server", &ao1, &ao2, TEST_CNT_GOOD); | 168 | test_tcp_ao_counters_cmp("passive RST server", &ao1, &ao2, TEST_CNT_GOOD); |
| 166 | 169 | ||
| 167 | synchronize_threads(); /* 5: verified => closed */ | 170 | synchronize_threads(); /* 6: server exits */ |
| 168 | close(sk); | ||
| 169 | } | 171 | } |
| 170 | 172 | ||
| 171 | static void *server_fn(void *arg) | 173 | static void *server_fn(void *arg) |
| @@ -284,7 +286,7 @@ static void test_client_active_rst(unsigned int port) · 112 unmodified lines | |||
| 284 | test_error("test_wait_fds(): %d", err); | 286 | test_error("test_wait_fds(): %d", err); |
| 285 | 287 | ||
| 286 | synchronize_threads(); /* 3: close listen socket */ | 288 | synchronize_threads(); /* 3: close listen socket */ |
| 287 | if (test_client_verify(sk[0], 100, quota / 100, TEST_TIMEOUT_SEC)) | 289 | if (test_client_verify(sk[0], packet_sz, quota / packet_sz, TEST_TIMEOUT_SEC)) |
| 288 | test_fail("Failed to send data on connected socket"); | 290 | test_fail("Failed to send data on connected socket"); |
| 289 | else | 291 | else |
| 290 | test_ok("Verified established tcp connection"); | 292 | test_ok("Verified established tcp connection"); |
| @@ -323,7 +325,6 @@ static void test_client_passive_rst(unsigned int port) · 32 unmodified lines | |||
| 323 | struct tcp_sock_state img; | 325 | struct tcp_sock_state img; |
| 324 | sockaddr_af saddr; | 326 | sockaddr_af saddr; |
| 325 | int sk, err; | 327 | int sk, err; |
| 326 | socklen_t slen = sizeof(err); | ||
| 327 | 328 | ||
| 328 | sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); | 329 | sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); |
| 329 | if (sk < 0) | 330 | if (sk < 0) |
| @@ -337,18 +338,51 @@ static void test_client_passive_rst(unsigned int port) · 7 unmodified lines | |||
| 337 | test_error("failed to connect()"); | 338 | test_error("failed to connect()"); |
| 338 | 339 | ||
| 339 | synchronize_threads(); /* 2: accepted => send data */ | 340 | synchronize_threads(); /* 2: accepted => send data */ |
| 340 | if (test_client_verify(sk, 100, quota / 100, TEST_TIMEOUT_SEC)) | 341 | if (test_client_verify(sk, packet_sz, quota / packet_sz, TEST_TIMEOUT_SEC)) |
| 341 | test_fail("Failed to send data on connected socket"); | 342 | test_fail("Failed to send data on connected socket"); |
| 342 | else | 343 | else |
| 343 | test_ok("Verified established tcp connection"); | 344 | test_ok("Verified established tcp connection"); |
| 344 | 345 | ||
| 345 | synchronize_threads(); /* 3: chekpoint/restore the connection */ | 346 | synchronize_threads(); /* 3: checkpoint the client */ |
| 346 | test_enable_repair(sk); | 347 | test_enable_repair(sk); |
| 347 | test_sock_checkpoint(sk, &img, &saddr); | 348 | test_sock_checkpoint(sk, &img, &saddr); |
| 348 | test_ao_checkpoint(sk, &ao_img); | 349 | test_ao_checkpoint(sk, &ao_img); |
| 349 | test_kill_sk(sk); | 350 | test_disable_repair(sk); |
| 350 | 351 | ||
| 351 | img.out.seq += quota; | 352 | synchronize_threads(); /* 4: close the server, creating twsk */ |
| 353 | |||
| 354 | /* | ||
| 355 | * The "corruption" in SEQ has to be small enough to fit into TCP | ||
| 356 | * window, see tcp_timewait_state_process() for out-of-window | ||
| 357 | * segments. | ||
| 358 | */ | ||
| 359 | img.out.seq += 5; /* 5 is more noticeable in tcpdump than 1 */ | ||
| 360 | |||
| 361 | /* | ||
| 362 | * FIXME: This is kind-of ugly and dirty, but it works. | ||
| 363 | * | ||
| 364 | * At this moment, the server has close'ed(sk). | ||
| 365 | * The passive RST that is being targeted here is new data after | ||
| 366 | * half-duplex close, see tcp_timewait_state_process() => TCP_TW_RST | ||
| 367 | * | ||
| 368 | * What is needed here is: | ||
| 369 | * (1) wait for FIN from the server | ||
| 370 | * (2) make sure that the ACK from the client went out | ||
| 371 | * (3) make sure that the ACK was received and processed by the server | ||
| 372 | * | ||
| 373 | * Otherwise, the data that will be sent from "repaired" socket | ||
| 374 | * post SEQ corruption may get to the server before it's in | ||
| 375 | * TCP_FIN_WAIT2. | ||
| 376 | * | ||
| 377 | * (1) is easy with select()/poll() | ||
| 378 | * (2) is possible by polling tcpi_state from TCP_INFO | ||
| 379 | * (3) is quite complex: as server's socket was already closed, | ||
| 380 | * probably the way to do it would be tcp-diag. | ||
| 381 | */ | ||
| 382 | sleep(TEST_RETRANSMIT_SEC); | ||
| 383 | |||
| 384 | synchronize_threads(); /* 5: restore the socket, send more data */ | ||
| 385 | test_kill_sk(sk); | ||
| 352 | 386 | ||
| 353 | sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); | 387 | sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); |
| 354 | if (sk < 0) | 388 | if (sk < 0) |
| @@ -366,25 +400,33 @@ static void test_client_passive_rst(unsigned int port) · 11 unmodified lines | |||
| 366 | test_disable_repair(sk); | 400 | test_disable_repair(sk); |
| 367 | test_sock_state_free(&img); | 401 | test_sock_state_free(&img); |
| 368 | 402 | ||
| 369 | synchronize_threads(); /* 4: terminate server + send more on client */ | 403 | /* |
| 370 | if (test_client_verify(sk, 100, quota / 100, 2 * TEST_TIMEOUT_SEC)) | 404 | * This is how "passive reset" is acquired in this test from TCP_TW_RST: |
| 371 | test_ok("client connection broken post-seq-adjust"); | 405 | * |
| 372 | else | 406 | * IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [P.], seq 901:1001, ack 1001, win 249, |
| 373 | test_fail("client connection still works post-seq-adjust"); | 407 | * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x10217d6c36a22379086ef3b1], length 100 |
| 374 | 408 | * IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [F.], seq 1001, ack 1001, win 249, | |
| 375 | test_wait_for_exception(sk, TEST_TIMEOUT_SEC); | 409 | * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x104ffc99b98c10a5298cc268], length 0 |
| 376 | 410 | * IP 10.0.1.1.59772 > 10.0.254.1.7011: Flags [.], ack 1002, win 251, | |
| 377 | if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &slen)) | 411 | * options [tcp-ao keyid 100 rnextkeyid 100 mac 0xe496dd4f7f5a8a66873c6f93,nop,nop,sack 1 {1001:1002}], length 0 |
| 378 | test_error("getsockopt()"); | 412 | * IP 10.0.1.1.59772 > 10.0.254.1.7011: Flags [P.], seq 1006:1106, ack 1001, win 251, |
| 379 | if (err != ECONNRESET && err != EPIPE) | 413 | * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x1b5f3330fb23fbcd0c77d0ca], length 100 |
| 380 | test_fail("client connection was not reset: %d", err); | 414 | * IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [R], seq 3215596252, win 0, |
| 415 | * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x0bcfbbf497bce844312304b2], length 0 | ||
| 416 | */ | ||
| 417 | err = test_client_verify(sk, packet_sz, quota / packet_sz, 2 * TEST_TIMEOUT_SEC); | ||
| 418 | /* Make sure that the connection was reset, not timeouted */ | ||
| 419 | if (err && err == -ECONNRESET) | ||
| 420 | test_ok("client sock was passively reset post-seq-adjust"); | ||
| 421 | else if (err) | ||
| 422 | test_fail("client sock was not reset post-seq-adjust: %d", err); | ||
| 381 | else | 423 | else |
| 382 | test_ok("client connection was reset"); | 424 | test_fail("client sock is yet connected post-seq-adjust"); |
| 383 | 425 | ||
| 384 | if (test_get_tcp_ao_counters(sk, &ao2)) | 426 | if (test_get_tcp_ao_counters(sk, &ao2)) |
| 385 | test_error("test_get_tcp_ao_counters()"); | 427 | test_error("test_get_tcp_ao_counters()"); |
| 386 | 428 | ||
| 387 | synchronize_threads(); /* 5: verified => closed */ | 429 | synchronize_threads(); /* 6: server exits */ |
| 388 | close(sk); | 430 | close(sk); |
| 389 | test_tcp_ao_counters_cmp("client passive RST", &ao1, &ao2, TEST_CNT_GOOD); | 431 | test_tcp_ao_counters_cmp("client passive RST", &ao1, &ao2, TEST_CNT_GOOD); |
| 390 | } | 432 | } |
| @@ -410,6 +452,6 @@ static void *client_fn(void *arg) · 19 unmodified lines | |||
| 410 | 452 | ||
| 411 | int main(int argc, char *argv[]) | 453 | int main(int argc, char *argv[]) |
| 412 | { | 454 | { |
| 413 | test_init(15, server_fn, client_fn); | 455 | test_init(14, server_fn, client_fn); |
| 414 | return 0; | 456 | return 0; |
| 415 | } | 457 | } |
| @@ -0,0 +1 @@ | |||
| 1 | timeout=120 | ||
| @@ -7,7 +7,7 @@ source net_helper.sh · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" | 8 | readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" |
| 9 | 9 | ||
| 10 | BPF_FILE="../bpf/xdp_dummy.bpf.o" | 10 | BPF_FILE="xdp_dummy.o" |
| 11 | 11 | ||
| 12 | # set global exit status, but never reset nonzero one. | 12 | # set global exit status, but never reset nonzero one. |
| 13 | check_err() | 13 | check_err() |
| @@ -197,7 +197,7 @@ run_all() { · 183 unmodified lines | |||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | if [ ! -f ${BPF_FILE} ]; then | 199 | if [ ! -f ${BPF_FILE} ]; then |
| 200 | echo "Missing ${BPF_FILE}. Build bpf selftest first" | 200 | echo "Missing ${BPF_FILE}. Run 'make' first" |
| 201 | exit -1 | 201 | exit -1 |
| 202 | fi | 202 | fi |
| 203 | 203 | ||
| @@ -7,7 +7,7 @@ source net_helper.sh · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" | 8 | readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" |
| 9 | 9 | ||
| 10 | BPF_FILE="../bpf/xdp_dummy.bpf.o" | 10 | BPF_FILE="xdp_dummy.o" |
| 11 | 11 | ||
| 12 | cleanup() { | 12 | cleanup() { |
| 13 | local -r jobs="$(jobs -p)" | 13 | local -r jobs="$(jobs -p)" |
| @@ -84,7 +84,7 @@ run_all() { · 70 unmodified lines | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | if [ ! -f ${BPF_FILE} ]; then | 86 | if [ ! -f ${BPF_FILE} ]; then |
| 87 | echo "Missing ${BPF_FILE}. Build bpf selftest first" | 87 | echo "Missing ${BPF_FILE}. Run 'make' first" |
| 88 | exit -1 | 88 | exit -1 |
| 89 | fi | 89 | fi |
| 90 | 90 | ||
| @@ -7,7 +7,7 @@ source net_helper.sh · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" | 8 | readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" |
| 9 | 9 | ||
| 10 | BPF_FILE="../bpf/xdp_dummy.bpf.o" | 10 | BPF_FILE="xdp_dummy.o" |
| 11 | 11 | ||
| 12 | cleanup() { | 12 | cleanup() { |
| 13 | local -r jobs="$(jobs -p)" | 13 | local -r jobs="$(jobs -p)" |
| @@ -85,12 +85,12 @@ run_all() { · 71 unmodified lines | |||
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | if [ ! -f ${BPF_FILE} ]; then | 87 | if [ ! -f ${BPF_FILE} ]; then |
| 88 | echo "Missing ${BPF_FILE}. Build bpf selftest first" | 88 | echo "Missing ${BPF_FILE}. Run 'make' first" |
| 89 | exit -1 | 89 | exit -1 |
| 90 | fi | 90 | fi |
| 91 | 91 | ||
| 92 | if [ ! -f nat6to4.o ]; then | 92 | if [ ! -f nat6to4.o ]; then |
| 93 | echo "Missing nat6to4 helper. Build bpf nat6to4.o selftest first" | 93 | echo "Missing nat6to4 helper. Run 'make' first" |
| 94 | exit -1 | 94 | exit -1 |
| 95 | fi | 95 | fi |
| 96 | 96 | ||
| @@ -1,7 +1,9 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | ||
| 4 | BPF_FILE="../bpf/xdp_dummy.bpf.o" | 4 | source net_helper.sh |
| 5 | |||
| 6 | BPF_FILE="xdp_dummy.o" | ||
| 5 | readonly BASE="ns-$(mktemp -u XXXXXX)" | 7 | readonly BASE="ns-$(mktemp -u XXXXXX)" |
| 6 | readonly SRC=2 | 8 | readonly SRC=2 |
| 7 | readonly DST=1 | 9 | readonly DST=1 |
| @@ -119,7 +121,7 @@ run_test() { · 111 unmodified lines | |||
| 119 | ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 8000 | 121 | ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 8000 |
| 120 | ip netns exec $NS_DST ./udpgso_bench_rx -C 1000 -R 10 -n 10 -l 1300 $rx_args & | 122 | ip netns exec $NS_DST ./udpgso_bench_rx -C 1000 -R 10 -n 10 -l 1300 $rx_args & |
| 121 | local spid=$! | 123 | local spid=$! |
| 122 | sleep 0.1 | 124 | wait_local_port_listen "$NS_DST" 8000 udp |
| 123 | ip netns exec $NS_SRC ./udpgso_bench_tx $family -M 1 -s 13000 -S 1300 -D $dst | 125 | ip netns exec $NS_SRC ./udpgso_bench_tx $family -M 1 -s 13000 -S 1300 -D $dst |
| 124 | local retc=$? | 126 | local retc=$? |
| 125 | wait $spid | 127 | wait $spid |
| @@ -168,7 +170,7 @@ run_bench() { · 42 unmodified lines | |||
| 168 | ip netns exec $NS_DST bash -c "echo 2 > /sys/class/net/veth$DST/queues/rx-0/rps_cpus" | 170 | ip netns exec $NS_DST bash -c "echo 2 > /sys/class/net/veth$DST/queues/rx-0/rps_cpus" |
| 169 | ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 1000 -R 10 & | 171 | ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 1000 -R 10 & |
| 170 | local spid=$! | 172 | local spid=$! |
| 171 | sleep 0.1 | 173 | wait_local_port_listen "$NS_DST" 8000 udp |
| 172 | ip netns exec $NS_SRC taskset 0x1 ./udpgso_bench_tx $family -l 3 -S 1300 -D $dst | 174 | ip netns exec $NS_SRC taskset 0x1 ./udpgso_bench_tx $family -l 3 -S 1300 -D $dst |
| 173 | local retc=$? | 175 | local retc=$? |
| 174 | wait $spid | 176 | wait $spid |
| @@ -1,7 +1,7 @@ | |||
| 1 | #!/bin/sh | 1 | #!/bin/sh |
| 2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | ||
| 4 | BPF_FILE="../bpf/xdp_dummy.bpf.o" | 4 | BPF_FILE="xdp_dummy.o" |
| 5 | readonly STATS="$(mktemp -p /tmp ns-XXXXXX)" | 5 | readonly STATS="$(mktemp -p /tmp ns-XXXXXX)" |
| 6 | readonly BASE=`basename $STATS` | 6 | readonly BASE=`basename $STATS` |
| 7 | readonly SRC=2 | 7 | readonly SRC=2 |
| @@ -218,7 +218,7 @@ while getopts "hs:" option; do · 210 unmodified lines | |||
| 218 | done | 218 | done |
| 219 | 219 | ||
| 220 | if [ ! -f ${BPF_FILE} ]; then | 220 | if [ ! -f ${BPF_FILE} ]; then |
| 221 | echo "Missing ${BPF_FILE}. Build bpf selftest first" | 221 | echo "Missing ${BPF_FILE}. Run 'make' first" |
| 222 | exit 1 | 222 | exit 1 |
| 223 | fi | 223 | fi |
| 224 | 224 | ||
| @@ -0,0 +1,13 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | #define KBUILD_MODNAME "xdp_dummy" | ||
| 4 | #include <linux/bpf.h> | ||
| 5 | #include <bpf/bpf_helpers.h> | ||
| 6 | |||
| 7 | SEC("xdp") | ||
| 8 | int xdp_dummy_prog(struct xdp_md *ctx) | ||
| 9 | { | ||
| 10 | return XDP_PASS; | ||
| 11 | } | ||
| 12 | |||
| 13 | char _license[] SEC("license") = "GPL"; | ||