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 | 2 | Date: March 2010 |
| 3 | 3 | KernelVersion: 2.6.35 |
| 4 | 4 | Contact: netdev@vger.kernel.org |
| @@ -8,7 +8,7 @@ Description: · 3 unmodified lines | ||
| 8 | 8 | network device queue. Possible values depend on the number |
| 9 | 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 | 12 | Date: April 2010 |
| 13 | 13 | KernelVersion: 2.6.35 |
| 14 | 14 | Contact: netdev@vger.kernel.org |
| @@ -16,7 +16,7 @@ Description: · 1 unmodified line | ||
| 16 | 16 | Number of Receive Packet Steering flows being currently |
| 17 | 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 | 20 | Date: November 2011 |
| 21 | 21 | KernelVersion: 3.3 |
| 22 | 22 | Contact: netdev@vger.kernel.org |
| @@ -24,7 +24,7 @@ Description: · 1 unmodified line | ||
| 24 | 24 | Indicates the number of transmit timeout events seen by this |
| 25 | 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 | 28 | Date: March 2015 |
| 29 | 29 | KernelVersion: 4.1 |
| 30 | 30 | Contact: netdev@vger.kernel.org |
| @@ -32,7 +32,7 @@ Description: · 1 unmodified line | ||
| 32 | 32 | A Mbps max-rate set for the queue, a value of zero means disabled, |
| 33 | 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 | 36 | Date: November 2010 |
| 37 | 37 | KernelVersion: 2.6.38 |
| 38 | 38 | Contact: netdev@vger.kernel.org |
| @@ -42,7 +42,7 @@ Description: · 3 unmodified lines | ||
| 42 | 42 | network device transmit queue. Possible values depend on the |
| 43 | 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 | 46 | Date: June 2018 |
| 47 | 47 | KernelVersion: 4.18.0 |
| 48 | 48 | Contact: netdev@vger.kernel.org |
| @@ -53,7 +53,7 @@ Description: · 4 unmodified lines | ||
| 53 | 53 | number of available receive queue(s) in the network device. |
| 54 | 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 | 57 | Date: November 2011 |
| 58 | 58 | KernelVersion: 3.3 |
| 59 | 59 | Contact: netdev@vger.kernel.org |
| @@ -62,7 +62,7 @@ Description: · 2 unmodified lines | ||
| 62 | 62 | of this particular network device transmit queue. |
| 63 | 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 | 66 | Date: November 2011 |
| 67 | 67 | KernelVersion: 3.3 |
| 68 | 68 | Contact: netdev@vger.kernel.org |
| @@ -70,7 +70,7 @@ Description: · 1 unmodified line | ||
| 70 | 70 | Indicates the number of bytes (objects) in flight on this |
| 71 | 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 | 74 | Date: November 2011 |
| 75 | 75 | KernelVersion: 3.3 |
| 76 | 76 | Contact: netdev@vger.kernel.org |
| @@ -79,7 +79,7 @@ Description: · 2 unmodified lines | ||
| 79 | 79 | on this network device transmit queue. This value is clamped |
| 80 | 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 | 83 | Date: November 2011 |
| 84 | 84 | KernelVersion: 3.3 |
| 85 | 85 | Contact: netdev@vger.kernel.org |
| @@ -88,7 +88,7 @@ Description: · 2 unmodified lines | ||
| 88 | 88 | queued on this network device transmit queue. See |
| 89 | 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 | 92 | Date: November 2011 |
| 93 | 93 | KernelVersion: 3.3 |
| 94 | 94 | Contact: netdev@vger.kernel.org |
| @@ -942,6 +942,10 @@ attribute-sets: · 941 unmodified lines | ||
| 942 | 942 | - |
| 943 | 943 | name: gro-ipv4-max-size |
| 944 | 944 | type: u32 |
| 945 | + - | |
| 946 | + name: dpll-pin | |
| 947 | + type: nest | |
| 948 | + nested-attributes: link-dpll-pin-attrs | |
| 945 | 949 | - |
| 946 | 950 | name: af-spec-attrs |
| 947 | 951 | attributes: |
| @@ -1627,6 +1631,12 @@ attribute-sets: · 679 unmodified lines | ||
| 1627 | 1631 | - |
| 1628 | 1632 | name: used |
| 1629 | 1633 | type: u8 |
| 1634 | + - | |
| 1635 | + name: link-dpll-pin-attrs | |
| 1636 | + attributes: | |
| 1637 | + - | |
| 1638 | + name: id | |
| 1639 | + type: u32 | |
| 1630 | 1640 | |
| 1631 | 1641 | sub-messages: |
| 1632 | 1642 | - |
| @@ -15181,6 +15181,7 @@ F: Documentation/networking/net_cachelines/net_device.rst · 15180 unmodified lines | ||
| 15181 | 15181 | F: drivers/connector/ |
| 15182 | 15182 | F: drivers/net/ |
| 15183 | 15183 | F: include/dt-bindings/net/ |
| 15184 | +F: include/linux/cn_proc.h | |
| 15184 | 15185 | F: include/linux/etherdevice.h |
| 15185 | 15186 | F: include/linux/fcdevice.h |
| 15186 | 15187 | F: include/linux/fddidevice.h |
| @@ -15188,6 +15189,7 @@ F: include/linux/hippidevice.h · 1 unmodified line | ||
| 15188 | 15189 | F: include/linux/if_* |
| 15189 | 15190 | F: include/linux/inetdevice.h |
| 15190 | 15191 | F: include/linux/netdevice.h |
| 15192 | +F: include/uapi/linux/cn_proc.h | |
| 15191 | 15193 | F: include/uapi/linux/if_* |
| 15192 | 15194 | F: include/uapi/linux/netdevice.h |
| 15193 | 15195 | X: drivers/net/wireless/ |
| @@ -18085,7 +18087,6 @@ F: drivers/net/ethernet/qualcomm/emac/ · 2891 unmodified lines | ||
| 18085 | 18087 | |
| 18086 | 18088 | QUALCOMM ETHQOS ETHERNET DRIVER |
| 18087 | 18089 | M: Vinod Koul <vkoul@kernel.org> |
| 18088 | −R: Bhupesh Sharma <bhupesh.sharma@linaro.org> | |
| 18089 | 18090 | L: netdev@vger.kernel.org |
| 18090 | 18091 | L: linux-arm-msm@vger.kernel.org |
| 18091 | 18092 | S: Maintained |
| @@ -2838,8 +2838,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, · 2837 unmodified lines | ||
| 2838 | 2838 | /* MT753x MAC works in 1G full duplex mode for all up-clocked |
| 2839 | 2839 | * variants. |
| 2840 | 2840 | */ |
| 2841 | − if (interface == PHY_INTERFACE_MODE_INTERNAL || | |
| 2842 | − interface == PHY_INTERFACE_MODE_TRGMII || | |
| 2841 | + if (interface == PHY_INTERFACE_MODE_TRGMII || | |
| 2843 | 2842 | (phy_interface_mode_is_8023z(interface))) { |
| 2844 | 2843 | speed = SPEED_1000; |
| 2845 | 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 | 3659 | int err; |
| 3660 | 3660 | |
| 3661 | 3661 | if (!chip->info->ops->phy_read_c45) |
| 3662 | − return -EOPNOTSUPP; | |
| 3662 | + return 0xffff; | |
| 3663 | 3663 | |
| 3664 | 3664 | mv88e6xxx_reg_lock(chip); |
| 3665 | 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 | 2051 | priv->info = of_device_get_match_data(priv->dev); |
| 2052 | 2052 | |
| 2053 | 2053 | priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", |
| 2054 | − GPIOD_ASIS); | |
| 2054 | + GPIOD_OUT_HIGH); | |
| 2055 | 2055 | if (IS_ERR(priv->reset_gpio)) |
| 2056 | 2056 | return PTR_ERR(priv->reset_gpio); |
| 2057 | 2057 | |
| 2058 | 2058 | if (priv->reset_gpio) { |
| 2059 | − gpiod_set_value_cansleep(priv->reset_gpio, 1); | |
| 2060 | 2059 | /* The active low duration must be greater than 10 ms |
| 2061 | 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 | 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 | 75 | void pdsc_process_adminq(struct pdsc_qcq *qcq) |
| 67 | 76 | { |
| 68 | 77 | union pds_core_adminq_comp *comp; |
| @@ -75,9 +84,9 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq) · 6 unmodified lines | ||
| 75 | 84 | int aq_work = 0; |
| 76 | 85 | int credits; |
| 77 | 86 | |
| 78 | − /* Don't process AdminQ when shutting down */ | |
| 79 | − if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { | |
| 80 | − dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", | |
| 87 | + /* Don't process AdminQ when it's not up */ | |
| 88 | + if (!pdsc_adminq_inc_if_up(pdsc)) { | |
| 89 | + dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", | |
| 81 | 90 | __func__); |
| 82 | 91 | return; |
| 83 | 92 | } |
| @@ -124,6 +133,7 @@ credits: · 40 unmodified lines | ||
| 124 | 133 | pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], |
| 125 | 134 | credits, |
| 126 | 135 | PDS_CORE_INTR_CRED_REARM); |
| 136 | + refcount_dec(&pdsc->adminq_refcnt); | |
| 127 | 137 | } |
| 128 | 138 | |
| 129 | 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 | 146 | irqreturn_t pdsc_adminq_isr(int irq, void *data) |
| 137 | 147 | { |
| 138 | − struct pdsc_qcq *qcq = data; | |
| 139 | − struct pdsc *pdsc = qcq->pdsc; | |
| 148 | + struct pdsc *pdsc = data; | |
| 149 | + struct pdsc_qcq *qcq; | |
| 140 | 150 | |
| 141 | − /* Don't process AdminQ when shutting down */ | |
| 142 | − if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { | |
| 143 | − dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", | |
| 151 | + /* Don't process AdminQ when it's not up */ | |
| 152 | + if (!pdsc_adminq_inc_if_up(pdsc)) { | |
| 153 | + dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", | |
| 144 | 154 | __func__); |
| 145 | 155 | return IRQ_HANDLED; |
| 146 | 156 | } |
| 147 | 157 | |
| 158 | + qcq = &pdsc->adminqcq; | |
| 148 | 159 | queue_work(pdsc->wq, &qcq->work); |
| 149 | 160 | pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); |
| 161 | + refcount_dec(&pdsc->adminq_refcnt); | |
| 150 | 162 | |
| 151 | 163 | return IRQ_HANDLED; |
| 152 | 164 | } |
| @@ -179,10 +191,16 @@ static int __pdsc_adminq_post(struct pdsc *pdsc, · 26 unmodified lines | ||
| 179 | 191 | |
| 180 | 192 | /* Check that the FW is running */ |
| 181 | 193 | if (!pdsc_is_fw_running(pdsc)) { |
| 182 | − u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | |
| 183 | − | |
| 184 | − dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", | |
| 185 | − __func__, fw_status); | |
| 194 | + if (pdsc->info_regs) { | |
| 195 | + u8 fw_status = | |
| 196 | + ioread8(&pdsc->info_regs->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 | 204 | ret = -ENXIO; |
| 187 | 205 | |
| 188 | 206 | goto err_out_unlock; |
| @@ -230,6 +248,12 @@ int pdsc_adminq_post(struct pdsc *pdsc, · 41 unmodified lines | ||
| 230 | 248 | int err = 0; |
| 231 | 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 | 257 | wc.qcq = &pdsc->adminqcq; |
| 234 | 258 | index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); |
| 235 | 259 | if (index < 0) { |
| @@ -248,10 +272,16 @@ int pdsc_adminq_post(struct pdsc *pdsc, · 12 unmodified lines | ||
| 248 | 272 | break; |
| 249 | 273 | |
| 250 | 274 | if (!pdsc_is_fw_running(pdsc)) { |
| 251 | − u8 fw_status = ioread8(&pdsc->info_regs->fw_status); | |
| 252 | − | |
| 253 | − dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", | |
| 254 | − __func__, fw_status); | |
| 275 | + if (pdsc->info_regs) { | |
| 276 | + u8 fw_status = | |
| 277 | + ioread8(&pdsc->info_regs->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 | 285 | err = -ENXIO; |
| 256 | 286 | break; |
| 257 | 287 | } |
| @@ -285,6 +315,8 @@ err_out: · 27 unmodified lines | ||
| 285 | 315 | queue_work(pdsc->wq, &pdsc->health_work); |
| 286 | 316 | } |
| 287 | 317 | |
| 318 | + refcount_dec(&pdsc->adminq_refcnt); | |
| 319 | + | |
| 288 | 320 | return err; |
| 289 | 321 | } |
| 290 | 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 | 126 | snprintf(name, sizeof(name), "%s-%d-%s", |
| 127 | 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 | 129 | if (index < 0) |
| 130 | 130 | return index; |
| 131 | 131 | qcq->intx = index; |
| @@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) · 272 unmodified lines | ||
| 404 | 404 | int numdescs; |
| 405 | 405 | int err; |
| 406 | 406 | |
| 407 | − if (init) | |
| 408 | − err = pdsc_dev_init(pdsc); | |
| 409 | − else | |
| 410 | − err = pdsc_dev_reinit(pdsc); | |
| 407 | + err = pdsc_dev_init(pdsc); | |
| 411 | 408 | if (err) |
| 412 | 409 | return err; |
| 413 | 410 | |
| @@ -450,6 +447,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init) · 36 unmodified lines | ||
| 450 | 447 | pdsc_debugfs_add_viftype(pdsc); |
| 451 | 448 | } |
| 452 | 449 | |
| 450 | + refcount_set(&pdsc->adminq_refcnt, 1); | |
| 453 | 451 | clear_bit(PDSC_S_FW_DEAD, &pdsc->state); |
| 454 | 452 | return 0; |
| 455 | 453 | |
| @@ -464,6 +462,8 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 8 unmodified lines | ||
| 464 | 462 | |
| 465 | 463 | if (!pdsc->pdev->is_virtfn) |
| 466 | 464 | pdsc_devcmd_reset(pdsc); |
| 465 | + if (pdsc->adminqcq.work.func) | |
| 466 | + cancel_work_sync(&pdsc->adminqcq.work); | |
| 467 | 467 | pdsc_qcq_free(pdsc, &pdsc->notifyqcq); |
| 468 | 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 | 476 | for (i = 0; i < pdsc->nintrs; i++) |
| 477 | 477 | pdsc_intr_free(pdsc, i); |
| 478 | 478 | |
| 479 | − if (removing) { | |
| 480 | − kfree(pdsc->intr_info); | |
| 481 | − pdsc->intr_info = NULL; | |
| 482 | − } | |
| 479 | + kfree(pdsc->intr_info); | |
| 480 | + pdsc->intr_info = NULL; | |
| 481 | + pdsc->nintrs = 0; | |
| 483 | 482 | } |
| 484 | 483 | |
| 485 | 484 | if (pdsc->kern_dbpage) { |
| @@ -487,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing) · 1 unmodified line | ||
| 487 | 486 | pdsc->kern_dbpage = NULL; |
| 488 | 487 | } |
| 489 | 488 | |
| 489 | + pci_free_irq_vectors(pdsc->pdev); | |
| 490 | 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 | 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 | 533 | void pdsc_fw_down(struct pdsc *pdsc) |
| 516 | 534 | { |
| 517 | 535 | union pds_core_notifyq_comp reset_event = { |
| @@ -527,6 +545,8 @@ void pdsc_fw_down(struct pdsc *pdsc) · 9 unmodified lines | ||
| 527 | 545 | if (pdsc->pdev->is_virtfn) |
| 528 | 546 | return; |
| 529 | 547 | |
| 548 | + pdsc_adminq_wait_and_dec_once_unused(pdsc); | |
| 549 | + | |
| 530 | 550 | /* Notify clients of fw_down */ |
| 531 | 551 | if (pdsc->fw_reporter) |
| 532 | 552 | devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); |
| @@ -577,7 +597,13 @@ err_out: · 44 unmodified lines | ||
| 577 | 597 | |
| 578 | 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 | 608 | /* is PCI broken? */ |
| 583 | 609 | if (fw_status != PDS_RC_BAD_PCI) |
| @@ -184,6 +184,7 @@ struct pdsc { · 183 unmodified lines | ||
| 184 | 184 | struct mutex devcmd_lock; /* lock for dev_cmd operations */ |
| 185 | 185 | struct mutex config_lock; /* lock for configuration operations */ |
| 186 | 186 | spinlock_t adminq_lock; /* lock for adminq operations */ |
| 187 | + refcount_t adminq_refcnt; | |
| 187 | 188 | struct pds_core_dev_info_regs __iomem *info_regs; |
| 188 | 189 | struct pds_core_dev_cmd_regs __iomem *cmd_regs; |
| 189 | 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 | 281 | union pds_core_dev_comp *comp, int max_seconds); |
| 281 | 282 | int pdsc_devcmd_init(struct pdsc *pdsc); |
| 282 | 283 | int pdsc_devcmd_reset(struct pdsc *pdsc); |
| 283 | −int pdsc_dev_reinit(struct pdsc *pdsc); | |
| 284 | 284 | int pdsc_dev_init(struct pdsc *pdsc); |
| 285 | 285 | |
| 286 | 286 | void pdsc_reset_prepare(struct pci_dev *pdev); |
| @@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity); · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 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 | 71 | debugfs_create_file("identity", 0400, pdsc->dentry, |
| 68 | 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 | 58 | bool pdsc_is_fw_running(struct pdsc *pdsc) |
| 59 | 59 | { |
| 60 | + if (!pdsc->info_regs) | |
| 61 | + return false; | |
| 62 | + | |
| 60 | 63 | pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); |
| 61 | 64 | pdsc->last_fw_time = jiffies; |
| 62 | 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 | 186 | int err; |
| 184 | 187 | |
| 188 | + if (!pdsc->cmd_regs) | |
| 189 | + return -ENXIO; | |
| 190 | + | |
| 185 | 191 | memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); |
| 186 | 192 | pdsc_devcmd_dbell(pdsc); |
| 187 | 193 | err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); |
| 188 | − memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); | |
| 189 | 194 | |
| 190 | 195 | if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) |
| 191 | 196 | queue_work(pdsc->wq, &pdsc->health_work); |
| 197 | + else | |
| 198 | + memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); | |
| 192 | 199 | |
| 193 | 200 | return err; |
| 194 | 201 | } |
| @@ -309,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc) · 114 unmodified lines | ||
| 309 | 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 | 319 | int pdsc_dev_init(struct pdsc *pdsc) |
| 320 | 320 | { |
| 321 | 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 | 112 | mutex_lock(&pdsc->devcmd_lock); |
| 113 | 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 | 116 | mutex_unlock(&pdsc->devcmd_lock); |
| 116 | 117 | if (err && err != -EIO) |
| 117 | 118 | return err; |
| @@ -107,6 +107,9 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw, · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | dev_info(pdsc->dev, "Installing firmware\n"); |
| 109 | 109 | |
| 110 | + if (!pdsc->cmd_regs) | |
| 111 | + return -ENXIO; | |
| 112 | + | |
| 110 | 113 | dl = priv_to_devlink(pdsc); |
| 111 | 114 | devlink_flash_update_status_notify(dl, "Preparing to flash", |
| 112 | 115 | NULL, 0, 0); |
| @@ -37,6 +37,11 @@ static void pdsc_unmap_bars(struct pdsc *pdsc) · 36 unmodified lines | ||
| 37 | 37 | struct pdsc_dev_bar *bars = pdsc->bars; |
| 38 | 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 | 45 | for (i = 0; i < PDS_CORE_BARS_MAX; i++) { |
| 41 | 46 | if (bars[i].vaddr) |
| 42 | 47 | pci_iounmap(pdsc->pdev, bars[i].vaddr); |
| @@ -293,7 +298,7 @@ err_out_stop: · 250 unmodified lines | ||
| 293 | 298 | err_out_teardown: |
| 294 | 299 | pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); |
| 295 | 300 | err_out_unmap_bars: |
| 296 | − del_timer_sync(&pdsc->wdtimer); | |
| 301 | + timer_shutdown_sync(&pdsc->wdtimer); | |
| 297 | 302 | if (pdsc->wq) |
| 298 | 303 | destroy_workqueue(pdsc->wq); |
| 299 | 304 | mutex_destroy(&pdsc->config_lock); |
| @@ -420,7 +425,7 @@ static void pdsc_remove(struct pci_dev *pdev) · 120 unmodified lines | ||
| 420 | 425 | */ |
| 421 | 426 | pdsc_sriov_configure(pdev, 0); |
| 422 | 427 | |
| 423 | − del_timer_sync(&pdsc->wdtimer); | |
| 428 | + timer_shutdown_sync(&pdsc->wdtimer); | |
| 424 | 429 | if (pdsc->wq) |
| 425 | 430 | destroy_workqueue(pdsc->wq); |
| 426 | 431 | |
| @@ -433,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev) · 6 unmodified lines | ||
| 433 | 438 | mutex_destroy(&pdsc->config_lock); |
| 434 | 439 | mutex_destroy(&pdsc->devcmd_lock); |
| 435 | 440 | |
| 436 | − pci_free_irq_vectors(pdev); | |
| 437 | 441 | pdsc_unmap_bars(pdsc); |
| 438 | 442 | pci_release_regions(pdev); |
| 439 | 443 | } |
| @@ -445,13 +449,26 @@ static void pdsc_remove(struct pci_dev *pdev) · 5 unmodified lines | ||
| 445 | 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 | 465 | void pdsc_reset_prepare(struct pci_dev *pdev) |
| 449 | 466 | { |
| 450 | 467 | struct pdsc *pdsc = pci_get_drvdata(pdev); |
| 451 | 468 | |
| 469 | + pdsc_stop_health_thread(pdsc); | |
| 452 | 470 | pdsc_fw_down(pdsc); |
| 453 | 471 | |
| 454 | − pci_free_irq_vectors(pdev); | |
| 455 | 472 | pdsc_unmap_bars(pdsc); |
| 456 | 473 | pci_release_regions(pdev); |
| 457 | 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 | 505 | pdsc_fw_up(pdsc); |
| 506 | + pdsc_restart_health_thread(pdsc); | |
| 489 | 507 | } |
| 490 | 508 | |
| 491 | 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 | 684 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 685 | 685 | skb_tstamp_tx(ptp->tx_skb, ×tamp); |
| 686 | 686 | } else { |
| 687 | − netdev_WARN_ONCE(bp->dev, | |
| 687 | + netdev_warn_once(bp->dev, | |
| 688 | 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 | 357 | static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, |
| 358 | 358 | struct gve_rx_slot_page_info *page_info, |
| 359 | − u16 packet_buffer_size, u16 len, | |
| 359 | + unsigned int truesize, u16 len, | |
| 360 | 360 | struct gve_rx_ctx *ctx) |
| 361 | 361 | { |
| 362 | 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 | 389 | if (skb != ctx->skb_head) { |
| 390 | 390 | ctx->skb_head->len += len; |
| 391 | 391 | ctx->skb_head->data_len += len; |
| 392 | − ctx->skb_head->truesize += packet_buffer_size; | |
| 392 | + ctx->skb_head->truesize += truesize; | |
| 393 | 393 | } |
| 394 | 394 | skb_add_rx_frag(skb, num_frags, page_info->page, |
| 395 | − offset, len, packet_buffer_size); | |
| 395 | + offset, len, truesize); | |
| 396 | 396 | |
| 397 | 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 | 487 | memcpy(alloc_page_info.page_address, src, page_info->pad + len); |
| 488 | 488 | skb = gve_rx_add_frags(napi, &alloc_page_info, |
| 489 | − rx->packet_buffer_size, | |
| 489 | + PAGE_SIZE, | |
| 490 | 490 | len, ctx); |
| 491 | 491 | |
| 492 | 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 | 360 | * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of |
| 361 | 361 | * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) |
| 362 | 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 | 380 | #define INCVALUE_96MHZ 125 |
| 365 | 381 | #define INCVALUE_SHIFT_96MHZ 17 |
| 366 | 382 | #define INCPERIOD_SHIFT_96MHZ 2 |
| 367 | 383 | #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) |
| 384 | +#define MAX_PPB_96MHZ 23999900 /* 23,999,900 ppb */ | |
| 368 | 385 | |
| 369 | 386 | #define INCVALUE_25MHZ 40 |
| 370 | 387 | #define INCVALUE_SHIFT_25MHZ 18 |
| 371 | 388 | #define INCPERIOD_25MHZ 1 |
| 389 | +#define MAX_PPB_25MHZ 599999900 /* 599,999,900 ppb */ | |
| 372 | 390 | |
| 373 | 391 | #define INCVALUE_24MHZ 125 |
| 374 | 392 | #define INCVALUE_SHIFT_24MHZ 14 |
| 375 | 393 | #define INCPERIOD_24MHZ 3 |
| 394 | +#define MAX_PPB_24MHZ 999999999 /* 999,999,999 ppb */ | |
| 376 | 395 | |
| 377 | 396 | #define INCVALUE_38400KHZ 26 |
| 378 | 397 | #define INCVALUE_SHIFT_38400KHZ 19 |
| 379 | 398 | #define INCPERIOD_38400KHZ 1 |
| 399 | +#define MAX_PPB_38400KHZ 230769100 /* 230,769,100 ppb */ | |
| 380 | 400 | |
| 381 | 401 | /* Another drawback of scaling the incvalue by a large factor is the |
| 382 | 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 | 281 | switch (hw->mac.type) { |
| 282 | 282 | case e1000_pch2lan: |
| 283 | + adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; | |
| 284 | + break; | |
| 283 | 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 | 291 | case e1000_pch_spt: |
| 292 | + adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; | |
| 293 | + break; | |
| 285 | 294 | case e1000_pch_cnp: |
| 286 | 295 | case e1000_pch_tgp: |
| 287 | 296 | case e1000_pch_adp: |
| @@ -289,15 +298,14 @@ void e1000e_ptp_init(struct e1000_adapter *adapter) · 1 unmodified line | ||
| 289 | 298 | case e1000_pch_lnp: |
| 290 | 299 | case e1000_pch_ptp: |
| 291 | 300 | case e1000_pch_nvp: |
| 292 | − if ((hw->mac.type < e1000_pch_lpt) || | |
| 293 | − (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) { | |
| 294 | − adapter->ptp_clock_info.max_adj = 24000000 - 1; | |
| 295 | − break; | |
| 296 | − } | |
| 297 | − fallthrough; | |
| 301 | + if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) | |
| 302 | + adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; | |
| 303 | + else | |
| 304 | + adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; | |
| 305 | + break; | |
| 298 | 306 | case e1000_82574: |
| 299 | 307 | case e1000_82583: |
| 300 | − adapter->ptp_clock_info.max_adj = 600000000 - 1; | |
| 308 | + adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; | |
| 301 | 309 | break; |
| 302 | 310 | default: |
| 303 | 311 | break; |
| @@ -978,7 +978,7 @@ struct virtchnl2_ptype { · 977 unmodified lines | ||
| 978 | 978 | u8 proto_id_count; |
| 979 | 979 | __le16 pad; |
| 980 | 980 | __le16 proto_id[]; |
| 981 | −}; | |
| 981 | +} __packed __aligned(2); | |
| 982 | 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 | 716 | if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) { |
| 717 | 717 | error = FIELD_GET(IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK, command); |
| 718 | 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 | 723 | if (!ret) |
| @@ -314,7 +314,6 @@ static int otx2_set_channels(struct net_device *dev, · 313 unmodified lines | ||
| 314 | 314 | pfvf->hw.tx_queues = channel->tx_count; |
| 315 | 315 | if (pfvf->xdp_prog) |
| 316 | 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 | 318 | if (if_up) |
| 320 | 319 | err = dev->netdev_ops->ndo_open(dev); |
| @@ -1744,6 +1744,7 @@ int otx2_open(struct net_device *netdev) · 1743 unmodified lines | ||
| 1744 | 1744 | /* RQ and SQs are mapped to different CQs, |
| 1745 | 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 | 1748 | pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, |
| 1748 | 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 | 2644 | xdp_features_clear_redirect_target(dev); |
| 2644 | 2645 | } |
| 2645 | 2646 | |
| 2646 | − pf->hw.non_qos_queues += pf->hw.xdp_queues; | |
| 2647 | − | |
| 2648 | 2647 | if (if_up) |
| 2649 | 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 | 1403 | struct otx2_cq_queue *cq, |
| 1404 | 1404 | bool *need_xdp_flush) |
| 1405 | 1405 | { |
| 1406 | − unsigned char *hard_start, *data; | |
| 1406 | + unsigned char *hard_start; | |
| 1407 | 1407 | int qidx = cq->cq_idx; |
| 1408 | 1408 | struct xdp_buff xdp; |
| 1409 | 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 | 1418 | xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); |
| 1419 | 1419 | |
| 1420 | − data = (unsigned char *)phys_to_virt(pa); | |
| 1421 | − hard_start = page_address(page); | |
| 1422 | − xdp_prepare_buff(&xdp, hard_start, data - hard_start, | |
| 1420 | + hard_start = (unsigned char *)phys_to_virt(pa); | |
| 1421 | + xdp_prepare_buff(&xdp, hard_start, OTX2_HEAD_ROOM, | |
| 1423 | 1422 | cqe->sg.seg_size, false); |
| 1424 | 1423 | |
| 1425 | 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 | 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 | 4768 | if (err) { |
| 4766 | 4769 | dev_err(&pdev->dev, "Wrong DMA config\n"); |
| 4767 | 4770 | return -EINVAL; |
| @@ -168,9 +168,10 @@ static void lan966x_port_link_up(struct lan966x_port *port) · 167 unmodified lines | ||
| 168 | 168 | lan966x_taprio_speed_set(port, config->speed); |
| 169 | 169 | |
| 170 | 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 | 175 | mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); |
| 175 | 176 | |
| 176 | 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 | 1424 | mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask); |
| 1425 | 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 | 1432 | case FLOW_ACT_MANGLE_HDR_TYPE_TCP: |
| 1428 | 1433 | case FLOW_ACT_MANGLE_HDR_TYPE_UDP: |
| 1429 | − mangle_action->mangle.val = (__force u16)cpu_to_be16(mangle_action->mangle.val); | |
| 1430 | − mangle_action->mangle.mask = (__force u16)cpu_to_be16(mangle_action->mangle.mask); | |
| 1434 | + if (mangle_action->mangle.offset == offsetof(struct tcphdr, source)) { | |
| 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 | 1451 | return; |
| 1432 | 1452 | |
| 1433 | 1453 | default: |
| @@ -1864,10 +1884,30 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv, · 430 unmodified lines | ||
| 1864 | 1884 | { |
| 1865 | 1885 | struct flow_rule *rule = flow_cls_offload_flow_rule(flow); |
| 1866 | 1886 | struct nfp_fl_ct_flow_entry *ct_entry; |
| 1887 | + struct flow_action_entry *ct_goto; | |
| 1867 | 1888 | struct nfp_fl_ct_zone_entry *zt; |
| 1889 | + struct flow_action_entry *act; | |
| 1868 | 1890 | bool wildcarded = false; |
| 1869 | 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 | 1912 | flow_rule_match_ct(rule, &ct); |
| 1873 | 1913 | if (!ct.mask->ct_zone) { |
| @@ -353,6 +353,10 @@ static int imx_dwmac_probe(struct platform_device *pdev) · 352 unmodified lines | ||
| 353 | 353 | if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) |
| 354 | 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 | 360 | plat_dat->host_dma_width = dwmac->ops->addr_width; |
| 357 | 361 | plat_dat->init = imx_dwmac_init; |
| 358 | 362 | plat_dat->exit = imx_dwmac_exit; |
| @@ -3932,6 +3932,9 @@ static int __stmmac_open(struct net_device *dev, · 3931 unmodified lines | ||
| 3932 | 3932 | priv->rx_copybreak = STMMAC_RX_COPYBREAK; |
| 3933 | 3933 | |
| 3934 | 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 | 3938 | memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); |
| 3936 | 3939 | |
| 3937 | 3940 | stmmac_reset_queues_param(priv); |
| @@ -708,7 +708,10 @@ void netvsc_device_remove(struct hv_device *device) · 707 unmodified lines | ||
| 708 | 708 | /* Disable NAPI and disassociate its context from the device. */ |
| 709 | 709 | for (i = 0; i < net_device->num_chn; i++) { |
| 710 | 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 | 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 | 489 | u16 reg, val; |
| 490 | 490 | |
| 491 | 491 | if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) |
| 492 | − bias = -2; | |
| 492 | + bias = -1; | |
| 493 | 493 | |
| 494 | 494 | val = clamp_val(bias + tx_r50_cal_val, 0, 63); |
| 495 | 495 | |
| @@ -705,6 +705,11 @@ restore: · 209 unmodified lines | ||
| 705 | 705 | static void mt798x_phy_common_finetune(struct phy_device *phydev) |
| 706 | 706 | { |
| 707 | 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 | 713 | /* EnabRandUpdTrig = 1 */ |
| 709 | 714 | __phy_write(phydev, 0x11, 0x2f00); |
| 710 | 715 | __phy_write(phydev, 0x12, 0xe); |
| @@ -715,15 +720,56 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 4 unmodified lines | ||
| 715 | 720 | __phy_write(phydev, 0x12, 0x0); |
| 716 | 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 | 729 | __phy_write(phydev, 0x11, 0x0); |
| 720 | 730 | __phy_write(phydev, 0x12, 0x0); |
| 721 | 731 | __phy_write(phydev, 0x10, 0x9686); |
| 722 | 732 | |
| 733 | + /* SSTrKp100 = 5 */ | |
| 734 | + /* SSTrKf100 = 6 */ | |
| 735 | + /* SSTrKp1000Mas = 5 */ | |
| 736 | + /* SSTrKf1000Mas = 6 */ | |
| 723 | 737 | /* SSTrKp1000Slv = 5 */ |
| 738 | + /* SSTrKf1000Slv = 6 */ | |
| 724 | 739 | __phy_write(phydev, 0x11, 0xbaef); |
| 725 | 740 | __phy_write(phydev, 0x12, 0x2e); |
| 726 | 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 | 774 | /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, |
| 729 | 775 | * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 |
| @@ -738,7 +784,7 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) · 8 unmodified lines | ||
| 738 | 784 | __phy_write(phydev, 0x10, 0x8ec0); |
| 739 | 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 | 788 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, |
| 743 | 789 | MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, |
| 744 | 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 | 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 | 820 | static void mt7988_phy_finetune(struct phy_device *phydev) |
| 817 | 821 | { |
| 818 | 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 | 831 | /* TCT finetune */ |
| 828 | 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 | 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 | 835 | /* ResetSyncOffset = 5 */ |
| 842 | 836 | __phy_write(phydev, 0x11, 0x500); |
| 843 | 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 | 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 | 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 | 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 | 892 | MTK_PHY_LPI_SLV_SEND_TX_EN, |
| 885 | 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, | |
| 888 | − MTK_PHY_LPI_SEND_LOC_TIMER_MASK | | |
| 889 | − MTK_PHY_LPI_TXPCS_LOC_RCV, | |
| 890 | − FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); | |
| 895 | + /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ | |
| 896 | + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, | |
| 897 | + MTK_PHY_LPI_TXPCS_LOC_RCV); | |
| 891 | 898 | |
| 899 | + /* This also fixes some IoT issues, such as CH340 */ | |
| 892 | 900 | phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, |
| 893 | 901 | MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, |
| 894 | 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 | 930 | __phy_write(phydev, 0x12, 0x0); |
| 923 | 931 | __phy_write(phydev, 0x10, 0x9690); |
| 924 | 932 | |
| 925 | − /* REG_EEE_st2TrKf1000 = 3 */ | |
| 933 | + /* REG_EEE_st2TrKf1000 = 2 */ | |
| 926 | 934 | __phy_write(phydev, 0x11, 0x114f); |
| 927 | 935 | __phy_write(phydev, 0x12, 0x2); |
| 928 | 936 | __phy_write(phydev, 0x10, 0x969a); |
| @@ -947,7 +955,7 @@ static void mt798x_phy_eee(struct phy_device *phydev) · 18 unmodified lines | ||
| 947 | 955 | __phy_write(phydev, 0x12, 0x0); |
| 948 | 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 | 959 | __phy_write(phydev, 0x11, 0x1463); |
| 952 | 960 | __phy_write(phydev, 0x12, 0x0); |
| 953 | 961 | __phy_write(phydev, 0x10, 0x96ca); |
| @@ -1459,6 +1467,13 @@ static int mt7988_phy_probe(struct phy_device *phydev) · 505 unmodified lines | ||
| 1459 | 1467 | if (err) |
| 1460 | 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 | 1477 | return mt798x_phy_calibration(phydev); |
| 1463 | 1478 | } |
| 1464 | 1479 | |
| @@ -104,13 +104,12 @@ bool provides_xdp_headroom = true; · 103 unmodified lines | ||
| 104 | 104 | module_param(provides_xdp_headroom, bool, 0644); |
| 105 | 105 | |
| 106 | 106 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, |
| 107 | − u8 status); | |
| 107 | + s8 status); | |
| 108 | 108 | |
| 109 | 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 | 111 | unsigned int extra_count, |
| 112 | − s8 st); | |
| 113 | −static void push_tx_responses(struct xenvif_queue *queue); | |
| 112 | + s8 status); | |
| 114 | 113 | |
| 115 | 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 | 207 | unsigned int extra_count, RING_IDX end) |
| 209 | 208 | { |
| 210 | 209 | RING_IDX cons = queue->tx.req_cons; |
| 211 | − unsigned long flags; | |
| 212 | 210 | |
| 213 | 211 | do { |
| 214 | − spin_lock_irqsave(&queue->response_lock, flags); | |
| 215 | 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 | 213 | if (cons == end) |
| 219 | 214 | break; |
| 220 | 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 | 460 | for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; |
| 466 | 461 | nr_slots--) { |
| 467 | 462 | if (unlikely(!txp->size)) { |
| 468 | − unsigned long flags; | |
| 469 | − | |
| 470 | − spin_lock_irqsave(&queue->response_lock, flags); | |
| 471 | 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 | 464 | ++txp; |
| 475 | 465 | continue; |
| 476 | 466 | } |
| @@ -496,14 +486,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, · 19 unmodified lines | ||
| 496 | 486 | |
| 497 | 487 | for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { |
| 498 | 488 | if (unlikely(!txp->size)) { |
| 499 | − unsigned long flags; | |
| 500 | − | |
| 501 | − spin_lock_irqsave(&queue->response_lock, flags); | |
| 502 | 489 | make_tx_response(queue, txp, 0, |
| 503 | 490 | XEN_NETIF_RSP_OKAY); |
| 504 | − push_tx_responses(queue); | |
| 505 | − spin_unlock_irqrestore(&queue->response_lock, | |
| 506 | − flags); | |
| 507 | 491 | continue; |
| 508 | 492 | } |
| 509 | 493 | |
| @@ -995,7 +979,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 485 unmodified lines | ||
| 995 | 979 | (ret == 0) ? |
| 996 | 980 | XEN_NETIF_RSP_OKAY : |
| 997 | 981 | XEN_NETIF_RSP_ERROR); |
| 998 | − push_tx_responses(queue); | |
| 999 | 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 | 991 | make_tx_response(queue, &txreq, extra_count, |
| 1009 | 992 | XEN_NETIF_RSP_OKAY); |
| 1010 | − push_tx_responses(queue); | |
| 1011 | 993 | continue; |
| 1012 | 994 | } |
| 1013 | 995 | |
| @@ -1433,8 +1415,35 @@ int xenvif_tx_action(struct xenvif_queue *queue, int budget) · 419 unmodified lines | ||
| 1433 | 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 | 1445 | static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, |
| 1437 | − u8 status) | |
| 1446 | + s8 status) | |
| 1438 | 1447 | { |
| 1439 | 1448 | struct pending_tx_info *pending_tx_info; |
| 1440 | 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 | 1454 | spin_lock_irqsave(&queue->response_lock, flags); |
| 1446 | 1455 | |
| 1447 | − make_tx_response(queue, &pending_tx_info->req, | |
| 1448 | − pending_tx_info->extra_count, status); | |
| 1456 | + _make_tx_response(queue, &pending_tx_info->req, | |
| 1457 | + pending_tx_info->extra_count, status); | |
| 1449 | 1458 | |
| 1450 | 1459 | /* Release the pending index before pusing the Tx response so |
| 1451 | 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 | 1468 | spin_unlock_irqrestore(&queue->response_lock, flags); |
| 1460 | 1469 | } |
| 1461 | 1470 | |
| 1462 | − | |
| 1463 | 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 | 1473 | unsigned int extra_count, |
| 1466 | − s8 st) | |
| 1474 | + s8 status) | |
| 1467 | 1475 | { |
| 1468 | − RING_IDX i = queue->tx.rsp_prod_pvt; | |
| 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; | |
| 1476 | + unsigned long flags; | |
| 1477 | 1477 | |
| 1478 | − queue->tx.rsp_prod_pvt = ++i; | |
| 1479 | −} | |
| 1478 | + spin_lock_irqsave(&queue->response_lock, flags); | |
| 1480 | 1479 | |
| 1481 | −static void push_tx_responses(struct xenvif_queue *queue) | |
| 1482 | −{ | |
| 1483 | − int notify; | |
| 1480 | + _make_tx_response(queue, txp, extra_count, status); | |
| 1481 | + push_tx_responses(queue); | |
| 1484 | 1482 | |
| 1485 | − RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); | |
| 1486 | − if (notify) | |
| 1487 | − notify_remote_via_irq(queue->tx_irq); | |
| 1483 | + spin_unlock_irqrestore(&queue->response_lock, flags); | |
| 1488 | 1484 | } |
| 1489 | 1485 | |
| 1490 | 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 | 186 | /* Return true if "b" set is the same as "a" |
| 187 | 187 | * according to the create set parameters */ |
| 188 | 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 | 191 | /* Region-locking is used */ |
| 190 | 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 | 245 | /* A generic IP set */ |
| 244 | 246 | struct ip_set { |
| 247 | + /* For call_cru in destroy */ | |
| 248 | + struct rcu_head rcu; | |
| 245 | 249 | /* The name of the set */ |
| 246 | 250 | char name[IPSET_MAXNAMELEN]; |
| 247 | 251 | /* Lock protecting the set data */ |
| @@ -46,12 +46,6 @@ struct scm_stat { · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 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 | 49 | /* The AF_UNIX socket */ |
| 56 | 50 | struct unix_sock { |
| 57 | 51 | /* WARNING: sk has to be the first member */ |
| @@ -77,6 +71,20 @@ struct unix_sock { · 19 unmodified lines | ||
| 77 | 71 | #define unix_sk(ptr) container_of_const(ptr, struct unix_sock, sk) |
| 78 | 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 | 88 | #define peer_wait peer_wq.wait |
| 81 | 89 | |
| 82 | 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 | 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 | 771 | void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, |
| 772 | 772 | struct sk_buff *skb, int tlen, int offset); |
| 773 | 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 | 1351 | * @type: stateful object numeric type |
| 1352 | 1352 | * @owner: module owner |
| 1353 | 1353 | * @maxattr: maximum netlink attribute |
| 1354 | + * @family: address family for AF-specific object types | |
| 1354 | 1355 | * @policy: netlink attribute policy |
| 1355 | 1356 | */ |
| 1356 | 1357 | struct nft_object_type { |
| @@ -1360,6 +1361,7 @@ struct nft_object_type { · 3 unmodified lines | ||
| 1360 | 1361 | struct list_head list; |
| 1361 | 1362 | u32 type; |
| 1362 | 1363 | unsigned int maxattr; |
| 1364 | + u8 family; | |
| 1363 | 1365 | struct module *owner; |
| 1364 | 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 | 2175 | cancel_delayed_work_sync(&bat_priv->mcast.work); |
| 2176 | 2176 | |
| 2177 | 2177 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2); |
| 2178 | + batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST_TRACKER, 1); | |
| 2178 | 2179 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2); |
| 2179 | 2180 | |
| 2180 | 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 | 2199 | BATADV_MCAST_WANT_NO_RTR4); |
| 2199 | 2200 | batadv_mcast_want_rtr6_update(bat_priv, orig, |
| 2200 | 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 | 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 | 1763 | #endif |
| 1764 | 1764 | |
| 1765 | +static void br_multicast_query_delay_expired(struct timer_list *t) | |
| 1766 | +{ | |
| 1767 | +} | |
| 1768 | + | |
| 1765 | 1769 | static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx, |
| 1766 | 1770 | struct br_ip *ip, |
| 1767 | 1771 | struct sk_buff *skb) |
| @@ -3198,7 +3202,7 @@ br_multicast_update_query_timer(struct net_bridge_mcast *brmctx, · 1430 unmodified lines | ||
| 3198 | 3202 | unsigned long max_delay) |
| 3199 | 3203 | { |
| 3200 | 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 | 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 | 4045 | brmctx->multicast_querier_interval = 255 * HZ; |
| 4042 | 4046 | brmctx->multicast_membership_interval = 260 * HZ; |
| 4043 | 4047 | |
| 4044 | − brmctx->ip4_other_query.delay_time = 0; | |
| 4045 | 4048 | brmctx->ip4_querier.port_ifidx = 0; |
| 4046 | 4049 | seqcount_spinlock_init(&brmctx->ip4_querier.seq, &br->multicast_lock); |
| 4047 | 4050 | brmctx->multicast_igmp_version = 2; |
| 4048 | 4051 | #if IS_ENABLED(CONFIG_IPV6) |
| 4049 | 4052 | brmctx->multicast_mld_version = 1; |
| 4050 | − brmctx->ip6_other_query.delay_time = 0; | |
| 4051 | 4053 | brmctx->ip6_querier.port_ifidx = 0; |
| 4052 | 4054 | seqcount_spinlock_init(&brmctx->ip6_querier.seq, &br->multicast_lock); |
| 4053 | 4055 | #endif |
| @@ -4056,6 +4058,8 @@ void br_multicast_ctx_init(struct net_bridge *br, · 2 unmodified lines | ||
| 4056 | 4058 | br_ip4_multicast_local_router_expired, 0); |
| 4057 | 4059 | timer_setup(&brmctx->ip4_other_query.timer, |
| 4058 | 4060 | br_ip4_multicast_querier_expired, 0); |
| 4061 | + timer_setup(&brmctx->ip4_other_query.delay_timer, | |
| 4062 | + br_multicast_query_delay_expired, 0); | |
| 4059 | 4063 | timer_setup(&brmctx->ip4_own_query.timer, |
| 4060 | 4064 | br_ip4_multicast_query_expired, 0); |
| 4061 | 4065 | #if IS_ENABLED(CONFIG_IPV6) |
| @@ -4063,6 +4067,8 @@ void br_multicast_ctx_init(struct net_bridge *br, · 1 unmodified line | ||
| 4063 | 4067 | br_ip6_multicast_local_router_expired, 0); |
| 4064 | 4068 | timer_setup(&brmctx->ip6_other_query.timer, |
| 4065 | 4069 | br_ip6_multicast_querier_expired, 0); |
| 4070 | + timer_setup(&brmctx->ip6_other_query.delay_timer, | |
| 4071 | + br_multicast_query_delay_expired, 0); | |
| 4066 | 4072 | timer_setup(&brmctx->ip6_own_query.timer, |
| 4067 | 4073 | br_ip6_multicast_query_expired, 0); |
| 4068 | 4074 | #endif |
| @@ -4197,10 +4203,12 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx) · 128 unmodified lines | ||
| 4197 | 4203 | { |
| 4198 | 4204 | del_timer_sync(&brmctx->ip4_mc_router_timer); |
| 4199 | 4205 | del_timer_sync(&brmctx->ip4_other_query.timer); |
| 4206 | + del_timer_sync(&brmctx->ip4_other_query.delay_timer); | |
| 4200 | 4207 | del_timer_sync(&brmctx->ip4_own_query.timer); |
| 4201 | 4208 | #if IS_ENABLED(CONFIG_IPV6) |
| 4202 | 4209 | del_timer_sync(&brmctx->ip6_mc_router_timer); |
| 4203 | 4210 | del_timer_sync(&brmctx->ip6_other_query.timer); |
| 4211 | + del_timer_sync(&brmctx->ip6_other_query.delay_timer); | |
| 4204 | 4212 | del_timer_sync(&brmctx->ip6_own_query.timer); |
| 4205 | 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 | 4651 | max_delay = brmctx->multicast_query_response_interval; |
| 4644 | 4652 | |
| 4645 | 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 | 4657 | br_multicast_start_querier(brmctx, &brmctx->ip4_own_query); |
| 4649 | 4658 | |
| 4650 | 4659 | #if IS_ENABLED(CONFIG_IPV6) |
| 4651 | 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 | 4664 | br_multicast_start_querier(brmctx, &brmctx->ip6_own_query); |
| 4655 | 4665 | #endif |
| @@ -78,7 +78,7 @@ struct bridge_mcast_own_query { · 77 unmodified lines | ||
| 78 | 78 | /* other querier */ |
| 79 | 79 | struct bridge_mcast_other_query { |
| 80 | 80 | struct timer_list timer; |
| 81 | − unsigned long delay_time; | |
| 81 | + struct timer_list delay_timer; | |
| 82 | 82 | }; |
| 83 | 83 | |
| 84 | 84 | /* selected querier */ |
| @@ -1159,7 +1159,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx, · 1074 unmodified lines | ||
| 1159 | 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 | 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 | 674 | return -EOPNOTSUPP; |
| 675 | 675 | } |
| 676 | 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 | 678 | "Function does not support state setting"); |
| 679 | 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 | 309 | skb = hsr_init_skb(master); |
| 310 | 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 | 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 | 356 | skb = hsr_init_skb(master); |
| 357 | 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 | 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 | 1287 | if (unlikely(!rt)) |
| 1288 | 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 | 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 | 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 | 1312 | cork->gso_size = ipc->gso_size; |
| 1313 | 1313 | |
| 1314 | 1314 | cork->dst = &rt->dst; |
| @@ -1363,12 +1363,13 @@ e_inval: · 1362 unmodified lines | ||
| 1363 | 1363 | * ipv4_pktinfo_prepare - transfer some info from rtable to skb |
| 1364 | 1364 | * @sk: socket |
| 1365 | 1365 | * @skb: buffer |
| 1366 | + * @drop_dst: if true, drops skb dst | |
| 1366 | 1367 | * |
| 1367 | 1368 | * To support IP_CMSG_PKTINFO option, we store rt_iif and specific |
| 1368 | 1369 | * destination in skb->cb[] before dst drop. |
| 1369 | 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 | 1374 | struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb); |
| 1374 | 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 | 1398 | pktinfo->ipi_ifindex = 0; |
| 1398 | 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 | 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 | 1073 | msg = (struct igmpmsg *)skb_network_header(skb); |
| 1074 | 1074 | msg->im_vif = vifi; |
| 1075 | 1075 | msg->im_vif_hi = vifi >> 8; |
| 1076 | − ipv4_pktinfo_prepare(mroute_sk, pkt); | |
| 1076 | + ipv4_pktinfo_prepare(mroute_sk, pkt, false); | |
| 1077 | 1077 | memcpy(skb->cb, pkt->cb, sizeof(skb->cb)); |
| 1078 | 1078 | /* Add our header */ |
| 1079 | 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 | 293 | /* Charge it to the socket. */ |
| 294 | 294 | |
| 295 | − ipv4_pktinfo_prepare(sk, skb); | |
| 295 | + ipv4_pktinfo_prepare(sk, skb, true); | |
| 296 | 296 | if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) { |
| 297 | 297 | kfree_skb_reason(skb, reason); |
| 298 | 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 | 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 | 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 | 2170 | udp_csum_pull_header(skb); |
| 2171 | 2171 | |
| 2172 | − ipv4_pktinfo_prepare(sk, skb); | |
| 2172 | + ipv4_pktinfo_prepare(sk, skb, true); | |
| 2173 | 2173 | return __udp_queue_rcv_skb(sk, skb); |
| 2174 | 2174 | |
| 2175 | 2175 | csum_error: |
| @@ -220,19 +220,26 @@ const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) { · 219 unmodified lines | ||
| 220 | 220 | EXPORT_SYMBOL_GPL(ipv6_stub); |
| 221 | 221 | |
| 222 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 243 | EXPORT_SYMBOL(in6addr_sitelocal_allrouters); |
| 237 | 244 | |
| 238 | 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 | 796 | struct sk_buff *skb), |
| 797 | 797 | bool log_ecn_err) |
| 798 | 798 | { |
| 799 | − const struct ipv6hdr *ipv6h = ipv6_hdr(skb); | |
| 800 | − int err; | |
| 799 | + const struct ipv6hdr *ipv6h; | |
| 800 | + int nh, err; | |
| 801 | 801 | |
| 802 | 802 | if ((!(tpi->flags & TUNNEL_CSUM) && |
| 803 | 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 | 829 | goto drop; |
| 830 | 830 | } |
| 831 | 831 | |
| 832 | − ipv6h = ipv6_hdr(skb); | |
| 833 | 832 | skb->protocol = eth_type_trans(skb, tunnel->dev); |
| 834 | 833 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
| 835 | 834 | } else { |
| @@ -837,7 +836,23 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, · 1 unmodified line | ||
| 837 | 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 | 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 | 856 | memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); |
| 842 | 857 | |
| 843 | 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 | 227 | netdev_put(llc->dev, &llc->dev_tracker); |
| 228 | 228 | sock_put(sk); |
| 229 | + sock_orphan(sk); | |
| 230 | + sock->sk = NULL; | |
| 229 | 231 | llc_sk_free(sk); |
| 230 | 232 | out: |
| 231 | 233 | return 0; |
| @@ -2314,9 +2314,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) · 2313 unmodified lines | ||
| 2314 | 2314 | if (__mptcp_check_fallback(msk)) |
| 2315 | 2315 | return false; |
| 2316 | 2316 | |
| 2317 | − if (tcp_rtx_and_write_queues_empty(sk)) | |
| 2318 | − return false; | |
| 2319 | − | |
| 2320 | 2317 | /* the closing socket has some data untransmitted and/or unacked: |
| 2321 | 2318 | * some data in the mptcp rtx queue has not really xmitted yet. |
| 2322 | 2319 | * keep it simple and re-inject the whole mptcp level rtx queue |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define mtype_del IPSET_TOKEN(MTYPE, _del) |
| 31 | 31 | #define mtype_list IPSET_TOKEN(MTYPE, _list) |
| 32 | 32 | #define mtype_gc IPSET_TOKEN(MTYPE, _gc) |
| 33 | +#define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc) | |
| 33 | 34 | #define mtype MTYPE |
| 34 | 35 | |
| 35 | 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 | 61 | struct mtype *map = set->data; |
| 61 | 62 | |
| 62 | − if (SET_WITH_TIMEOUT(set)) | |
| 63 | − del_timer_sync(&map->gc); | |
| 64 | − | |
| 65 | 63 | if (set->dsize && set->extensions & IPSET_EXT_DESTROY) |
| 66 | 64 | mtype_ext_cleanup(set); |
| 67 | 65 | ip_set_free(map->members); |
| @@ -290,6 +288,15 @@ mtype_gc(struct timer_list *t) · 222 unmodified lines | ||
| 290 | 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 | 300 | static const struct ip_set_type_variant mtype = { |
| 294 | 301 | .kadt = mtype_kadt, |
| 295 | 302 | .uadt = mtype_uadt, |
| @@ -303,6 +310,7 @@ static const struct ip_set_type_variant mtype = { · 7 unmodified lines | ||
| 303 | 310 | .head = mtype_head, |
| 304 | 311 | .list = mtype_list, |
| 305 | 312 | .same_set = mtype_same_set, |
| 313 | + .cancel_gc = mtype_cancel_gc, | |
| 306 | 314 | }; |
| 307 | 315 | |
| 308 | 316 | #endif /* __IP_SET_BITMAP_IP_GEN_H */ |
| @@ -1182,6 +1182,14 @@ ip_set_destroy_set(struct ip_set *set) · 1181 unmodified lines | ||
| 1182 | 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 | 1193 | static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, |
| 1186 | 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 | 1201 | if (unlikely(protocol_min_failed(attr))) |
| 1194 | 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 | 1205 | /* Commands are serialized and references are |
| 1200 | 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 | 1212 | * counter, so if it's already zero, we can proceed |
| 1207 | 1213 | * without holding the lock. |
| 1208 | 1214 | */ |
| 1209 | − read_lock_bh(&ip_set_ref_lock); | |
| 1210 | 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 | 1219 | for (i = 0; i < inst->ip_set_max; i++) { |
| 1212 | 1220 | s = ip_set(inst, i); |
| 1213 | 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 | 1229 | s = ip_set(inst, i); |
| 1222 | 1230 | if (s) { |
| 1223 | 1231 | ip_set(inst, i) = NULL; |
| 1232 | + /* Must cancel garbage collectors */ | |
| 1233 | + s->variant->cancel_gc(s); | |
| 1224 | 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 | 1238 | inst->is_destroyed = false; |
| 1229 | 1239 | } else { |
| 1230 | 1240 | u32 flags = flag_exist(info->nlh); |
| 1241 | + u16 features = 0; | |
| 1242 | + | |
| 1243 | + read_lock_bh(&ip_set_ref_lock); | |
| 1231 | 1244 | s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]), |
| 1232 | 1245 | &i); |
| 1233 | 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 | 1251 | ret = -IPSET_ERR_BUSY; |
| 1239 | 1252 | goto out; |
| 1240 | 1253 | } |
| 1254 | + features = s->type->features; | |
| 1241 | 1255 | ip_set(inst, i) = NULL; |
| 1242 | 1256 | read_unlock_bh(&ip_set_ref_lock); |
| 1243 | − | |
| 1244 | − ip_set_destroy_set(s); | |
| 1257 | + if (features & IPSET_TYPE_NAME) { | |
| 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 | 1265 | return 0; |
| 1247 | 1266 | out: |
| @@ -1394,9 +1413,6 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info, · 146 unmodified lines | ||
| 1394 | 1413 | ip_set(inst, to_id) = from; |
| 1395 | 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 | 1416 | return 0; |
| 1401 | 1417 | } |
| 1402 | 1418 | |
| @@ -2409,8 +2425,11 @@ ip_set_fini(void) · 1006 unmodified lines | ||
| 2409 | 2425 | { |
| 2410 | 2426 | nf_unregister_sockopt(&so_set); |
| 2411 | 2427 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); |
| 2412 | − | |
| 2413 | 2428 | unregister_pernet_subsys(&ip_set_net_ops); |
| 2429 | + | |
| 2430 | + /* Wait for call_rcu() in destroy */ | |
| 2431 | + rcu_barrier(); | |
| 2432 | + | |
| 2414 | 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 | 222 | #undef mtype_gc_do |
| 223 | 223 | #undef mtype_gc |
| 224 | 224 | #undef mtype_gc_init |
| 225 | +#undef mtype_cancel_gc | |
| 225 | 226 | #undef mtype_variant |
| 226 | 227 | #undef mtype_data_match |
| 227 | 228 | |
| @@ -266,6 +267,7 @@ static const union nf_inet_addr zeromask = {}; · 38 unmodified lines | ||
| 266 | 267 | #define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do) |
| 267 | 268 | #define mtype_gc IPSET_TOKEN(MTYPE, _gc) |
| 268 | 269 | #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) |
| 270 | +#define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc) | |
| 269 | 271 | #define mtype_variant IPSET_TOKEN(MTYPE, _variant) |
| 270 | 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 | 452 | struct htype *h = set->data; |
| 451 | 453 | struct list_head *l, *lt; |
| 452 | 454 | |
| 453 | − if (SET_WITH_TIMEOUT(set)) | |
| 454 | − cancel_delayed_work_sync(&h->gc.dwork); | |
| 455 | − | |
| 456 | 455 | mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true); |
| 457 | 456 | list_for_each_safe(l, lt, &h->ad) { |
| 458 | 457 | list_del(l); |
| @@ -599,6 +598,15 @@ mtype_gc_init(struct htable_gc *gc) · 140 unmodified lines | ||
| 599 | 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 | 610 | static int |
| 603 | 611 | mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, |
| 604 | 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 | 1449 | .uref = mtype_uref, |
| 1442 | 1450 | .resize = mtype_resize, |
| 1443 | 1451 | .same_set = mtype_same_set, |
| 1452 | + .cancel_gc = mtype_cancel_gc, | |
| 1444 | 1453 | .region_lock = true, |
| 1445 | 1454 | }; |
| 1446 | 1455 | |
| @@ -426,9 +426,6 @@ list_set_destroy(struct ip_set *set) · 425 unmodified lines | ||
| 426 | 426 | struct list_set *map = set->data; |
| 427 | 427 | struct set_elem *e, *n; |
| 428 | 428 | |
| 429 | − if (SET_WITH_TIMEOUT(set)) | |
| 430 | − timer_shutdown_sync(&map->gc); | |
| 431 | − | |
| 432 | 429 | list_for_each_entry_safe(e, n, &map->members, list) { |
| 433 | 430 | list_del(&e->list); |
| 434 | 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 | 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 | 554 | static const struct ip_set_type_variant set_variant = { |
| 549 | 555 | .kadt = list_set_kadt, |
| 550 | 556 | .uadt = list_set_uadt, |
| @@ -558,6 +564,7 @@ static const struct ip_set_type_variant set_variant = { · 7 unmodified lines | ||
| 558 | 564 | .head = list_set_head, |
| 559 | 565 | .list = list_set_list, |
| 560 | 566 | .same_set = list_set_same_set, |
| 567 | + .cancel_gc = list_set_cancel_gc, | |
| 561 | 568 | }; |
| 562 | 569 | |
| 563 | 570 | static void |
| @@ -283,7 +283,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb, · 282 unmodified lines | ||
| 283 | 283 | pr_debug("Setting vtag %x for secondary conntrack\n", |
| 284 | 284 | sh->vtag); |
| 285 | 285 | ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag; |
| 286 | − } else { | |
| 286 | + } else if (sch->type == SCTP_CID_SHUTDOWN_ACK) { | |
| 287 | 287 | /* If it is a shutdown ack OOTB packet, we expect a return |
| 288 | 288 | shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ |
| 289 | 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 | 457 | const struct sk_buff *skb, |
| 458 | 458 | unsigned int dataoff, |
| 459 | 459 | const struct tcphdr *tcph, |
| 460 | − u32 end, u32 win) | |
| 460 | + u32 end, u32 win, | |
| 461 | + enum ip_conntrack_dir dir) | |
| 461 | 462 | { |
| 462 | 463 | /* SYN-ACK in reply to a SYN |
| 463 | 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 | 472 | * Both sides must send the Window Scale option |
| 472 | 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 | 477 | receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) { |
| 476 | 478 | sender->td_scale = 0; |
| 477 | 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 | 544 | if (tcph->syn) { |
| 543 | 545 | tcp_init_sender(sender, receiver, |
| 544 | 546 | skb, dataoff, tcph, |
| 545 | − end, win); | |
| 547 | + end, win, dir); | |
| 546 | 548 | if (!tcph->ack) |
| 547 | 549 | /* Simultaneous open */ |
| 548 | 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 | 588 | tcp_init_sender(sender, receiver, |
| 587 | 589 | skb, dataoff, tcph, |
| 588 | − end, win); | |
| 590 | + end, win, dir); | |
| 589 | 591 | |
| 590 | 592 | if (dir == IP_CT_DIR_REPLY && !tcph->ack) |
| 591 | 593 | return NFCT_TCP_ACCEPT; |
| @@ -193,11 +193,12 @@ void nf_logger_put(int pf, enum nf_log_type type) · 192 unmodified lines | ||
| 193 | 193 | return; |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | − BUG_ON(loggers[pf][type] == NULL); | |
| 197 | − | |
| 198 | 196 | rcu_read_lock(); |
| 199 | 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 | 202 | rcu_read_unlock(); |
| 202 | 203 | } |
| 203 | 204 | EXPORT_SYMBOL_GPL(nf_logger_put); |
| @@ -7551,11 +7551,15 @@ nla_put_failure: · 7550 unmodified lines | ||
| 7551 | 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 | 7556 | const struct nft_object_type *type; |
| 7557 | 7557 | |
| 7558 | 7558 | list_for_each_entry(type, &nf_tables_objects, list) { |
| 7559 | + if (type->family != NFPROTO_UNSPEC && | |
| 7560 | + type->family != family) | |
| 7561 | + continue; | |
| 7562 | + | |
| 7559 | 7563 | if (objtype == type->type) |
| 7560 | 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 | 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 | 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 | 7575 | if (type != NULL && try_module_get(type->owner)) |
| 7572 | 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 | 7664 | if (info->nlh->nlmsg_flags & NLM_F_REPLACE) |
| 7661 | 7665 | return -EOPNOTSUPP; |
| 7662 | 7666 | |
| 7663 | − type = __nft_obj_type_get(objtype); | |
| 7667 | + type = __nft_obj_type_get(objtype, family); | |
| 7664 | 7668 | if (WARN_ON_ONCE(!type)) |
| 7665 | 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 | 7678 | if (!nft_use_inc(&table->use)) |
| 7675 | 7679 | return -EMFILE; |
| 7676 | 7680 | |
| 7677 | − type = nft_obj_type_get(net, objtype); | |
| 7681 | + type = nft_obj_type_get(net, objtype, family); | |
| 7678 | 7682 | if (IS_ERR(type)) { |
| 7679 | 7683 | err = PTR_ERR(type); |
| 7680 | 7684 | goto err_type; |
| @@ -1250,7 +1250,31 @@ static int nft_ct_expect_obj_init(const struct nft_ctx *ctx, · 1249 unmodified lines | ||
| 1250 | 1250 | if (tb[NFTA_CT_EXPECT_L3PROTO]) |
| 1251 | 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 | 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 | 1278 | priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]); |
| 1255 | 1279 | priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]); |
| 1256 | 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 | 714 | static struct nft_object_type nft_tunnel_obj_type __read_mostly = { |
| 715 | 715 | .type = NFT_OBJECT_TUNNEL, |
| 716 | + .family = NFPROTO_NETDEV, | |
| 716 | 717 | .ops = &nft_tunnel_obj_ops, |
| 717 | 718 | .maxattr = NFTA_TUNNEL_KEY_MAX, |
| 718 | 719 | .policy = nft_tunnel_key_policy, |
| @@ -1208,6 +1208,10 @@ void nci_free_device(struct nci_dev *ndev) · 1207 unmodified lines | ||
| 1208 | 1208 | { |
| 1209 | 1209 | nfc_free_device(ndev->nfc_dev); |
| 1210 | 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 | 1215 | kfree(ndev); |
| 1212 | 1216 | } |
| 1213 | 1217 | EXPORT_SYMBOL(nci_free_device); |
| @@ -1877,9 +1877,15 @@ static bool smcd_lgr_match(struct smc_link_group *lgr, · 1876 unmodified lines | ||
| 1877 | 1877 | struct smcd_dev *smcismdev, |
| 1878 | 1878 | struct smcd_gid *peer_gid) |
| 1879 | 1879 | { |
| 1880 | − return lgr->peer_gid.gid == peer_gid->gid && lgr->smcd == smcismdev && | |
| 1881 | − smc_ism_is_virtual(smcismdev) ? | |
| 1882 | − (lgr->peer_gid.gid_ext == peer_gid->gid_ext) : 1; | |
| 1880 | + if (lgr->peer_gid.gid != peer_gid->gid || | |
| 1881 | + lgr->smcd != smcismdev) | |
| 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 | 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 | 1344 | unix_state_lock(sk1); |
| 1345 | 1345 | return; |
| 1346 | 1346 | } |
| 1347 | − if (sk1 < sk2) { | |
| 1348 | − unix_state_lock(sk1); | |
| 1349 | − unix_state_lock_nested(sk2); | |
| 1350 | − } else { | |
| 1351 | − unix_state_lock(sk2); | |
| 1352 | − unix_state_lock_nested(sk1); | |
| 1353 | − } | |
| 1347 | + if (sk1 > sk2) | |
| 1348 | + swap(sk1, sk2); | |
| 1349 | + | |
| 1350 | + unix_state_lock(sk1); | |
| 1351 | + unix_state_lock_nested(sk2, U_LOCK_SECOND); | |
| 1354 | 1352 | } |
| 1355 | 1353 | |
| 1356 | 1354 | static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) |
| @@ -1591,7 +1589,7 @@ restart: · 234 unmodified lines | ||
| 1591 | 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 | 1594 | if (sk->sk_state != st) { |
| 1597 | 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 | 84 | * queue lock. With the other's queue locked it's |
| 85 | 85 | * OK to lock the state. |
| 86 | 86 | */ |
| 87 | − unix_state_lock_nested(req); | |
| 87 | + unix_state_lock_nested(req, U_LOCK_DIAG); | |
| 88 | 88 | peer = unix_sk(req)->peer; |
| 89 | 89 | buf[i++] = (peer ? sock_i_ino(peer) : 0); |
| 90 | 90 | unix_state_unlock(req); |
| @@ -48,6 +48,17 @@ test_LAG_cleanup() · 47 unmodified lines | ||
| 48 | 48 | ip link add mv0 link "$name" up address "$ucaddr" type macvlan |
| 49 | 49 | # Used to test dev->mc handling |
| 50 | 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 | 62 | ip link set dev "$name" down |
| 52 | 63 | ip link del "$name" |
| 53 | 64 | |
| @@ -1,3 +1,5 @@ | ||
| 1 | +CONFIG_DUMMY=y | |
| 2 | +CONFIG_IPV6=y | |
| 3 | +CONFIG_MACVLAN=y | |
| 1 | 4 | CONFIG_NET_TEAM=y |
| 2 | 5 | CONFIG_NET_TEAM_MODE_LOADBALANCE=y |
| 3 | −CONFIG_MACVLAN=y | |
| @@ -53,8 +53,7 @@ TEST_PROGS += bind_bhash.sh · 52 unmodified lines | ||
| 53 | 53 | TEST_PROGS += ip_local_port_range.sh |
| 54 | 54 | TEST_PROGS += rps_default_mask.sh |
| 55 | 55 | TEST_PROGS += big_tcp.sh |
| 56 | −TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh | |
| 57 | −TEST_PROGS_EXTENDED += toeplitz_client.sh toeplitz.sh lib.sh | |
| 56 | +TEST_PROGS_EXTENDED := toeplitz_client.sh toeplitz.sh | |
| 58 | 57 | TEST_GEN_FILES = socket nettest |
| 59 | 58 | TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any |
| 60 | 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 | 83 | TEST_GEN_FILES += sctp_hello |
| 85 | 84 | TEST_GEN_FILES += csum |
| 86 | 85 | TEST_GEN_FILES += nat6to4.o |
| 86 | +TEST_GEN_FILES += xdp_dummy.o | |
| 87 | 87 | TEST_GEN_FILES += ip_local_port_range |
| 88 | 88 | TEST_GEN_FILES += bind_wildcard |
| 89 | 89 | TEST_PROGS += test_vxlan_mdb.sh |
| @@ -95,6 +95,7 @@ TEST_PROGS += fq_band_pktlimit.sh · 5 unmodified lines | ||
| 95 | 95 | TEST_PROGS += vlan_hw_filter.sh |
| 96 | 96 | |
| 97 | 97 | TEST_FILES := settings |
| 98 | +TEST_FILES += in_netns.sh lib.sh net_helper.sh setup_loopback.sh setup_veth.sh | |
| 98 | 99 | |
| 99 | 100 | include ../lib.mk |
| 100 | 101 | |
| @@ -104,7 +105,7 @@ $(OUTPUT)/tcp_inq: LDLIBS += -lpthread · 3 unmodified lines | ||
| 104 | 105 | $(OUTPUT)/bind_bhash: LDLIBS += -lpthread |
| 105 | 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 | 109 | CLANG ?= clang |
| 109 | 110 | SCRATCH_DIR := $(OUTPUT)/tools |
| 110 | 111 | BUILD_DIR := $(SCRATCH_DIR)/build |
| @@ -139,7 +140,7 @@ endif · 28 unmodified lines | ||
| 139 | 140 | |
| 140 | 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 | 144 | $(CLANG) -O2 --target=bpf -c $< $(CCINCLUDE) $(CLANG_SYS_INCLUDES) -o $@ |
| 144 | 145 | |
| 145 | 146 | $(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ |
| @@ -19,8 +19,11 @@ CONFIG_BRIDGE_VLAN_FILTERING=y · 18 unmodified lines | ||
| 19 | 19 | CONFIG_BRIDGE=y |
| 20 | 20 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| 21 | 21 | CONFIG_VLAN_8021Q=y |
| 22 | +CONFIG_GENEVE=m | |
| 22 | 23 | CONFIG_IFB=y |
| 23 | 24 | CONFIG_INET_DIAG=y |
| 25 | +CONFIG_INET_ESP=y | |
| 26 | +CONFIG_INET_ESP_OFFLOAD=y | |
| 24 | 27 | CONFIG_IP_GRE=m |
| 25 | 28 | CONFIG_NETFILTER=y |
| 26 | 29 | CONFIG_NETFILTER_ADVANCED=y |
| @@ -29,7 +32,10 @@ CONFIG_NF_NAT=m · 2 unmodified lines | ||
| 29 | 32 | CONFIG_IP6_NF_IPTABLES=m |
| 30 | 33 | CONFIG_IP_NF_IPTABLES=m |
| 31 | 34 | CONFIG_IP6_NF_NAT=m |
| 35 | +CONFIG_IP6_NF_RAW=m | |
| 32 | 36 | CONFIG_IP_NF_NAT=m |
| 37 | +CONFIG_IP_NF_RAW=m | |
| 38 | +CONFIG_IP_NF_TARGET_TTL=m | |
| 33 | 39 | CONFIG_IPV6_GRE=m |
| 34 | 40 | CONFIG_IPV6_SEG6_LWTUNNEL=y |
| 35 | 41 | CONFIG_L2TP_ETH=m |
| @@ -45,8 +51,14 @@ CONFIG_NF_TABLES=m · 9 unmodified lines | ||
| 45 | 51 | CONFIG_NF_TABLES_IPV6=y |
| 46 | 52 | CONFIG_NF_TABLES_IPV4=y |
| 47 | 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 | 57 | CONFIG_NET_ACT_GACT=m |
| 58 | +CONFIG_NET_ACT_PEDIT=m | |
| 49 | 59 | CONFIG_NET_CLS_BASIC=m |
| 60 | +CONFIG_NET_CLS_BPF=m | |
| 61 | +CONFIG_NET_CLS_MATCHALL=m | |
| 50 | 62 | CONFIG_NET_CLS_U32=m |
| 51 | 63 | CONFIG_NET_IPGRE_DEMUX=m |
| 52 | 64 | CONFIG_NET_IPGRE=m |
| @@ -55,6 +67,9 @@ CONFIG_NET_SCH_HTB=m · 2 unmodified lines | ||
| 55 | 67 | CONFIG_NET_SCH_FQ=m |
| 56 | 68 | CONFIG_NET_SCH_ETF=m |
| 57 | 69 | CONFIG_NET_SCH_NETEM=y |
| 70 | +CONFIG_NET_SCH_PRIO=m | |
| 71 | +CONFIG_NFT_COMPAT=m | |
| 72 | +CONFIG_NF_FLOW_TABLE=m | |
| 58 | 73 | CONFIG_PSAMPLE=m |
| 59 | 74 | CONFIG_TCP_MD5SIG=y |
| 60 | 75 | CONFIG_TEST_BLACKHOLE_DEV=m |
| @@ -80,3 +95,4 @@ CONFIG_IP_SCTP=m · 19 unmodified lines | ||
| 80 | 95 | CONFIG_NETFILTER_XT_MATCH_POLICY=m |
| 81 | 96 | CONFIG_CRYPTO_ARIA=y |
| 82 | 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 | 112 | vxlan_symmetric_ipv6.sh \ |
| 113 | 113 | vxlan_symmetric.sh |
| 114 | 114 | |
| 115 | −TEST_PROGS_EXTENDED := devlink_lib.sh \ | |
| 115 | +TEST_FILES := devlink_lib.sh \ | |
| 116 | 116 | ethtool_lib.sh \ |
| 117 | 117 | fib_offload_lib.sh \ |
| 118 | 118 | forwarding.config.sample \ |
| @@ -4,6 +4,9 @@ · 3 unmodified lines | ||
| 4 | 4 | ############################################################################## |
| 5 | 5 | # Defines |
| 6 | 6 | |
| 7 | +WAIT_TIMEOUT=${WAIT_TIMEOUT:=20} | |
| 8 | +BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms | |
| 9 | + | |
| 7 | 10 | # Kselftest framework requirement - SKIP code is 4. |
| 8 | 11 | ksft_skip=4 |
| 9 | 12 | # namespace list created by setup_ns |
| @@ -48,7 +51,7 @@ cleanup_ns() · 38 unmodified lines | ||
| 48 | 51 | |
| 49 | 52 | for ns in "$@"; do |
| 50 | 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 | 55 | echo "Warn: Failed to remove namespace $ns" |
| 53 | 56 | ret=1 |
| 54 | 57 | fi |
| @@ -22,8 +22,11 @@ CONFIG_NFT_TPROXY=m · 21 unmodified lines | ||
| 22 | 22 | CONFIG_NFT_SOCKET=m |
| 23 | 23 | CONFIG_IP_ADVANCED_ROUTER=y |
| 24 | 24 | CONFIG_IP_MULTIPLE_TABLES=y |
| 25 | +CONFIG_IP_NF_FILTER=m | |
| 26 | +CONFIG_IP_NF_MANGLE=m | |
| 25 | 27 | CONFIG_IP_NF_TARGET_REJECT=m |
| 26 | 28 | CONFIG_IPV6_MULTIPLE_TABLES=y |
| 29 | +CONFIG_IP6_NF_FILTER=m | |
| 27 | 30 | CONFIG_NET_ACT_CSUM=m |
| 28 | 31 | CONFIG_NET_ACT_PEDIT=m |
| 29 | 32 | CONFIG_NET_CLS_ACT=y |
| @@ -643,13 +643,6 @@ kill_events_pids() · 642 unmodified lines | ||
| 643 | 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 | 646 | pm_nl_set_limits() |
| 654 | 647 | { |
| 655 | 648 | local ns=$1 |
| @@ -3453,7 +3446,7 @@ userspace_tests() · 2797 unmodified lines | ||
| 3453 | 3446 | chk_mptcp_info subflows 0 subflows 0 |
| 3454 | 3447 | chk_subflows_total 1 1 |
| 3455 | 3448 | kill_events_pids |
| 3456 | − wait $tests_pid | |
| 3449 | + mptcp_lib_kill_wait $tests_pid | |
| 3457 | 3450 | fi |
| 3458 | 3451 | |
| 3459 | 3452 | # userspace pm create destroy subflow |
| @@ -3475,7 +3468,7 @@ userspace_tests() · 15 unmodified lines | ||
| 3475 | 3468 | chk_mptcp_info subflows 0 subflows 0 |
| 3476 | 3469 | chk_subflows_total 1 1 |
| 3477 | 3470 | kill_events_pids |
| 3478 | − wait $tests_pid | |
| 3471 | + mptcp_lib_kill_wait $tests_pid | |
| 3479 | 3472 | fi |
| 3480 | 3473 | |
| 3481 | 3474 | # userspace pm create id 0 subflow |
| @@ -3494,7 +3487,7 @@ userspace_tests() · 12 unmodified lines | ||
| 3494 | 3487 | chk_mptcp_info subflows 1 subflows 1 |
| 3495 | 3488 | chk_subflows_total 2 2 |
| 3496 | 3489 | kill_events_pids |
| 3497 | − wait $tests_pid | |
| 3490 | + mptcp_lib_kill_wait $tests_pid | |
| 3498 | 3491 | fi |
| 3499 | 3492 | |
| 3500 | 3493 | # userspace pm remove initial subflow |
| @@ -3518,7 +3511,7 @@ userspace_tests() · 17 unmodified lines | ||
| 3518 | 3511 | chk_mptcp_info subflows 1 subflows 1 |
| 3519 | 3512 | chk_subflows_total 1 1 |
| 3520 | 3513 | kill_events_pids |
| 3521 | − wait $tests_pid | |
| 3514 | + mptcp_lib_kill_wait $tests_pid | |
| 3522 | 3515 | fi |
| 3523 | 3516 | |
| 3524 | 3517 | # userspace pm send RM_ADDR for ID 0 |
| @@ -3544,7 +3537,7 @@ userspace_tests() · 19 unmodified lines | ||
| 3544 | 3537 | chk_mptcp_info subflows 1 subflows 1 |
| 3545 | 3538 | chk_subflows_total 1 1 |
| 3546 | 3539 | kill_events_pids |
| 3547 | − wait $tests_pid | |
| 3540 | + mptcp_lib_kill_wait $tests_pid | |
| 3548 | 3541 | fi |
| 3549 | 3542 | } |
| 3550 | 3543 | |
| @@ -3558,7 +3551,8 @@ endpoint_tests() · 7 unmodified lines | ||
| 3558 | 3551 | pm_nl_set_limits $ns2 2 2 |
| 3559 | 3552 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| 3560 | 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 | 3557 | wait_mpj $ns1 |
| 3564 | 3558 | pm_nl_check_endpoint "creation" \ |
| @@ -3573,7 +3567,7 @@ endpoint_tests() · 8 unmodified lines | ||
| 3573 | 3567 | pm_nl_add_endpoint $ns2 10.0.2.2 flags signal |
| 3574 | 3568 | pm_nl_check_endpoint "modif is allowed" \ |
| 3575 | 3569 | $ns2 10.0.2.2 id 1 flags signal |
| 3576 | − kill_tests_wait | |
| 3570 | + mptcp_lib_kill_wait $tests_pid | |
| 3577 | 3571 | fi |
| 3578 | 3572 | |
| 3579 | 3573 | if reset "delete and re-add" && |
| @@ -3582,7 +3576,8 @@ endpoint_tests() · 2 unmodified lines | ||
| 3582 | 3576 | pm_nl_set_limits $ns2 1 1 |
| 3583 | 3577 | pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow |
| 3584 | 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 | 3582 | wait_mpj $ns2 |
| 3588 | 3583 | chk_subflow_nr "before delete" 2 |
| @@ -3597,7 +3592,7 @@ endpoint_tests() · 8 unmodified lines | ||
| 3597 | 3592 | wait_mpj $ns2 |
| 3598 | 3593 | chk_subflow_nr "after re-add" 2 |
| 3599 | 3594 | chk_mptcp_info subflows 1 subflows 1 |
| 3600 | − kill_tests_wait | |
| 3595 | + mptcp_lib_kill_wait $tests_pid | |
| 3601 | 3596 | fi |
| 3602 | 3597 | } |
| 3603 | 3598 | |
| @@ -6,7 +6,7 @@ readonly KSFT_FAIL=1 · 5 unmodified lines | ||
| 6 | 6 | readonly KSFT_SKIP=4 |
| 7 | 7 | |
| 8 | 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 | 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 | 285 | setup |
| 286 | 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 | 289 | # we still need some additional infrastructure to pass the following test-cases |
| 290 | −run_test 30 10 0 0 "unbalanced bwidth" | |
| 291 | −run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay" | |
| 292 | −run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay" | |
| 290 | +run_test 10 3 0 0 "unbalanced bwidth" | |
| 291 | +run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay" | |
| 292 | +run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay" | |
| 293 | 293 | |
| 294 | 294 | mptcp_lib_result_print_all_tap |
| 295 | 295 | exit $ret |
File mode changed from 100755 to 100644.
| @@ -707,23 +707,23 @@ setup_xfrm6() { · 706 unmodified lines | ||
| 707 | 707 | } |
| 708 | 708 | |
| 709 | 709 | setup_xfrm4udp() { |
| 710 | − setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" | |
| 711 | − setup_nettest_xfrm 4 4500 | |
| 710 | + setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ | |
| 711 | + setup_nettest_xfrm 4 4500 | |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | 714 | setup_xfrm6udp() { |
| 715 | − setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" | |
| 716 | − setup_nettest_xfrm 6 4500 | |
| 715 | + setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ | |
| 716 | + setup_nettest_xfrm 6 4500 | |
| 717 | 717 | } |
| 718 | 718 | |
| 719 | 719 | setup_xfrm4udprouted() { |
| 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 | |
| 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 | |
| 722 | 722 | } |
| 723 | 723 | |
| 724 | 724 | setup_xfrm6udprouted() { |
| 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 | |
| 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 | |
| 727 | 727 | } |
| 728 | 728 | |
| 729 | 729 | setup_routing_old() { |
| @@ -1339,7 +1339,7 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() { · 609 unmodified lines | ||
| 1339 | 1339 | |
| 1340 | 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 | 1344 | size=$(du -sb $tmpoutfile) |
| 1345 | 1345 | size=${size%%/tmp/*} |
File mode changed from 100755 to 100644.
| @@ -11,7 +11,7 @@ setup_veth_ns() { · 10 unmodified lines | ||
| 11 | 11 | local -r ns_mac="$4" |
| 12 | 12 | |
| 13 | 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 | 15 | ip link set dev "${ns_dev}" netns "${ns_name}" mtu 65535 |
| 16 | 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 | 417 | matches_vrf : 1, |
| 418 | 418 | is_current : 1, |
| 419 | 419 | is_rnext : 1, |
| 420 | − used_on_handshake : 1, | |
| 421 | − used_after_accept : 1, | |
| 422 | − used_on_client : 1; | |
| 420 | + used_on_server_tx : 1, | |
| 421 | + used_on_client_tx : 1, | |
| 422 | + skip_counters_checks : 1; | |
| 423 | 423 | }; |
| 424 | 424 | |
| 425 | 425 | struct key_collection { |
| @@ -609,16 +609,14 @@ static int key_collection_socket(bool server, unsigned int port) · 183 unmodified lines | ||
| 609 | 609 | addr = &this_ip_dest; |
| 610 | 610 | sndid = key->client_keyid; |
| 611 | 611 | rcvid = key->server_keyid; |
| 612 | − set_current = key->is_current; | |
| 613 | − set_rnext = key->is_rnext; | |
| 612 | + key->used_on_client_tx = set_current = key->is_current; | |
| 613 | + key->used_on_server_tx = set_rnext = key->is_rnext; | |
| 614 | 614 | } |
| 615 | 615 | |
| 616 | 616 | if (test_add_key_cr(sk, key->password, key->len, |
| 617 | 617 | *addr, vrf, sndid, rcvid, key->maclen, |
| 618 | 618 | key->alg, set_current, set_rnext)) |
| 619 | 619 | test_key_error("setsockopt(TCP_AO_ADD_KEY)", key); |
| 620 | − if (set_current || set_rnext) | |
| 621 | − key->used_on_handshake = 1; | |
| 622 | 620 | #ifdef DEBUG |
| 623 | 621 | test_print("%s [%u/%u] key: { %s, %u:%u, %u, %u:%u:%u:%u (%u)}", |
| 624 | 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 | 638 | for (i = 0; i < collection.nr_keys; i++) { |
| 641 | 639 | struct test_key *key = &collection.keys[i]; |
| 642 | 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 | 645 | if (server) { |
| 646 | 646 | sndid = key->server_keyid; |
| 647 | 647 | rcvid = key->client_keyid; |
| 648 | − if (is_listen_sk) | |
| 649 | − was_used = key->used_on_handshake; | |
| 650 | − else | |
| 651 | − was_used = key->used_after_accept; | |
| 648 | + rx_cnt_expected = key->used_on_client_tx; | |
| 652 | 649 | } else { |
| 653 | 650 | sndid = key->client_keyid; |
| 654 | 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 | 657 | sndid, rcvid); |
| 660 | 658 | } |
| 661 | 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 | 841 | synchronize_threads(); /* 4: verified => closed */ |
| 844 | 842 | close(sk); |
| 845 | 843 | |
| 846 | − verify_counters(tst_name, true, false, begin, &end); | |
| 844 | + verify_counters(tst_name, false, true, begin, &end); | |
| 847 | 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 | 914 | current_index = nr_keys - 1; |
| 917 | 915 | if (rnext_index < 0) |
| 918 | 916 | rnext_index = nr_keys - 1; |
| 919 | − collection.keys[current_index].used_on_handshake = 1; | |
| 920 | − collection.keys[rnext_index].used_after_accept = 1; | |
| 921 | − collection.keys[rnext_index].used_on_client = 1; | |
| 917 | + collection.keys[current_index].used_on_client_tx = 1; | |
| 918 | + collection.keys[rnext_index].used_on_server_tx = 1; | |
| 922 | 919 | |
| 923 | 920 | synchronize_threads(); /* 3: accepted => send data */ |
| 924 | 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 | 1056 | test_error("Can't change the current key"); |
| 1060 | 1057 | if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) |
| 1061 | 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 | 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 | 1096 | verify_current_rnext(tst_name, sk, -1, |
| 1091 | 1097 | collection.keys[i].server_keyid); |
| 1092 | − collection.keys[i].used_on_client = 1; | |
| 1098 | + collection.keys[i].used_on_server_tx = 1; | |
| 1093 | 1099 | synchronize_threads(); /* verify current/rnext */ |
| 1094 | 1100 | } |
| 1095 | 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 | 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 | 68 | return -ret; |
| 67 | 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 | 587 | size_t buf_sz = msg_len * nr; |
| 586 | 588 | char *buf = alloca(buf_sz); |
| 589 | + ssize_t ret; | |
| 587 | 590 | |
| 588 | 591 | randomize_buffer(buf, buf_sz); |
| 589 | − if (test_client_loop(sk, buf, buf_sz, msg_len, timeout_sec) != buf_sz) | |
| 590 | − return -1; | |
| 591 | − return 0; | |
| 592 | + ret = test_client_loop(sk, buf, buf_sz, msg_len, timeout_sec); | |
| 593 | + if (ret < 0) | |
| 594 | + return (int)ret; | |
| 595 | + return ret != buf_sz ? -1 : 0; | |
| 592 | 596 | } |
| @@ -1,10 +1,33 @@ | ||
| 1 | 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 | 25 | #include <inttypes.h> |
| 4 | 26 | #include "../../../../include/linux/kernel.h" |
| 5 | 27 | #include "aolib.h" |
| 6 | 28 | |
| 7 | 29 | const size_t quota = 1000; |
| 30 | +const size_t packet_sz = 100; | |
| 8 | 31 | /* |
| 9 | 32 | * Backlog == 0 means 1 connection in queue, see: |
| 10 | 33 | * commit 64a146513f8f ("[NET]: Revert incorrect accept queue...") |
| @@ -59,26 +82,6 @@ static void close_forced(int sk) · 48 unmodified lines | ||
| 59 | 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 | 85 | static void test_server_active_rst(unsigned int port) |
| 83 | 86 | { |
| 84 | 87 | struct tcp_ao_counters cnt1, cnt2; |
| @@ -155,17 +158,16 @@ static void test_server_passive_rst(unsigned int port) · 70 unmodified lines | ||
| 155 | 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 | 163 | if (test_get_tcp_ao_counters(sk, &ao2)) |
| 160 | 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 | 165 | close(sk); |
| 166 | + | |
| 167 | + synchronize_threads(); /* 5: restore the socket, send more data */ | |
| 165 | 168 | test_tcp_ao_counters_cmp("passive RST server", &ao1, &ao2, TEST_CNT_GOOD); |
| 166 | 169 | |
| 167 | − synchronize_threads(); /* 5: verified => closed */ | |
| 168 | − close(sk); | |
| 170 | + synchronize_threads(); /* 6: server exits */ | |
| 169 | 171 | } |
| 170 | 172 | |
| 171 | 173 | static void *server_fn(void *arg) |
| @@ -284,7 +286,7 @@ static void test_client_active_rst(unsigned int port) · 112 unmodified lines | ||
| 284 | 286 | test_error("test_wait_fds(): %d", err); |
| 285 | 287 | |
| 286 | 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 | 290 | test_fail("Failed to send data on connected socket"); |
| 289 | 291 | else |
| 290 | 292 | test_ok("Verified established tcp connection"); |
| @@ -323,7 +325,6 @@ static void test_client_passive_rst(unsigned int port) · 32 unmodified lines | ||
| 323 | 325 | struct tcp_sock_state img; |
| 324 | 326 | sockaddr_af saddr; |
| 325 | 327 | int sk, err; |
| 326 | − socklen_t slen = sizeof(err); | |
| 327 | 328 | |
| 328 | 329 | sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); |
| 329 | 330 | if (sk < 0) |
| @@ -337,18 +338,51 @@ static void test_client_passive_rst(unsigned int port) · 7 unmodified lines | ||
| 337 | 338 | test_error("failed to connect()"); |
| 338 | 339 | |
| 339 | 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 | 342 | test_fail("Failed to send data on connected socket"); |
| 342 | 343 | else |
| 343 | 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 | 347 | test_enable_repair(sk); |
| 347 | 348 | test_sock_checkpoint(sk, &img, &saddr); |
| 348 | 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 | 387 | sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); |
| 354 | 388 | if (sk < 0) |
| @@ -366,25 +400,33 @@ static void test_client_passive_rst(unsigned int port) · 11 unmodified lines | ||
| 366 | 400 | test_disable_repair(sk); |
| 367 | 401 | test_sock_state_free(&img); |
| 368 | 402 | |
| 369 | − synchronize_threads(); /* 4: terminate server + send more on client */ | |
| 370 | − if (test_client_verify(sk, 100, quota / 100, 2 * TEST_TIMEOUT_SEC)) | |
| 371 | − test_ok("client connection broken post-seq-adjust"); | |
| 372 | − else | |
| 373 | − test_fail("client connection still works post-seq-adjust"); | |
| 374 | − | |
| 375 | − test_wait_for_exception(sk, TEST_TIMEOUT_SEC); | |
| 376 | − | |
| 377 | − if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &slen)) | |
| 378 | − test_error("getsockopt()"); | |
| 379 | − if (err != ECONNRESET && err != EPIPE) | |
| 380 | − test_fail("client connection was not reset: %d", err); | |
| 403 | + /* | |
| 404 | + * This is how "passive reset" is acquired in this test from TCP_TW_RST: | |
| 405 | + * | |
| 406 | + * IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [P.], seq 901:1001, ack 1001, win 249, | |
| 407 | + * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x10217d6c36a22379086ef3b1], length 100 | |
| 408 | + * IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [F.], seq 1001, ack 1001, win 249, | |
| 409 | + * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x104ffc99b98c10a5298cc268], length 0 | |
| 410 | + * IP 10.0.1.1.59772 > 10.0.254.1.7011: Flags [.], ack 1002, win 251, | |
| 411 | + * options [tcp-ao keyid 100 rnextkeyid 100 mac 0xe496dd4f7f5a8a66873c6f93,nop,nop,sack 1 {1001:1002}], length 0 | |
| 412 | + * IP 10.0.1.1.59772 > 10.0.254.1.7011: Flags [P.], seq 1006:1106, ack 1001, win 251, | |
| 413 | + * options [tcp-ao keyid 100 rnextkeyid 100 mac 0x1b5f3330fb23fbcd0c77d0ca], length 100 | |
| 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 | 423 | else |
| 382 | − test_ok("client connection was reset"); | |
| 424 | + test_fail("client sock is yet connected post-seq-adjust"); | |
| 383 | 425 | |
| 384 | 426 | if (test_get_tcp_ao_counters(sk, &ao2)) |
| 385 | 427 | test_error("test_get_tcp_ao_counters()"); |
| 386 | 428 | |
| 387 | − synchronize_threads(); /* 5: verified => closed */ | |
| 429 | + synchronize_threads(); /* 6: server exits */ | |
| 388 | 430 | close(sk); |
| 389 | 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 | 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 | 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 | 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 | 12 | # set global exit status, but never reset nonzero one. |
| 13 | 13 | check_err() |
| @@ -197,7 +197,7 @@ run_all() { · 183 unmodified lines | ||
| 197 | 197 | } |
| 198 | 198 | |
| 199 | 199 | if [ ! -f ${BPF_FILE} ]; then |
| 200 | − echo "Missing ${BPF_FILE}. Build bpf selftest first" | |
| 200 | + echo "Missing ${BPF_FILE}. Run 'make' first" | |
| 201 | 201 | exit -1 |
| 202 | 202 | fi |
| 203 | 203 | |
| @@ -7,7 +7,7 @@ source net_helper.sh · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 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 | 12 | cleanup() { |
| 13 | 13 | local -r jobs="$(jobs -p)" |
| @@ -84,7 +84,7 @@ run_all() { · 70 unmodified lines | ||
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | if [ ! -f ${BPF_FILE} ]; then |
| 87 | − echo "Missing ${BPF_FILE}. Build bpf selftest first" | |
| 87 | + echo "Missing ${BPF_FILE}. Run 'make' first" | |
| 88 | 88 | exit -1 |
| 89 | 89 | fi |
| 90 | 90 | |
| @@ -7,7 +7,7 @@ source net_helper.sh · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 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 | 12 | cleanup() { |
| 13 | 13 | local -r jobs="$(jobs -p)" |
| @@ -85,12 +85,12 @@ run_all() { · 71 unmodified lines | ||
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | if [ ! -f ${BPF_FILE} ]; then |
| 88 | − echo "Missing ${BPF_FILE}. Build bpf selftest first" | |
| 88 | + echo "Missing ${BPF_FILE}. Run 'make' first" | |
| 89 | 89 | exit -1 |
| 90 | 90 | fi |
| 91 | 91 | |
| 92 | 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 | 94 | exit -1 |
| 95 | 95 | fi |
| 96 | 96 | |
| @@ -1,7 +1,9 @@ | ||
| 1 | 1 | #!/bin/bash |
| 2 | 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 | 7 | readonly BASE="ns-$(mktemp -u XXXXXX)" |
| 6 | 8 | readonly SRC=2 |
| 7 | 9 | readonly DST=1 |
| @@ -119,7 +121,7 @@ run_test() { · 111 unmodified lines | ||
| 119 | 121 | ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 8000 |
| 120 | 122 | ip netns exec $NS_DST ./udpgso_bench_rx -C 1000 -R 10 -n 10 -l 1300 $rx_args & |
| 121 | 123 | local spid=$! |
| 122 | − sleep 0.1 | |
| 124 | + wait_local_port_listen "$NS_DST" 8000 udp | |
| 123 | 125 | ip netns exec $NS_SRC ./udpgso_bench_tx $family -M 1 -s 13000 -S 1300 -D $dst |
| 124 | 126 | local retc=$? |
| 125 | 127 | wait $spid |
| @@ -168,7 +170,7 @@ run_bench() { · 42 unmodified lines | ||
| 168 | 170 | ip netns exec $NS_DST bash -c "echo 2 > /sys/class/net/veth$DST/queues/rx-0/rps_cpus" |
| 169 | 171 | ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 1000 -R 10 & |
| 170 | 172 | local spid=$! |
| 171 | − sleep 0.1 | |
| 173 | + wait_local_port_listen "$NS_DST" 8000 udp | |
| 172 | 174 | ip netns exec $NS_SRC taskset 0x1 ./udpgso_bench_tx $family -l 3 -S 1300 -D $dst |
| 173 | 175 | local retc=$? |
| 174 | 176 | wait $spid |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | #!/bin/sh |
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | |
| 4 | −BPF_FILE="../bpf/xdp_dummy.bpf.o" | |
| 4 | +BPF_FILE="xdp_dummy.o" | |
| 5 | 5 | readonly STATS="$(mktemp -p /tmp ns-XXXXXX)" |
| 6 | 6 | readonly BASE=`basename $STATS` |
| 7 | 7 | readonly SRC=2 |
| @@ -218,7 +218,7 @@ while getopts "hs:" option; do · 210 unmodified lines | ||
| 218 | 218 | done |
| 219 | 219 | |
| 220 | 220 | if [ ! -f ${BPF_FILE} ]; then |
| 221 | − echo "Missing ${BPF_FILE}. Build bpf selftest first" | |
| 221 | + echo "Missing ${BPF_FILE}. Run 'make' first" | |
| 222 | 222 | exit 1 |
| 223 | 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"; | |