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
 
 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmW74qQACgkQMUZtbf5S
 Irv8BxAAvGQ8js+HyzDsQ8RYLLzKP+YZbMDwQdpZYSXBEskLSxdEn/SoD+2VOtfD
 5op+ZOusE098Zppj9XEdQoqLDpTuOK5+mVA/85PUVuumz+nh/PfXNDPKO0M6V+pO
 iNq/qR6/gScwPFOzkrNXQaH3gOO1CfFW1Khwf8SPPWx+qCgNQZw3HI6yncukdx/K
 TLLM9LOgOJkhLCjMc7o2zpySQA9ctnVQB/Z6iT+j9EDvB30eyv+gSTT0OJQdMgod
 HpIXh0En52Ndt1Z32vKNoxEIgEWDylgoFUMTTTbJ/mKTwCfseC7PXPs6Kv9CxTJr
 aqFXNJkkF1Lzj09QMtBnfqprST7LEmvdQvOX0B8CT6fdQg0o3l6oz2WiTcpBKV7H
 ArlLLSWq9ABJZZcElR8ESkK3zg1YT42VaXfHsOCduMN1pV+5BbMl0xNSkTJpj+QC
 +r1h/hd09dp+pehJmcT2Coi7kXT2VWJvyqGLWZU7bxmc9wYM/63WHUIWdFAirmRq
 8i2e9WHH6lqmjtzKG2CUpjg92NTpkEPkUDUjpMc+VbUYo583AFt2noNpGvDRZgcq
 3WtcDyyfmX1bOHbagVidtphyQpPki9xt6ZxfgMkIqjNq2qSAr8fWj+cxjSSQvZjR
 +XEc/2NKedXcSnMXSFitsZ4wPJpgCRs2oLBtLQ9SDq4/p6uBSF4=
 =UJVq
 -----END PGP SIGNATURE-----

Merge tag 'net-6.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

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
  ...
This commit is contained in:
Linus Torvalds 2024-02-01 12:39:54 -08:00
commit 41b9fb381a
90 changed files with 845 additions and 409 deletions

View File

@ -1,4 +1,4 @@
What: /sys/class/<iface>/queues/rx-<queue>/rps_cpus
What: /sys/class/net/<iface>/queues/rx-<queue>/rps_cpus
Date: March 2010
KernelVersion: 2.6.35
Contact: netdev@vger.kernel.org
@ -8,7 +8,7 @@ Description:
network device queue. Possible values depend on the number
of available CPU(s) in the system.
What: /sys/class/<iface>/queues/rx-<queue>/rps_flow_cnt
What: /sys/class/net/<iface>/queues/rx-<queue>/rps_flow_cnt
Date: April 2010
KernelVersion: 2.6.35
Contact: netdev@vger.kernel.org
@ -16,7 +16,7 @@ Description:
Number of Receive Packet Steering flows being currently
processed by this particular network device receive queue.
What: /sys/class/<iface>/queues/tx-<queue>/tx_timeout
What: /sys/class/net/<iface>/queues/tx-<queue>/tx_timeout
Date: November 2011
KernelVersion: 3.3
Contact: netdev@vger.kernel.org
@ -24,7 +24,7 @@ Description:
Indicates the number of transmit timeout events seen by this
network interface transmit queue.
What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate
What: /sys/class/net/<iface>/queues/tx-<queue>/tx_maxrate
Date: March 2015
KernelVersion: 4.1
Contact: netdev@vger.kernel.org
@ -32,7 +32,7 @@ Description:
A Mbps max-rate set for the queue, a value of zero means disabled,
default is disabled.
What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus
What: /sys/class/net/<iface>/queues/tx-<queue>/xps_cpus
Date: November 2010
KernelVersion: 2.6.38
Contact: netdev@vger.kernel.org
@ -42,7 +42,7 @@ Description:
network device transmit queue. Possible values depend on the
number of available CPU(s) in the system.
What: /sys/class/<iface>/queues/tx-<queue>/xps_rxqs
What: /sys/class/net/<iface>/queues/tx-<queue>/xps_rxqs
Date: June 2018
KernelVersion: 4.18.0
Contact: netdev@vger.kernel.org
@ -53,7 +53,7 @@ Description:
number of available receive queue(s) in the network device.
Default is disabled.
What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time
What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/hold_time
Date: November 2011
KernelVersion: 3.3
Contact: netdev@vger.kernel.org
@ -62,7 +62,7 @@ Description:
of this particular network device transmit queue.
Default value is 1000.
What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/inflight
What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/inflight
Date: November 2011
KernelVersion: 3.3
Contact: netdev@vger.kernel.org
@ -70,7 +70,7 @@ Description:
Indicates the number of bytes (objects) in flight on this
network device transmit queue.
What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit
What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit
Date: November 2011
KernelVersion: 3.3
Contact: netdev@vger.kernel.org
@ -79,7 +79,7 @@ Description:
on this network device transmit queue. This value is clamped
to be within the bounds defined by limit_max and limit_min.
What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max
What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_max
Date: November 2011
KernelVersion: 3.3
Contact: netdev@vger.kernel.org
@ -88,7 +88,7 @@ Description:
queued on this network device transmit queue. See
include/linux/dynamic_queue_limits.h for the default value.
What: /sys/class/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min
What: /sys/class/net/<iface>/queues/tx-<queue>/byte_queue_limits/limit_min
Date: November 2011
KernelVersion: 3.3
Contact: netdev@vger.kernel.org

View File

@ -942,6 +942,10 @@ attribute-sets:
-
name: gro-ipv4-max-size
type: u32
-
name: dpll-pin
type: nest
nested-attributes: link-dpll-pin-attrs
-
name: af-spec-attrs
attributes:
@ -1627,6 +1631,12 @@ attribute-sets:
-
name: used
type: u8
-
name: link-dpll-pin-attrs
attributes:
-
name: id
type: u32
sub-messages:
-

View File

@ -15181,6 +15181,7 @@ F: Documentation/networking/net_cachelines/net_device.rst
F: drivers/connector/
F: drivers/net/
F: include/dt-bindings/net/
F: include/linux/cn_proc.h
F: include/linux/etherdevice.h
F: include/linux/fcdevice.h
F: include/linux/fddidevice.h
@ -15188,6 +15189,7 @@ F: include/linux/hippidevice.h
F: include/linux/if_*
F: include/linux/inetdevice.h
F: include/linux/netdevice.h
F: include/uapi/linux/cn_proc.h
F: include/uapi/linux/if_*
F: include/uapi/linux/netdevice.h
X: drivers/net/wireless/
@ -18085,7 +18087,6 @@ F: drivers/net/ethernet/qualcomm/emac/
QUALCOMM ETHQOS ETHERNET DRIVER
M: Vinod Koul <vkoul@kernel.org>
R: Bhupesh Sharma <bhupesh.sharma@linaro.org>
L: netdev@vger.kernel.org
L: linux-arm-msm@vger.kernel.org
S: Maintained

View File

@ -2838,8 +2838,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
/* MT753x MAC works in 1G full duplex mode for all up-clocked
* variants.
*/
if (interface == PHY_INTERFACE_MODE_INTERNAL ||
interface == PHY_INTERFACE_MODE_TRGMII ||
if (interface == PHY_INTERFACE_MODE_TRGMII ||
(phy_interface_mode_is_8023z(interface))) {
speed = SPEED_1000;
duplex = DUPLEX_FULL;

View File

@ -3659,7 +3659,7 @@ static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad,
int err;
if (!chip->info->ops->phy_read_c45)
return -EOPNOTSUPP;
return 0xffff;
mv88e6xxx_reg_lock(chip);
err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val);

View File

@ -2051,12 +2051,11 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
priv->info = of_device_get_match_data(priv->dev);
priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
GPIOD_ASIS);
GPIOD_OUT_HIGH);
if (IS_ERR(priv->reset_gpio))
return PTR_ERR(priv->reset_gpio);
if (priv->reset_gpio) {
gpiod_set_value_cansleep(priv->reset_gpio, 1);
/* The active low duration must be greater than 10 ms
* and checkpatch.pl wants 20 ms.
*/

View File

@ -63,6 +63,15 @@ static int pdsc_process_notifyq(struct pdsc_qcq *qcq)
return nq_work;
}
static bool pdsc_adminq_inc_if_up(struct pdsc *pdsc)
{
if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER) ||
pdsc->state & BIT_ULL(PDSC_S_FW_DEAD))
return false;
return refcount_inc_not_zero(&pdsc->adminq_refcnt);
}
void pdsc_process_adminq(struct pdsc_qcq *qcq)
{
union pds_core_adminq_comp *comp;
@ -75,9 +84,9 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq)
int aq_work = 0;
int credits;
/* Don't process AdminQ when shutting down */
if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) {
dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n",
/* Don't process AdminQ when it's not up */
if (!pdsc_adminq_inc_if_up(pdsc)) {
dev_err(pdsc->dev, "%s: called while adminq is unavailable\n",
__func__);
return;
}
@ -124,6 +133,7 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq)
pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx],
credits,
PDS_CORE_INTR_CRED_REARM);
refcount_dec(&pdsc->adminq_refcnt);
}
void pdsc_work_thread(struct work_struct *work)
@ -135,18 +145,20 @@ void pdsc_work_thread(struct work_struct *work)
irqreturn_t pdsc_adminq_isr(int irq, void *data)
{
struct pdsc_qcq *qcq = data;
struct pdsc *pdsc = qcq->pdsc;
struct pdsc *pdsc = data;
struct pdsc_qcq *qcq;
/* Don't process AdminQ when shutting down */
if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) {
dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n",
/* Don't process AdminQ when it's not up */
if (!pdsc_adminq_inc_if_up(pdsc)) {
dev_err(pdsc->dev, "%s: called while adminq is unavailable\n",
__func__);
return IRQ_HANDLED;
}
qcq = &pdsc->adminqcq;
queue_work(pdsc->wq, &qcq->work);
pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR);
refcount_dec(&pdsc->adminq_refcnt);
return IRQ_HANDLED;
}
@ -179,10 +191,16 @@ static int __pdsc_adminq_post(struct pdsc *pdsc,
/* Check that the FW is running */
if (!pdsc_is_fw_running(pdsc)) {
u8 fw_status = ioread8(&pdsc->info_regs->fw_status);
if (pdsc->info_regs) {
u8 fw_status =
ioread8(&pdsc->info_regs->fw_status);
dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n",
__func__, fw_status);
dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n",
__func__, fw_status);
} else {
dev_info(pdsc->dev, "%s: post failed - BARs not setup\n",
__func__);
}
ret = -ENXIO;
goto err_out_unlock;
@ -230,6 +248,12 @@ int pdsc_adminq_post(struct pdsc *pdsc,
int err = 0;
int index;
if (!pdsc_adminq_inc_if_up(pdsc)) {
dev_dbg(pdsc->dev, "%s: preventing adminq cmd %u\n",
__func__, cmd->opcode);
return -ENXIO;
}
wc.qcq = &pdsc->adminqcq;
index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc);
if (index < 0) {
@ -248,10 +272,16 @@ int pdsc_adminq_post(struct pdsc *pdsc,
break;
if (!pdsc_is_fw_running(pdsc)) {
u8 fw_status = ioread8(&pdsc->info_regs->fw_status);
if (pdsc->info_regs) {
u8 fw_status =
ioread8(&pdsc->info_regs->fw_status);
dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n",
__func__, fw_status);
dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n",
__func__, fw_status);
} else {
dev_dbg(pdsc->dev, "%s: post wait failed - BARs not setup\n",
__func__);
}
err = -ENXIO;
break;
}
@ -285,6 +315,8 @@ int pdsc_adminq_post(struct pdsc *pdsc,
queue_work(pdsc->wq, &pdsc->health_work);
}
refcount_dec(&pdsc->adminq_refcnt);
return err;
}
EXPORT_SYMBOL_GPL(pdsc_adminq_post);

View File

@ -125,7 +125,7 @@ static int pdsc_qcq_intr_alloc(struct pdsc *pdsc, struct pdsc_qcq *qcq)
snprintf(name, sizeof(name), "%s-%d-%s",
PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name);
index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, qcq);
index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, pdsc);
if (index < 0)
return index;
qcq->intx = index;
@ -404,10 +404,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init)
int numdescs;
int err;
if (init)
err = pdsc_dev_init(pdsc);
else
err = pdsc_dev_reinit(pdsc);
err = pdsc_dev_init(pdsc);
if (err)
return err;
@ -450,6 +447,7 @@ int pdsc_setup(struct pdsc *pdsc, bool init)
pdsc_debugfs_add_viftype(pdsc);
}
refcount_set(&pdsc->adminq_refcnt, 1);
clear_bit(PDSC_S_FW_DEAD, &pdsc->state);
return 0;
@ -464,6 +462,8 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
if (!pdsc->pdev->is_virtfn)
pdsc_devcmd_reset(pdsc);
if (pdsc->adminqcq.work.func)
cancel_work_sync(&pdsc->adminqcq.work);
pdsc_qcq_free(pdsc, &pdsc->notifyqcq);
pdsc_qcq_free(pdsc, &pdsc->adminqcq);
@ -476,10 +476,9 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
for (i = 0; i < pdsc->nintrs; i++)
pdsc_intr_free(pdsc, i);
if (removing) {
kfree(pdsc->intr_info);
pdsc->intr_info = NULL;
}
kfree(pdsc->intr_info);
pdsc->intr_info = NULL;
pdsc->nintrs = 0;
}
if (pdsc->kern_dbpage) {
@ -487,6 +486,7 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
pdsc->kern_dbpage = NULL;
}
pci_free_irq_vectors(pdsc->pdev);
set_bit(PDSC_S_FW_DEAD, &pdsc->state);
}
@ -512,6 +512,24 @@ void pdsc_stop(struct pdsc *pdsc)
PDS_CORE_INTR_MASK_SET);
}
static void pdsc_adminq_wait_and_dec_once_unused(struct pdsc *pdsc)
{
/* The driver initializes the adminq_refcnt to 1 when the adminq is
* allocated and ready for use. Other users/requesters will increment
* the refcnt while in use. If the refcnt is down to 1 then the adminq
* is not in use and the refcnt can be cleared and adminq freed. Before
* calling this function the driver will set PDSC_S_FW_DEAD, which
* prevent subsequent attempts to use the adminq and increment the
* refcnt to fail. This guarantees that this function will eventually
* exit.
*/
while (!refcount_dec_if_one(&pdsc->adminq_refcnt)) {
dev_dbg_ratelimited(pdsc->dev, "%s: adminq in use\n",
__func__);
cpu_relax();
}
}
void pdsc_fw_down(struct pdsc *pdsc)
{
union pds_core_notifyq_comp reset_event = {
@ -527,6 +545,8 @@ void pdsc_fw_down(struct pdsc *pdsc)
if (pdsc->pdev->is_virtfn)
return;
pdsc_adminq_wait_and_dec_once_unused(pdsc);
/* Notify clients of fw_down */
if (pdsc->fw_reporter)
devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc);
@ -577,7 +597,13 @@ void pdsc_fw_up(struct pdsc *pdsc)
static void pdsc_check_pci_health(struct pdsc *pdsc)
{
u8 fw_status = ioread8(&pdsc->info_regs->fw_status);
u8 fw_status;
/* some sort of teardown already in progress */
if (!pdsc->info_regs)
return;
fw_status = ioread8(&pdsc->info_regs->fw_status);
/* is PCI broken? */
if (fw_status != PDS_RC_BAD_PCI)

View File

@ -184,6 +184,7 @@ struct pdsc {
struct mutex devcmd_lock; /* lock for dev_cmd operations */
struct mutex config_lock; /* lock for configuration operations */
spinlock_t adminq_lock; /* lock for adminq operations */
refcount_t adminq_refcnt;
struct pds_core_dev_info_regs __iomem *info_regs;
struct pds_core_dev_cmd_regs __iomem *cmd_regs;
struct pds_core_intr __iomem *intr_ctrl;
@ -280,7 +281,6 @@ int pdsc_devcmd_locked(struct pdsc *pdsc, union pds_core_dev_cmd *cmd,
union pds_core_dev_comp *comp, int max_seconds);
int pdsc_devcmd_init(struct pdsc *pdsc);
int pdsc_devcmd_reset(struct pdsc *pdsc);
int pdsc_dev_reinit(struct pdsc *pdsc);
int pdsc_dev_init(struct pdsc *pdsc);
void pdsc_reset_prepare(struct pci_dev *pdev);

View File

@ -64,6 +64,10 @@ DEFINE_SHOW_ATTRIBUTE(identity);
void pdsc_debugfs_add_ident(struct pdsc *pdsc)
{
/* This file will already exist in the reset flow */
if (debugfs_lookup("identity", pdsc->dentry))
return;
debugfs_create_file("identity", 0400, pdsc->dentry,
pdsc, &identity_fops);
}

View File

@ -57,6 +57,9 @@ int pdsc_err_to_errno(enum pds_core_status_code code)
bool pdsc_is_fw_running(struct pdsc *pdsc)
{
if (!pdsc->info_regs)
return false;
pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status);
pdsc->last_fw_time = jiffies;
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,
{
int err;
if (!pdsc->cmd_regs)
return -ENXIO;
memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd));
pdsc_devcmd_dbell(pdsc);
err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds);
memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp));
if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq)
queue_work(pdsc->wq, &pdsc->health_work);
else
memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp));
return err;
}
@ -309,13 +316,6 @@ static int pdsc_identify(struct pdsc *pdsc)
return 0;
}
int pdsc_dev_reinit(struct pdsc *pdsc)
{
pdsc_init_devinfo(pdsc);
return pdsc_identify(pdsc);
}
int pdsc_dev_init(struct pdsc *pdsc)
{
unsigned int nintrs;

View File

@ -111,7 +111,8 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
mutex_lock(&pdsc->devcmd_lock);
err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2);
memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list));
if (!err)
memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list));
mutex_unlock(&pdsc->devcmd_lock);
if (err && err != -EIO)
return err;

View File

@ -107,6 +107,9 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw,
dev_info(pdsc->dev, "Installing firmware\n");
if (!pdsc->cmd_regs)
return -ENXIO;
dl = priv_to_devlink(pdsc);
devlink_flash_update_status_notify(dl, "Preparing to flash",
NULL, 0, 0);

View File

@ -37,6 +37,11 @@ static void pdsc_unmap_bars(struct pdsc *pdsc)
struct pdsc_dev_bar *bars = pdsc->bars;
unsigned int i;
pdsc->info_regs = NULL;
pdsc->cmd_regs = NULL;
pdsc->intr_status = NULL;
pdsc->intr_ctrl = NULL;
for (i = 0; i < PDS_CORE_BARS_MAX; i++) {
if (bars[i].vaddr)
pci_iounmap(pdsc->pdev, bars[i].vaddr);
@ -293,7 +298,7 @@ static int pdsc_init_pf(struct pdsc *pdsc)
err_out_teardown:
pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING);
err_out_unmap_bars:
del_timer_sync(&pdsc->wdtimer);
timer_shutdown_sync(&pdsc->wdtimer);
if (pdsc->wq)
destroy_workqueue(pdsc->wq);
mutex_destroy(&pdsc->config_lock);
@ -420,7 +425,7 @@ static void pdsc_remove(struct pci_dev *pdev)
*/
pdsc_sriov_configure(pdev, 0);
del_timer_sync(&pdsc->wdtimer);
timer_shutdown_sync(&pdsc->wdtimer);
if (pdsc->wq)
destroy_workqueue(pdsc->wq);
@ -433,7 +438,6 @@ static void pdsc_remove(struct pci_dev *pdev)
mutex_destroy(&pdsc->config_lock);
mutex_destroy(&pdsc->devcmd_lock);
pci_free_irq_vectors(pdev);
pdsc_unmap_bars(pdsc);
pci_release_regions(pdev);
}
@ -445,13 +449,26 @@ static void pdsc_remove(struct pci_dev *pdev)
devlink_free(dl);
}
static void pdsc_stop_health_thread(struct pdsc *pdsc)
{
timer_shutdown_sync(&pdsc->wdtimer);
if (pdsc->health_work.func)
cancel_work_sync(&pdsc->health_work);
}
static void pdsc_restart_health_thread(struct pdsc *pdsc)
{
timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0);
mod_timer(&pdsc->wdtimer, jiffies + 1);
}
void pdsc_reset_prepare(struct pci_dev *pdev)
{
struct pdsc *pdsc = pci_get_drvdata(pdev);
pdsc_stop_health_thread(pdsc);
pdsc_fw_down(pdsc);
pci_free_irq_vectors(pdev);
pdsc_unmap_bars(pdsc);
pci_release_regions(pdev);
pci_disable_device(pdev);
@ -486,6 +503,7 @@ void pdsc_reset_done(struct pci_dev *pdev)
}
pdsc_fw_up(pdsc);
pdsc_restart_health_thread(pdsc);
}
static const struct pci_error_handlers pdsc_err_handler = {

View File

@ -684,7 +684,7 @@ static void bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
timestamp.hwtstamp = ns_to_ktime(ns);
skb_tstamp_tx(ptp->tx_skb, &timestamp);
} else {
netdev_WARN_ONCE(bp->dev,
netdev_warn_once(bp->dev,
"TS query for TX timer failed rc = %x\n", rc);
}

View File

@ -356,7 +356,7 @@ static enum pkt_hash_types gve_rss_type(__be16 pkt_flags)
static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi,
struct gve_rx_slot_page_info *page_info,
u16 packet_buffer_size, u16 len,
unsigned int truesize, u16 len,
struct gve_rx_ctx *ctx)
{
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,
if (skb != ctx->skb_head) {
ctx->skb_head->len += len;
ctx->skb_head->data_len += len;
ctx->skb_head->truesize += packet_buffer_size;
ctx->skb_head->truesize += truesize;
}
skb_add_rx_frag(skb, num_frags, page_info->page,
offset, len, packet_buffer_size);
offset, len, truesize);
return ctx->skb_head;
}
@ -486,7 +486,7 @@ static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx,
memcpy(alloc_page_info.page_address, src, page_info->pad + len);
skb = gve_rx_add_frags(napi, &alloc_page_info,
rx->packet_buffer_size,
PAGE_SIZE,
len, ctx);
u64_stats_update_begin(&rx->statss);

View File

@ -360,23 +360,43 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca);
* As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of
* INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n)
* bits to count nanoseconds leaving the rest for fractional nonseconds.
*
* Any given INCVALUE also has an associated maximum adjustment value. This
* maximum adjustment value is the largest increase (or decrease) which can be
* safely applied without overflowing the INCVALUE. Since INCVALUE has
* a maximum range of 24 bits, its largest value is 0xFFFFFF.
*
* To understand where the maximum value comes from, consider the following
* equation:
*
* new_incval = base_incval + (base_incval * adjustment) / 1billion
*
* To avoid overflow that means:
* max_incval = base_incval + (base_incval * max_adj) / billion
*
* Re-arranging:
* max_adj = floor(((max_incval - base_incval) * 1billion) / 1billion)
*/
#define INCVALUE_96MHZ 125
#define INCVALUE_SHIFT_96MHZ 17
#define INCPERIOD_SHIFT_96MHZ 2
#define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ)
#define MAX_PPB_96MHZ 23999900 /* 23,999,900 ppb */
#define INCVALUE_25MHZ 40
#define INCVALUE_SHIFT_25MHZ 18
#define INCPERIOD_25MHZ 1
#define MAX_PPB_25MHZ 599999900 /* 599,999,900 ppb */
#define INCVALUE_24MHZ 125
#define INCVALUE_SHIFT_24MHZ 14
#define INCPERIOD_24MHZ 3
#define MAX_PPB_24MHZ 999999999 /* 999,999,999 ppb */
#define INCVALUE_38400KHZ 26
#define INCVALUE_SHIFT_38400KHZ 19
#define INCPERIOD_38400KHZ 1
#define MAX_PPB_38400KHZ 230769100 /* 230,769,100 ppb */
/* Another drawback of scaling the incvalue by a large factor is the
* 64-bit SYSTIM register overflows more quickly. This is dealt with

View File

@ -280,8 +280,17 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)
switch (hw->mac.type) {
case e1000_pch2lan:
adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ;
break;
case e1000_pch_lpt:
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)
adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ;
else
adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ;
break;
case e1000_pch_spt:
adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ;
break;
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
@ -289,15 +298,14 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)
case e1000_pch_lnp:
case e1000_pch_ptp:
case e1000_pch_nvp:
if ((hw->mac.type < e1000_pch_lpt) ||
(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
adapter->ptp_clock_info.max_adj = 24000000 - 1;
break;
}
fallthrough;
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)
adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ;
else
adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ;
break;
case e1000_82574:
case e1000_82583:
adapter->ptp_clock_info.max_adj = 600000000 - 1;
adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ;
break;
default:
break;

View File

@ -978,7 +978,7 @@ struct virtchnl2_ptype {
u8 proto_id_count;
__le16 pad;
__le16 proto_id[];
};
} __packed __aligned(2);
VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype);
/**

View File

@ -716,7 +716,8 @@ static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
error = FIELD_GET(IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK, command);
hw_dbg(hw, "Failed to read, error %x\n", error);
return -EIO;
ret = -EIO;
goto out;
}
if (!ret)

View File

@ -314,7 +314,6 @@ static int otx2_set_channels(struct net_device *dev,
pfvf->hw.tx_queues = channel->tx_count;
if (pfvf->xdp_prog)
pfvf->hw.xdp_queues = channel->rx_count;
pfvf->hw.non_qos_queues = pfvf->hw.tx_queues + pfvf->hw.xdp_queues;
if (if_up)
err = dev->netdev_ops->ndo_open(dev);

View File

@ -1744,6 +1744,7 @@ int otx2_open(struct net_device *netdev)
/* RQ and SQs are mapped to different CQs,
* so find out max CQ IRQs (i.e CINTs) needed.
*/
pf->hw.non_qos_queues = pf->hw.tx_queues + pf->hw.xdp_queues;
pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues,
pf->hw.tc_tx_queues);
@ -2643,8 +2644,6 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog)
xdp_features_clear_redirect_target(dev);
}
pf->hw.non_qos_queues += pf->hw.xdp_queues;
if (if_up)
otx2_open(pf->netdev);

View File

@ -1403,7 +1403,7 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf,
struct otx2_cq_queue *cq,
bool *need_xdp_flush)
{
unsigned char *hard_start, *data;
unsigned char *hard_start;
int qidx = cq->cq_idx;
struct xdp_buff xdp;
struct page *page;
@ -1417,9 +1417,8 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf,
xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq);
data = (unsigned char *)phys_to_virt(pa);
hard_start = page_address(page);
xdp_prepare_buff(&xdp, hard_start, data - hard_start,
hard_start = (unsigned char *)phys_to_virt(pa);
xdp_prepare_buff(&xdp, hard_start, OTX2_HEAD_ROOM,
cqe->sg.seg_size, false);
act = bpf_prog_run_xdp(prog, &xdp);

View File

@ -4761,7 +4761,10 @@ static int mtk_probe(struct platform_device *pdev)
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
if (!err)
err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "Wrong DMA config\n");
return -EINVAL;

View File

@ -168,9 +168,10 @@ static void lan966x_port_link_up(struct lan966x_port *port)
lan966x_taprio_speed_set(port, config->speed);
/* Also the GIGA_MODE_ENA(1) needs to be set regardless of the
* port speed for QSGMII ports.
* port speed for QSGMII or SGMII ports.
*/
if (phy_interface_num_ports(config->portmode) == 4)
if (phy_interface_num_ports(config->portmode) == 4 ||
config->portmode == PHY_INTERFACE_MODE_SGMII)
mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
lan_wr(config->duplex | mode,

View File

@ -1424,10 +1424,30 @@ static void nfp_nft_ct_translate_mangle_action(struct flow_action_entry *mangle_
mangle_action->mangle.mask = (__force u32)cpu_to_be32(mangle_action->mangle.mask);
return;
/* Both struct tcphdr and struct udphdr start with
* __be16 source;
* __be16 dest;
* so we can use the same code for both.
*/
case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
mangle_action->mangle.val = (__force u16)cpu_to_be16(mangle_action->mangle.val);
mangle_action->mangle.mask = (__force u16)cpu_to_be16(mangle_action->mangle.mask);
if (mangle_action->mangle.offset == offsetof(struct tcphdr, source)) {
mangle_action->mangle.val =
(__force u32)cpu_to_be32(mangle_action->mangle.val << 16);
/* The mask of mangle action is inverse mask,
* so clear the dest tp port with 0xFFFF to
* instead of rotate-left operation.
*/
mangle_action->mangle.mask =
(__force u32)cpu_to_be32(mangle_action->mangle.mask << 16 | 0xFFFF);
}
if (mangle_action->mangle.offset == offsetof(struct tcphdr, dest)) {
mangle_action->mangle.offset = 0;
mangle_action->mangle.val =
(__force u32)cpu_to_be32(mangle_action->mangle.val);
mangle_action->mangle.mask =
(__force u32)cpu_to_be32(mangle_action->mangle.mask);
}
return;
default:
@ -1864,10 +1884,30 @@ int nfp_fl_ct_handle_post_ct(struct nfp_flower_priv *priv,
{
struct flow_rule *rule = flow_cls_offload_flow_rule(flow);
struct nfp_fl_ct_flow_entry *ct_entry;
struct flow_action_entry *ct_goto;
struct nfp_fl_ct_zone_entry *zt;
struct flow_action_entry *act;
bool wildcarded = false;
struct flow_match_ct ct;
struct flow_action_entry *ct_goto;
int i;
flow_action_for_each(i, act, &rule->action) {
switch (act->id) {
case FLOW_ACTION_REDIRECT:
case FLOW_ACTION_REDIRECT_INGRESS:
case FLOW_ACTION_MIRRED:
case FLOW_ACTION_MIRRED_INGRESS:
if (act->dev->rtnl_link_ops &&
!strcmp(act->dev->rtnl_link_ops->kind, "openvswitch")) {
NL_SET_ERR_MSG_MOD(extack,
"unsupported offload: out port is openvswitch internal port");
return -EOPNOTSUPP;
}
break;
default:
break;
}
}
flow_rule_match_ct(rule, &ct);
if (!ct.mask->ct_zone) {

View File

@ -353,6 +353,10 @@ static int imx_dwmac_probe(struct platform_device *pdev)
if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY)
plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY;
/* Default TX Q0 to use TSO and rest TXQ for TBS */
for (int i = 1; i < plat_dat->tx_queues_to_use; i++)
plat_dat->tx_queues_cfg[i].tbs_en = 1;
plat_dat->host_dma_width = dwmac->ops->addr_width;
plat_dat->init = imx_dwmac_init;
plat_dat->exit = imx_dwmac_exit;

View File

@ -3932,6 +3932,9 @@ static int __stmmac_open(struct net_device *dev,
priv->rx_copybreak = STMMAC_RX_COPYBREAK;
buf_sz = dma_conf->dma_buf_sz;
for (int i = 0; i < MTL_MAX_TX_QUEUES; i++)
if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_EN)
dma_conf->tx_queue[i].tbs = priv->dma_conf.tx_queue[i].tbs;
memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf));
stmmac_reset_queues_param(priv);

View File

@ -708,7 +708,10 @@ void netvsc_device_remove(struct hv_device *device)
/* Disable NAPI and disassociate its context from the device. */
for (i = 0; i < net_device->num_chn; i++) {
/* See also vmbus_reset_channel_cb(). */
napi_disable(&net_device->chan_table[i].napi);
/* only disable enabled NAPI channel */
if (i < ndev->real_num_rx_queues)
napi_disable(&net_device->chan_table[i].napi);
netif_napi_del(&net_device->chan_table[i].napi);
}

View File

@ -489,7 +489,7 @@ static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
u16 reg, val;
if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
bias = -2;
bias = -1;
val = clamp_val(bias + tx_r50_cal_val, 0, 63);
@ -705,6 +705,11 @@ static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
static void mt798x_phy_common_finetune(struct phy_device *phydev)
{
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
/* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
__phy_write(phydev, 0x11, 0xc71);
__phy_write(phydev, 0x12, 0xc);
__phy_write(phydev, 0x10, 0x8fae);
/* EnabRandUpdTrig = 1 */
__phy_write(phydev, 0x11, 0x2f00);
__phy_write(phydev, 0x12, 0xe);
@ -715,15 +720,56 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev)
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x83aa);
/* TrFreeze = 0 */
/* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
__phy_write(phydev, 0x11, 0x240);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x9680);
/* TrFreeze = 0 (mt7988 default) */
__phy_write(phydev, 0x11, 0x0);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x9686);
/* SSTrKp100 = 5 */
/* SSTrKf100 = 6 */
/* SSTrKp1000Mas = 5 */
/* SSTrKf1000Mas = 6 */
/* SSTrKp1000Slv = 5 */
/* SSTrKf1000Slv = 6 */
__phy_write(phydev, 0x11, 0xbaef);
__phy_write(phydev, 0x12, 0x2e);
__phy_write(phydev, 0x10, 0x968c);
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
}
static void mt7981_phy_finetune(struct phy_device *phydev)
{
u16 val[8] = { 0x01ce, 0x01c1,
0x020f, 0x0202,
0x03d0, 0x03c0,
0x0013, 0x0005 };
int i, k;
/* 100M eye finetune:
* Keep middle level of TX MLT3 shapper as default.
* Only change TX MLT3 overshoot level here.
*/
for (k = 0, i = 1; i < 12; i++) {
if (i % 3 == 0)
continue;
phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
}
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
/* ResetSyncOffset = 6 */
__phy_write(phydev, 0x11, 0x600);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x8fc0);
/* VgaDecRate = 1 */
__phy_write(phydev, 0x11, 0x4c2a);
__phy_write(phydev, 0x12, 0x3e);
__phy_write(phydev, 0x10, 0x8fa4);
/* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
* MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
@ -738,7 +784,7 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev)
__phy_write(phydev, 0x10, 0x8ec0);
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
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)
phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
}
static void mt7981_phy_finetune(struct phy_device *phydev)
{
u16 val[8] = { 0x01ce, 0x01c1,
0x020f, 0x0202,
0x03d0, 0x03c0,
0x0013, 0x0005 };
int i, k;
/* 100M eye finetune:
* Keep middle level of TX MLT3 shapper as default.
* Only change TX MLT3 overshoot level here.
*/
for (k = 0, i = 1; i < 12; i++) {
if (i % 3 == 0)
continue;
phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
}
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
/* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
__phy_write(phydev, 0x11, 0xc71);
__phy_write(phydev, 0x12, 0xc);
__phy_write(phydev, 0x10, 0x8fae);
/* ResetSyncOffset = 6 */
__phy_write(phydev, 0x11, 0x600);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x8fc0);
/* VgaDecRate = 1 */
__phy_write(phydev, 0x11, 0x4c2a);
__phy_write(phydev, 0x12, 0x3e);
__phy_write(phydev, 0x10, 0x8fa4);
/* FfeUpdGainForce = 4 */
__phy_write(phydev, 0x11, 0x240);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x9680);
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
}
static void mt7988_phy_finetune(struct phy_device *phydev)
{
u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
@ -827,17 +831,7 @@ static void mt7988_phy_finetune(struct phy_device *phydev)
/* TCT finetune */
phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
/* Disable TX power saving */
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
/* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
__phy_write(phydev, 0x11, 0x671);
__phy_write(phydev, 0x12, 0xc);
__phy_write(phydev, 0x10, 0x8fae);
/* ResetSyncOffset = 5 */
__phy_write(phydev, 0x11, 0x500);
__phy_write(phydev, 0x12, 0x0);
@ -845,13 +839,27 @@ static void mt7988_phy_finetune(struct phy_device *phydev)
/* VgaDecRate is 1 at default on mt7988 */
/* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
* MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
*/
__phy_write(phydev, 0x11, 0xb90a);
__phy_write(phydev, 0x12, 0x6f);
__phy_write(phydev, 0x10, 0x8f82);
/* RemAckCntLimitCtrl = 1 */
__phy_write(phydev, 0x11, 0xfbba);
__phy_write(phydev, 0x12, 0xc3);
__phy_write(phydev, 0x10, 0x87f8);
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
/* TxClkOffset = 2 */
__phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
/* rg_tr_lpf_cnt_val = 1023 */
phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
}
static void mt798x_phy_eee(struct phy_device *phydev)
@ -884,11 +892,11 @@ static void mt798x_phy_eee(struct phy_device *phydev)
MTK_PHY_LPI_SLV_SEND_TX_EN,
FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
MTK_PHY_LPI_TXPCS_LOC_RCV,
FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
/* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
MTK_PHY_LPI_TXPCS_LOC_RCV);
/* This also fixes some IoT issues, such as CH340 */
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
@ -922,7 +930,7 @@ static void mt798x_phy_eee(struct phy_device *phydev)
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x9690);
/* REG_EEE_st2TrKf1000 = 3 */
/* REG_EEE_st2TrKf1000 = 2 */
__phy_write(phydev, 0x11, 0x114f);
__phy_write(phydev, 0x12, 0x2);
__phy_write(phydev, 0x10, 0x969a);
@ -947,7 +955,7 @@ static void mt798x_phy_eee(struct phy_device *phydev)
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x96b8);
/* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
/* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
__phy_write(phydev, 0x11, 0x1463);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x96ca);
@ -1459,6 +1467,13 @@ static int mt7988_phy_probe(struct phy_device *phydev)
if (err)
return err;
/* Disable TX power saving at probing to:
* 1. Meet common mode compliance test criteria
* 2. Make sure that TX-VCM calibration works fine
*/
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
return mt798x_phy_calibration(phydev);
}

View File

@ -104,13 +104,12 @@ bool provides_xdp_headroom = true;
module_param(provides_xdp_headroom, bool, 0644);
static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx,
u8 status);
s8 status);
static void make_tx_response(struct xenvif_queue *queue,
struct xen_netif_tx_request *txp,
const struct xen_netif_tx_request *txp,
unsigned int extra_count,
s8 st);
static void push_tx_responses(struct xenvif_queue *queue);
s8 status);
static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx);
@ -208,13 +207,9 @@ static void xenvif_tx_err(struct xenvif_queue *queue,
unsigned int extra_count, RING_IDX end)
{
RING_IDX cons = queue->tx.req_cons;
unsigned long flags;
do {
spin_lock_irqsave(&queue->response_lock, flags);
make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR);
push_tx_responses(queue);
spin_unlock_irqrestore(&queue->response_lock, flags);
if (cons == end)
break;
RING_COPY_REQUEST(&queue->tx, cons++, txp);
@ -465,12 +460,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS;
nr_slots--) {
if (unlikely(!txp->size)) {
unsigned long flags;
spin_lock_irqsave(&queue->response_lock, flags);
make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY);
push_tx_responses(queue);
spin_unlock_irqrestore(&queue->response_lock, flags);
++txp;
continue;
}
@ -496,14 +486,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) {
if (unlikely(!txp->size)) {
unsigned long flags;
spin_lock_irqsave(&queue->response_lock, flags);
make_tx_response(queue, txp, 0,
XEN_NETIF_RSP_OKAY);
push_tx_responses(queue);
spin_unlock_irqrestore(&queue->response_lock,
flags);
continue;
}
@ -995,7 +979,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
(ret == 0) ?
XEN_NETIF_RSP_OKAY :
XEN_NETIF_RSP_ERROR);
push_tx_responses(queue);
continue;
}
@ -1007,7 +990,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
make_tx_response(queue, &txreq, extra_count,
XEN_NETIF_RSP_OKAY);
push_tx_responses(queue);
continue;
}
@ -1433,44 +1415,17 @@ int xenvif_tx_action(struct xenvif_queue *queue, int budget)
return work_done;
}
static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx,
u8 status)
{
struct pending_tx_info *pending_tx_info;
pending_ring_idx_t index;
unsigned long flags;
pending_tx_info = &queue->pending_tx_info[pending_idx];
spin_lock_irqsave(&queue->response_lock, flags);
make_tx_response(queue, &pending_tx_info->req,
pending_tx_info->extra_count, status);
/* Release the pending index before pusing the Tx response so
* its available before a new Tx request is pushed by the
* frontend.
*/
index = pending_index(queue->pending_prod++);
queue->pending_ring[index] = pending_idx;
push_tx_responses(queue);
spin_unlock_irqrestore(&queue->response_lock, flags);
}
static void make_tx_response(struct xenvif_queue *queue,
struct xen_netif_tx_request *txp,
static void _make_tx_response(struct xenvif_queue *queue,
const struct xen_netif_tx_request *txp,
unsigned int extra_count,
s8 st)
s8 status)
{
RING_IDX i = queue->tx.rsp_prod_pvt;
struct xen_netif_tx_response *resp;
resp = RING_GET_RESPONSE(&queue->tx, i);
resp->id = txp->id;
resp->status = st;
resp->status = status;
while (extra_count-- != 0)
RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL;
@ -1487,6 +1442,47 @@ static void push_tx_responses(struct xenvif_queue *queue)
notify_remote_via_irq(queue->tx_irq);
}
static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx,
s8 status)
{
struct pending_tx_info *pending_tx_info;
pending_ring_idx_t index;
unsigned long flags;
pending_tx_info = &queue->pending_tx_info[pending_idx];
spin_lock_irqsave(&queue->response_lock, flags);
_make_tx_response(queue, &pending_tx_info->req,
pending_tx_info->extra_count, status);
/* Release the pending index before pusing the Tx response so
* its available before a new Tx request is pushed by the
* frontend.
*/
index = pending_index(queue->pending_prod++);
queue->pending_ring[index] = pending_idx;
push_tx_responses(queue);
spin_unlock_irqrestore(&queue->response_lock, flags);
}
static void make_tx_response(struct xenvif_queue *queue,
const struct xen_netif_tx_request *txp,
unsigned int extra_count,
s8 status)
{
unsigned long flags;
spin_lock_irqsave(&queue->response_lock, flags);
_make_tx_response(queue, txp, extra_count, status);
push_tx_responses(queue);
spin_unlock_irqrestore(&queue->response_lock, flags);
}
static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
{
int ret;

View File

@ -186,6 +186,8 @@ struct ip_set_type_variant {
/* Return true if "b" set is the same as "a"
* according to the create set parameters */
bool (*same_set)(const struct ip_set *a, const struct ip_set *b);
/* Cancel ongoing garbage collectors before destroying the set*/
void (*cancel_gc)(struct ip_set *set);
/* Region-locking is used */
bool region_lock;
};
@ -242,6 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type);
/* A generic IP set */
struct ip_set {
/* For call_cru in destroy */
struct rcu_head rcu;
/* The name of the set */
char name[IPSET_MAXNAMELEN];
/* Lock protecting the set data */

View File

@ -46,12 +46,6 @@ struct scm_stat {
#define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb))
#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
#define unix_state_lock_nested(s) \
spin_lock_nested(&unix_sk(s)->lock, \
SINGLE_DEPTH_NESTING)
/* The AF_UNIX socket */
struct unix_sock {
/* WARNING: sk has to be the first member */
@ -77,6 +71,20 @@ struct unix_sock {
#define unix_sk(ptr) container_of_const(ptr, struct unix_sock, sk)
#define unix_peer(sk) (unix_sk(sk)->peer)
#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
enum unix_socket_lock_class {
U_LOCK_NORMAL,
U_LOCK_SECOND, /* for double locking, see unix_state_double_lock(). */
U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */
};
static inline void unix_state_lock_nested(struct sock *sk,
enum unix_socket_lock_class subclass)
{
spin_lock_nested(&unix_sk(sk)->lock, subclass);
}
#define peer_wait peer_wq.wait
long unix_inq_len(struct sock *sk);

View File

@ -767,7 +767,7 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev);
* Functions provided by ip_sockglue.c
*/
void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst);
void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb, int tlen, int offset);
int ip_cmsg_send(struct sock *sk, struct msghdr *msg,

View File

@ -1351,6 +1351,7 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
* @type: stateful object numeric type
* @owner: module owner
* @maxattr: maximum netlink attribute
* @family: address family for AF-specific object types
* @policy: netlink attribute policy
*/
struct nft_object_type {
@ -1360,6 +1361,7 @@ struct nft_object_type {
struct list_head list;
u32 type;
unsigned int maxattr;
u8 family;
struct module *owner;
const struct nla_policy *policy;
};

View File

@ -2175,6 +2175,7 @@ void batadv_mcast_free(struct batadv_priv *bat_priv)
cancel_delayed_work_sync(&bat_priv->mcast.work);
batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST_TRACKER, 1);
batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 2);
/* safely calling outside of worker, as worker was canceled above */
@ -2198,6 +2199,8 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig)
BATADV_MCAST_WANT_NO_RTR4);
batadv_mcast_want_rtr6_update(bat_priv, orig,
BATADV_MCAST_WANT_NO_RTR6);
batadv_mcast_have_mc_ptype_update(bat_priv, orig,
BATADV_MCAST_HAVE_MC_PTYPE_CAPA);
spin_unlock_bh(&orig->mcast_handler_lock);
}

View File

@ -1762,6 +1762,10 @@ static void br_ip6_multicast_querier_expired(struct timer_list *t)
}
#endif
static void br_multicast_query_delay_expired(struct timer_list *t)
{
}
static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx,
struct br_ip *ip,
struct sk_buff *skb)
@ -3198,7 +3202,7 @@ br_multicast_update_query_timer(struct net_bridge_mcast *brmctx,
unsigned long max_delay)
{
if (!timer_pending(&query->timer))
query->delay_time = jiffies + max_delay;
mod_timer(&query->delay_timer, jiffies + max_delay);
mod_timer(&query->timer, jiffies + brmctx->multicast_querier_interval);
}
@ -4041,13 +4045,11 @@ void br_multicast_ctx_init(struct net_bridge *br,
brmctx->multicast_querier_interval = 255 * HZ;
brmctx->multicast_membership_interval = 260 * HZ;
brmctx->ip4_other_query.delay_time = 0;
brmctx->ip4_querier.port_ifidx = 0;
seqcount_spinlock_init(&brmctx->ip4_querier.seq, &br->multicast_lock);
brmctx->multicast_igmp_version = 2;
#if IS_ENABLED(CONFIG_IPV6)
brmctx->multicast_mld_version = 1;
brmctx->ip6_other_query.delay_time = 0;
brmctx->ip6_querier.port_ifidx = 0;
seqcount_spinlock_init(&brmctx->ip6_querier.seq, &br->multicast_lock);
#endif
@ -4056,6 +4058,8 @@ void br_multicast_ctx_init(struct net_bridge *br,
br_ip4_multicast_local_router_expired, 0);
timer_setup(&brmctx->ip4_other_query.timer,
br_ip4_multicast_querier_expired, 0);
timer_setup(&brmctx->ip4_other_query.delay_timer,
br_multicast_query_delay_expired, 0);
timer_setup(&brmctx->ip4_own_query.timer,
br_ip4_multicast_query_expired, 0);
#if IS_ENABLED(CONFIG_IPV6)
@ -4063,6 +4067,8 @@ void br_multicast_ctx_init(struct net_bridge *br,
br_ip6_multicast_local_router_expired, 0);
timer_setup(&brmctx->ip6_other_query.timer,
br_ip6_multicast_querier_expired, 0);
timer_setup(&brmctx->ip6_other_query.delay_timer,
br_multicast_query_delay_expired, 0);
timer_setup(&brmctx->ip6_own_query.timer,
br_ip6_multicast_query_expired, 0);
#endif
@ -4197,10 +4203,12 @@ static void __br_multicast_stop(struct net_bridge_mcast *brmctx)
{
del_timer_sync(&brmctx->ip4_mc_router_timer);
del_timer_sync(&brmctx->ip4_other_query.timer);
del_timer_sync(&brmctx->ip4_other_query.delay_timer);
del_timer_sync(&brmctx->ip4_own_query.timer);
#if IS_ENABLED(CONFIG_IPV6)
del_timer_sync(&brmctx->ip6_mc_router_timer);
del_timer_sync(&brmctx->ip6_other_query.timer);
del_timer_sync(&brmctx->ip6_other_query.delay_timer);
del_timer_sync(&brmctx->ip6_own_query.timer);
#endif
}
@ -4643,13 +4651,15 @@ int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val)
max_delay = brmctx->multicast_query_response_interval;
if (!timer_pending(&brmctx->ip4_other_query.timer))
brmctx->ip4_other_query.delay_time = jiffies + max_delay;
mod_timer(&brmctx->ip4_other_query.delay_timer,
jiffies + max_delay);
br_multicast_start_querier(brmctx, &brmctx->ip4_own_query);
#if IS_ENABLED(CONFIG_IPV6)
if (!timer_pending(&brmctx->ip6_other_query.timer))
brmctx->ip6_other_query.delay_time = jiffies + max_delay;
mod_timer(&brmctx->ip6_other_query.delay_timer,
jiffies + max_delay);
br_multicast_start_querier(brmctx, &brmctx->ip6_own_query);
#endif

View File

@ -78,7 +78,7 @@ struct bridge_mcast_own_query {
/* other querier */
struct bridge_mcast_other_query {
struct timer_list timer;
unsigned long delay_time;
struct timer_list delay_timer;
};
/* selected querier */
@ -1159,7 +1159,7 @@ __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
own_querier_enabled = false;
}
return time_is_before_jiffies(querier->delay_time) &&
return !timer_pending(&querier->delay_timer) &&
(own_querier_enabled || timer_pending(&querier->timer));
}

View File

@ -674,7 +674,7 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port,
return -EOPNOTSUPP;
}
if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FN_ATTR_STATE],
"Function does not support state setting");
return -EOPNOTSUPP;
}

View File

@ -308,7 +308,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
skb = hsr_init_skb(master);
if (!skb) {
WARN_ONCE(1, "HSR: Could not send supervision frame\n");
netdev_warn_once(master->dev, "HSR: Could not send supervision frame\n");
return;
}
@ -355,7 +355,7 @@ static void send_prp_supervision_frame(struct hsr_port *master,
skb = hsr_init_skb(master);
if (!skb) {
WARN_ONCE(1, "PRP: Could not send supervision frame\n");
netdev_warn_once(master->dev, "PRP: Could not send supervision frame\n");
return;
}

View File

@ -1287,6 +1287,12 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
if (unlikely(!rt))
return -EFAULT;
cork->fragsize = ip_sk_use_pmtu(sk) ?
dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
if (!inetdev_valid_mtu(cork->fragsize))
return -ENETUNREACH;
/*
* setup for corking.
*/
@ -1303,12 +1309,6 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
cork->addr = ipc->addr;
}
cork->fragsize = ip_sk_use_pmtu(sk) ?
dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
if (!inetdev_valid_mtu(cork->fragsize))
return -ENETUNREACH;
cork->gso_size = ipc->gso_size;
cork->dst = &rt->dst;

View File

@ -1363,12 +1363,13 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname,
* ipv4_pktinfo_prepare - transfer some info from rtable to skb
* @sk: socket
* @skb: buffer
* @drop_dst: if true, drops skb dst
*
* To support IP_CMSG_PKTINFO option, we store rt_iif and specific
* destination in skb->cb[] before dst drop.
* This way, receiver doesn't make cache line misses to read rtable.
*/
void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst)
{
struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb);
bool prepare = inet_test_bit(PKTINFO, sk) ||
@ -1397,7 +1398,8 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
pktinfo->ipi_ifindex = 0;
pktinfo->ipi_spec_dst.s_addr = 0;
}
skb_dst_drop(skb);
if (drop_dst)
skb_dst_drop(skb);
}
int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,

View File

@ -1073,7 +1073,7 @@ static int ipmr_cache_report(const struct mr_table *mrt,
msg = (struct igmpmsg *)skb_network_header(skb);
msg->im_vif = vifi;
msg->im_vif_hi = vifi >> 8;
ipv4_pktinfo_prepare(mroute_sk, pkt);
ipv4_pktinfo_prepare(mroute_sk, pkt, false);
memcpy(skb->cb, pkt->cb, sizeof(skb->cb));
/* Add our header */
igmp = skb_put(skb, sizeof(struct igmphdr));

View File

@ -292,7 +292,7 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
/* Charge it to the socket. */
ipv4_pktinfo_prepare(sk, skb);
ipv4_pktinfo_prepare(sk, skb, true);
if (sock_queue_rcv_skb_reason(sk, skb, &reason) < 0) {
kfree_skb_reason(skb, reason);
return NET_RX_DROP;

View File

@ -1786,7 +1786,17 @@ static skb_frag_t *skb_advance_to_frag(struct sk_buff *skb, u32 offset_skb,
static bool can_map_frag(const skb_frag_t *frag)
{
return skb_frag_size(frag) == PAGE_SIZE && !skb_frag_off(frag);
struct page *page;
if (skb_frag_size(frag) != PAGE_SIZE || skb_frag_off(frag))
return false;
page = skb_frag_page(frag);
if (PageCompound(page) || page->mapping)
return false;
return true;
}
static int find_next_mappable_frag(const skb_frag_t *frag,

View File

@ -2169,7 +2169,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
udp_csum_pull_header(skb);
ipv4_pktinfo_prepare(sk, skb);
ipv4_pktinfo_prepare(sk, skb, true);
return __udp_queue_rcv_skb(sk, skb);
csum_error:

View File

@ -220,19 +220,26 @@ const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) {
EXPORT_SYMBOL_GPL(ipv6_stub);
/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
const struct in6_addr in6addr_loopback __aligned(BITS_PER_LONG/8)
= IN6ADDR_LOOPBACK_INIT;
EXPORT_SYMBOL(in6addr_loopback);
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
const struct in6_addr in6addr_any __aligned(BITS_PER_LONG/8)
= IN6ADDR_ANY_INIT;
EXPORT_SYMBOL(in6addr_any);
const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
const struct in6_addr in6addr_linklocal_allnodes __aligned(BITS_PER_LONG/8)
= IN6ADDR_LINKLOCAL_ALLNODES_INIT;
EXPORT_SYMBOL(in6addr_linklocal_allnodes);
const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
const struct in6_addr in6addr_linklocal_allrouters __aligned(BITS_PER_LONG/8)
= IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
EXPORT_SYMBOL(in6addr_linklocal_allrouters);
const struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT;
const struct in6_addr in6addr_interfacelocal_allnodes __aligned(BITS_PER_LONG/8)
= IN6ADDR_INTERFACELOCAL_ALLNODES_INIT;
EXPORT_SYMBOL(in6addr_interfacelocal_allnodes);
const struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT;
const struct in6_addr in6addr_interfacelocal_allrouters __aligned(BITS_PER_LONG/8)
= IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT;
EXPORT_SYMBOL(in6addr_interfacelocal_allrouters);
const struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT;
const struct in6_addr in6addr_sitelocal_allrouters __aligned(BITS_PER_LONG/8)
= IN6ADDR_SITELOCAL_ALLROUTERS_INIT;
EXPORT_SYMBOL(in6addr_sitelocal_allrouters);
static void snmp6_free_dev(struct inet6_dev *idev)

View File

@ -796,8 +796,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
struct sk_buff *skb),
bool log_ecn_err)
{
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
int err;
const struct ipv6hdr *ipv6h;
int nh, err;
if ((!(tpi->flags & TUNNEL_CSUM) &&
(tunnel->parms.i_flags & TUNNEL_CSUM)) ||
@ -829,7 +829,6 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
goto drop;
}
ipv6h = ipv6_hdr(skb);
skb->protocol = eth_type_trans(skb, tunnel->dev);
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
} else {
@ -837,7 +836,23 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
skb_reset_mac_header(skb);
}
/* Save offset of outer header relative to skb->head,
* because we are going to reset the network header to the inner header
* and might change skb->head.
*/
nh = skb_network_header(skb) - skb->head;
skb_reset_network_header(skb);
if (!pskb_inet_may_pull(skb)) {
DEV_STATS_INC(tunnel->dev, rx_length_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
goto drop;
}
/* Get the outer header. */
ipv6h = (struct ipv6hdr *)(skb->head + nh);
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
__skb_tunnel_rx(skb, tunnel->dev, tunnel->net);

View File

@ -226,6 +226,8 @@ static int llc_ui_release(struct socket *sock)
}
netdev_put(llc->dev, &llc->dev_tracker);
sock_put(sk);
sock_orphan(sk);
sock->sk = NULL;
llc_sk_free(sk);
out:
return 0;

View File

@ -2314,9 +2314,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
if (__mptcp_check_fallback(msk))
return false;
if (tcp_rtx_and_write_queues_empty(sk))
return false;
/* the closing socket has some data untransmitted and/or unacked:
* some data in the mptcp rtx queue has not really xmitted yet.
* keep it simple and re-inject the whole mptcp level rtx queue

View File

@ -30,6 +30,7 @@
#define mtype_del IPSET_TOKEN(MTYPE, _del)
#define mtype_list IPSET_TOKEN(MTYPE, _list)
#define mtype_gc IPSET_TOKEN(MTYPE, _gc)
#define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc)
#define mtype MTYPE
#define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id)))
@ -59,9 +60,6 @@ mtype_destroy(struct ip_set *set)
{
struct mtype *map = set->data;
if (SET_WITH_TIMEOUT(set))
del_timer_sync(&map->gc);
if (set->dsize && set->extensions & IPSET_EXT_DESTROY)
mtype_ext_cleanup(set);
ip_set_free(map->members);
@ -290,6 +288,15 @@ mtype_gc(struct timer_list *t)
add_timer(&map->gc);
}
static void
mtype_cancel_gc(struct ip_set *set)
{
struct mtype *map = set->data;
if (SET_WITH_TIMEOUT(set))
del_timer_sync(&map->gc);
}
static const struct ip_set_type_variant mtype = {
.kadt = mtype_kadt,
.uadt = mtype_uadt,
@ -303,6 +310,7 @@ static const struct ip_set_type_variant mtype = {
.head = mtype_head,
.list = mtype_list,
.same_set = mtype_same_set,
.cancel_gc = mtype_cancel_gc,
};
#endif /* __IP_SET_BITMAP_IP_GEN_H */

View File

@ -1182,6 +1182,14 @@ ip_set_destroy_set(struct ip_set *set)
kfree(set);
}
static void
ip_set_destroy_set_rcu(struct rcu_head *head)
{
struct ip_set *set = container_of(head, struct ip_set, rcu);
ip_set_destroy_set(set);
}
static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
const struct nlattr * const attr[])
{
@ -1193,8 +1201,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
if (unlikely(protocol_min_failed(attr)))
return -IPSET_ERR_PROTOCOL;
/* Must wait for flush to be really finished in list:set */
rcu_barrier();
/* Commands are serialized and references are
* 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,
* counter, so if it's already zero, we can proceed
* without holding the lock.
*/
read_lock_bh(&ip_set_ref_lock);
if (!attr[IPSET_ATTR_SETNAME]) {
/* Must wait for flush to be really finished in list:set */
rcu_barrier();
read_lock_bh(&ip_set_ref_lock);
for (i = 0; i < inst->ip_set_max; i++) {
s = ip_set(inst, i);
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,
s = ip_set(inst, i);
if (s) {
ip_set(inst, i) = NULL;
/* Must cancel garbage collectors */
s->variant->cancel_gc(s);
ip_set_destroy_set(s);
}
}
@ -1228,6 +1238,9 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
inst->is_destroyed = false;
} else {
u32 flags = flag_exist(info->nlh);
u16 features = 0;
read_lock_bh(&ip_set_ref_lock);
s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]),
&i);
if (!s) {
@ -1238,10 +1251,16 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
ret = -IPSET_ERR_BUSY;
goto out;
}
features = s->type->features;
ip_set(inst, i) = NULL;
read_unlock_bh(&ip_set_ref_lock);
ip_set_destroy_set(s);
if (features & IPSET_TYPE_NAME) {
/* Must wait for flush to be really finished */
rcu_barrier();
}
/* Must cancel garbage collectors */
s->variant->cancel_gc(s);
call_rcu(&s->rcu, ip_set_destroy_set_rcu);
}
return 0;
out:
@ -1394,9 +1413,6 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info,
ip_set(inst, to_id) = from;
write_unlock_bh(&ip_set_ref_lock);
/* Make sure all readers of the old set pointers are completed. */
synchronize_rcu();
return 0;
}
@ -2409,8 +2425,11 @@ ip_set_fini(void)
{
nf_unregister_sockopt(&so_set);
nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
unregister_pernet_subsys(&ip_set_net_ops);
/* Wait for call_rcu() in destroy */
rcu_barrier();
pr_debug("these are the famous last words\n");
}

View File

@ -222,6 +222,7 @@ static const union nf_inet_addr zeromask = {};
#undef mtype_gc_do
#undef mtype_gc
#undef mtype_gc_init
#undef mtype_cancel_gc
#undef mtype_variant
#undef mtype_data_match
@ -266,6 +267,7 @@ static const union nf_inet_addr zeromask = {};
#define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do)
#define mtype_gc IPSET_TOKEN(MTYPE, _gc)
#define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init)
#define mtype_cancel_gc IPSET_TOKEN(MTYPE, _cancel_gc)
#define mtype_variant IPSET_TOKEN(MTYPE, _variant)
#define mtype_data_match IPSET_TOKEN(MTYPE, _data_match)
@ -450,9 +452,6 @@ mtype_destroy(struct ip_set *set)
struct htype *h = set->data;
struct list_head *l, *lt;
if (SET_WITH_TIMEOUT(set))
cancel_delayed_work_sync(&h->gc.dwork);
mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true);
list_for_each_safe(l, lt, &h->ad) {
list_del(l);
@ -599,6 +598,15 @@ mtype_gc_init(struct htable_gc *gc)
queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ);
}
static void
mtype_cancel_gc(struct ip_set *set)
{
struct htype *h = set->data;
if (SET_WITH_TIMEOUT(set))
cancel_delayed_work_sync(&h->gc.dwork);
}
static int
mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
struct ip_set_ext *mext, u32 flags);
@ -1441,6 +1449,7 @@ static const struct ip_set_type_variant mtype_variant = {
.uref = mtype_uref,
.resize = mtype_resize,
.same_set = mtype_same_set,
.cancel_gc = mtype_cancel_gc,
.region_lock = true,
};

View File

@ -426,9 +426,6 @@ list_set_destroy(struct ip_set *set)
struct list_set *map = set->data;
struct set_elem *e, *n;
if (SET_WITH_TIMEOUT(set))
timer_shutdown_sync(&map->gc);
list_for_each_entry_safe(e, n, &map->members, list) {
list_del(&e->list);
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)
a->extensions == b->extensions;
}
static void
list_set_cancel_gc(struct ip_set *set)
{
struct list_set *map = set->data;
if (SET_WITH_TIMEOUT(set))
timer_shutdown_sync(&map->gc);
}
static const struct ip_set_type_variant set_variant = {
.kadt = list_set_kadt,
.uadt = list_set_uadt,
@ -558,6 +564,7 @@ static const struct ip_set_type_variant set_variant = {
.head = list_set_head,
.list = list_set_list,
.same_set = list_set_same_set,
.cancel_gc = list_set_cancel_gc,
};
static void

View File

@ -283,7 +283,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
pr_debug("Setting vtag %x for secondary conntrack\n",
sh->vtag);
ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag;
} else {
} else if (sch->type == SCTP_CID_SHUTDOWN_ACK) {
/* If it is a shutdown ack OOTB packet, we expect a return
shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
pr_debug("Setting vtag %x for new conn OOTB\n",

View File

@ -457,7 +457,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender,
const struct sk_buff *skb,
unsigned int dataoff,
const struct tcphdr *tcph,
u32 end, u32 win)
u32 end, u32 win,
enum ip_conntrack_dir dir)
{
/* SYN-ACK in reply to a SYN
* or SYN from reply direction in simultaneous open.
@ -471,7 +472,8 @@ static void tcp_init_sender(struct ip_ct_tcp_state *sender,
* Both sides must send the Window Scale option
* to enable window scaling in either direction.
*/
if (!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
if (dir == IP_CT_DIR_REPLY &&
!(sender->flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE)) {
sender->td_scale = 0;
receiver->td_scale = 0;
@ -542,7 +544,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir,
if (tcph->syn) {
tcp_init_sender(sender, receiver,
skb, dataoff, tcph,
end, win);
end, win, dir);
if (!tcph->ack)
/* Simultaneous open */
return NFCT_TCP_ACCEPT;
@ -585,7 +587,7 @@ tcp_in_window(struct nf_conn *ct, enum ip_conntrack_dir dir,
*/
tcp_init_sender(sender, receiver,
skb, dataoff, tcph,
end, win);
end, win, dir);
if (dir == IP_CT_DIR_REPLY && !tcph->ack)
return NFCT_TCP_ACCEPT;

View File

@ -193,11 +193,12 @@ void nf_logger_put(int pf, enum nf_log_type type)
return;
}
BUG_ON(loggers[pf][type] == NULL);
rcu_read_lock();
logger = rcu_dereference(loggers[pf][type]);
module_put(logger->me);
if (!logger)
WARN_ON_ONCE(1);
else
module_put(logger->me);
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(nf_logger_put);

View File

@ -7551,11 +7551,15 @@ static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
return -1;
}
static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
static const struct nft_object_type *__nft_obj_type_get(u32 objtype, u8 family)
{
const struct nft_object_type *type;
list_for_each_entry(type, &nf_tables_objects, list) {
if (type->family != NFPROTO_UNSPEC &&
type->family != family)
continue;
if (objtype == type->type)
return type;
}
@ -7563,11 +7567,11 @@ static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
}
static const struct nft_object_type *
nft_obj_type_get(struct net *net, u32 objtype)
nft_obj_type_get(struct net *net, u32 objtype, u8 family)
{
const struct nft_object_type *type;
type = __nft_obj_type_get(objtype);
type = __nft_obj_type_get(objtype, family);
if (type != NULL && try_module_get(type->owner))
return type;
@ -7660,7 +7664,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info,
if (info->nlh->nlmsg_flags & NLM_F_REPLACE)
return -EOPNOTSUPP;
type = __nft_obj_type_get(objtype);
type = __nft_obj_type_get(objtype, family);
if (WARN_ON_ONCE(!type))
return -ENOENT;
@ -7674,7 +7678,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info,
if (!nft_use_inc(&table->use))
return -EMFILE;
type = nft_obj_type_get(net, objtype);
type = nft_obj_type_get(net, objtype, family);
if (IS_ERR(type)) {
err = PTR_ERR(type);
goto err_type;

View File

@ -1250,7 +1250,31 @@ static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
if (tb[NFTA_CT_EXPECT_L3PROTO])
priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO]));
switch (priv->l3num) {
case NFPROTO_IPV4:
case NFPROTO_IPV6:
if (priv->l3num != ctx->family)
return -EINVAL;
fallthrough;
case NFPROTO_INET:
break;
default:
return -EOPNOTSUPP;
}
priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
switch (priv->l4proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_DCCP:
case IPPROTO_SCTP:
break;
default:
return -EOPNOTSUPP;
}
priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]);
priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]);

View File

@ -713,6 +713,7 @@ static const struct nft_object_ops nft_tunnel_obj_ops = {
static struct nft_object_type nft_tunnel_obj_type __read_mostly = {
.type = NFT_OBJECT_TUNNEL,
.family = NFPROTO_NETDEV,
.ops = &nft_tunnel_obj_ops,
.maxattr = NFTA_TUNNEL_KEY_MAX,
.policy = nft_tunnel_key_policy,

View File

@ -1208,6 +1208,10 @@ void nci_free_device(struct nci_dev *ndev)
{
nfc_free_device(ndev->nfc_dev);
nci_hci_deallocate(ndev);
/* drop partial rx data packet if present */
if (ndev->rx_data_reassembly)
kfree_skb(ndev->rx_data_reassembly);
kfree(ndev);
}
EXPORT_SYMBOL(nci_free_device);

View File

@ -1877,9 +1877,15 @@ static bool smcd_lgr_match(struct smc_link_group *lgr,
struct smcd_dev *smcismdev,
struct smcd_gid *peer_gid)
{
return lgr->peer_gid.gid == peer_gid->gid && lgr->smcd == smcismdev &&
smc_ism_is_virtual(smcismdev) ?
(lgr->peer_gid.gid_ext == peer_gid->gid_ext) : 1;
if (lgr->peer_gid.gid != peer_gid->gid ||
lgr->smcd != smcismdev)
return false;
if (smc_ism_is_virtual(smcismdev) &&
lgr->peer_gid.gid_ext != peer_gid->gid_ext)
return false;
return true;
}
/* create a new SMC connection (and a new link group if necessary) */

View File

@ -1344,13 +1344,11 @@ static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
unix_state_lock(sk1);
return;
}
if (sk1 < sk2) {
unix_state_lock(sk1);
unix_state_lock_nested(sk2);
} else {
unix_state_lock(sk2);
unix_state_lock_nested(sk1);
}
if (sk1 > sk2)
swap(sk1, sk2);
unix_state_lock(sk1);
unix_state_lock_nested(sk2, U_LOCK_SECOND);
}
static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
@ -1591,7 +1589,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
goto out_unlock;
}
unix_state_lock_nested(sk);
unix_state_lock_nested(sk, U_LOCK_SECOND);
if (sk->sk_state != st) {
unix_state_unlock(sk);

View File

@ -84,7 +84,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
* queue lock. With the other's queue locked it's
* OK to lock the state.
*/
unix_state_lock_nested(req);
unix_state_lock_nested(req, U_LOCK_DIAG);
peer = unix_sk(req)->peer;
buf[i++] = (peer ? sock_i_ino(peer) : 0);
unix_state_unlock(req);

View File

@ -48,6 +48,17 @@ test_LAG_cleanup()
ip link add mv0 link "$name" up address "$ucaddr" type macvlan
# Used to test dev->mc handling
ip address add "$addr6" dev "$name"
# Check that addresses were added as expected
(grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy1 ||
grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy2) >/dev/null
check_err $? "macvlan unicast address not found on a slave"
# mcaddr is added asynchronously by addrconf_dad_work(), use busywait
(busywait 10000 grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy1 ||
grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy2) >/dev/null
check_err $? "IPv6 solicited-node multicast mac address not found on a slave"
ip link set dev "$name" down
ip link del "$name"

View File

@ -1,3 +1,5 @@
CONFIG_DUMMY=y
CONFIG_IPV6=y
CONFIG_MACVLAN=y
CONFIG_NET_TEAM=y
CONFIG_NET_TEAM_MODE_LOADBALANCE=y
CONFIG_MACVLAN=y

View File

@ -53,8 +53,7 @@ TEST_PROGS += bind_bhash.sh
TEST_PROGS += ip_local_port_range.sh
TEST_PROGS += rps_default_mask.sh
TEST_PROGS += big_tcp.sh
TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh
TEST_PROGS_EXTENDED += toeplitz_client.sh toeplitz.sh lib.sh
TEST_PROGS_EXTENDED := toeplitz_client.sh toeplitz.sh
TEST_GEN_FILES = socket nettest
TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite
@ -84,6 +83,7 @@ TEST_PROGS += sctp_vrf.sh
TEST_GEN_FILES += sctp_hello
TEST_GEN_FILES += csum
TEST_GEN_FILES += nat6to4.o
TEST_GEN_FILES += xdp_dummy.o
TEST_GEN_FILES += ip_local_port_range
TEST_GEN_FILES += bind_wildcard
TEST_PROGS += test_vxlan_mdb.sh
@ -95,6 +95,7 @@ TEST_PROGS += fq_band_pktlimit.sh
TEST_PROGS += vlan_hw_filter.sh
TEST_FILES := settings
TEST_FILES += in_netns.sh lib.sh net_helper.sh setup_loopback.sh setup_veth.sh
include ../lib.mk
@ -104,7 +105,7 @@ $(OUTPUT)/tcp_inq: LDLIBS += -lpthread
$(OUTPUT)/bind_bhash: LDLIBS += -lpthread
$(OUTPUT)/io_uring_zerocopy_tx: CFLAGS += -I../../../include/
# Rules to generate bpf obj nat6to4.o
# Rules to generate bpf objs
CLANG ?= clang
SCRATCH_DIR := $(OUTPUT)/tools
BUILD_DIR := $(SCRATCH_DIR)/build
@ -139,7 +140,7 @@ endif
CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH))
$(OUTPUT)/nat6to4.o: nat6to4.c $(BPFOBJ) | $(MAKE_DIRS)
$(OUTPUT)/nat6to4.o $(OUTPUT)/xdp_dummy.o: $(OUTPUT)/%.o : %.c $(BPFOBJ) | $(MAKE_DIRS)
$(CLANG) -O2 --target=bpf -c $< $(CCINCLUDE) $(CLANG_SYS_INCLUDES) -o $@
$(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \

View File

@ -19,8 +19,11 @@ CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE=y
CONFIG_CRYPTO_CHACHA20POLY1305=m
CONFIG_VLAN_8021Q=y
CONFIG_GENEVE=m
CONFIG_IFB=y
CONFIG_INET_DIAG=y
CONFIG_INET_ESP=y
CONFIG_INET_ESP_OFFLOAD=y
CONFIG_IP_GRE=m
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
@ -29,7 +32,10 @@ CONFIG_NF_NAT=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IPV6_GRE=m
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_L2TP_ETH=m
@ -45,8 +51,14 @@ CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_IPV6=y
CONFIG_NF_TABLES_IPV4=y
CONFIG_NFT_NAT=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NET_ACT_CSUM=m
CONFIG_NET_ACT_CT=m
CONFIG_NET_ACT_GACT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_MATCHALL=m
CONFIG_NET_CLS_U32=m
CONFIG_NET_IPGRE_DEMUX=m
CONFIG_NET_IPGRE=m
@ -55,6 +67,9 @@ CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_FQ=m
CONFIG_NET_SCH_ETF=m
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_PRIO=m
CONFIG_NFT_COMPAT=m
CONFIG_NF_FLOW_TABLE=m
CONFIG_PSAMPLE=m
CONFIG_TCP_MD5SIG=y
CONFIG_TEST_BLACKHOLE_DEV=m
@ -80,3 +95,4 @@ CONFIG_IP_SCTP=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_CRYPTO_ARIA=y
CONFIG_XFRM_INTERFACE=m
CONFIG_XFRM_USER=m

View File

@ -112,7 +112,7 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \
vxlan_symmetric_ipv6.sh \
vxlan_symmetric.sh
TEST_PROGS_EXTENDED := devlink_lib.sh \
TEST_FILES := devlink_lib.sh \
ethtool_lib.sh \
fib_offload_lib.sh \
forwarding.config.sample \

View File

@ -4,6 +4,9 @@
##############################################################################
# Defines
WAIT_TIMEOUT=${WAIT_TIMEOUT:=20}
BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
# namespace list created by setup_ns
@ -48,7 +51,7 @@ cleanup_ns()
for ns in "$@"; do
ip netns delete "${ns}" &> /dev/null
if ! busywait 2 ip netns list \| grep -vq "^$ns$" &> /dev/null; then
if ! busywait $BUSYWAIT_TIMEOUT ip netns list \| grep -vq "^$ns$" &> /dev/null; then
echo "Warn: Failed to remove namespace $ns"
ret=1
fi

View File

@ -22,8 +22,11 @@ CONFIG_NFT_TPROXY=m
CONFIG_NFT_SOCKET=m
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IP6_NF_FILTER=m
CONFIG_NET_ACT_CSUM=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_CLS_ACT=y

View File

@ -643,13 +643,6 @@ kill_events_pids()
mptcp_lib_kill_wait $evts_ns2_pid
}
kill_tests_wait()
{
#shellcheck disable=SC2046
kill -SIGUSR1 $(ip netns pids $ns2) $(ip netns pids $ns1)
wait
}
pm_nl_set_limits()
{
local ns=$1
@ -3453,7 +3446,7 @@ userspace_tests()
chk_mptcp_info subflows 0 subflows 0
chk_subflows_total 1 1
kill_events_pids
wait $tests_pid
mptcp_lib_kill_wait $tests_pid
fi
# userspace pm create destroy subflow
@ -3475,7 +3468,7 @@ userspace_tests()
chk_mptcp_info subflows 0 subflows 0
chk_subflows_total 1 1
kill_events_pids
wait $tests_pid
mptcp_lib_kill_wait $tests_pid
fi
# userspace pm create id 0 subflow
@ -3494,7 +3487,7 @@ userspace_tests()
chk_mptcp_info subflows 1 subflows 1
chk_subflows_total 2 2
kill_events_pids
wait $tests_pid
mptcp_lib_kill_wait $tests_pid
fi
# userspace pm remove initial subflow
@ -3518,7 +3511,7 @@ userspace_tests()
chk_mptcp_info subflows 1 subflows 1
chk_subflows_total 1 1
kill_events_pids
wait $tests_pid
mptcp_lib_kill_wait $tests_pid
fi
# userspace pm send RM_ADDR for ID 0
@ -3544,7 +3537,7 @@ userspace_tests()
chk_mptcp_info subflows 1 subflows 1
chk_subflows_total 1 1
kill_events_pids
wait $tests_pid
mptcp_lib_kill_wait $tests_pid
fi
}
@ -3558,7 +3551,8 @@ endpoint_tests()
pm_nl_set_limits $ns2 2 2
pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
speed=slow \
run_tests $ns1 $ns2 10.0.1.1 2>/dev/null &
run_tests $ns1 $ns2 10.0.1.1 &
local tests_pid=$!
wait_mpj $ns1
pm_nl_check_endpoint "creation" \
@ -3573,7 +3567,7 @@ endpoint_tests()
pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
pm_nl_check_endpoint "modif is allowed" \
$ns2 10.0.2.2 id 1 flags signal
kill_tests_wait
mptcp_lib_kill_wait $tests_pid
fi
if reset "delete and re-add" &&
@ -3582,7 +3576,8 @@ endpoint_tests()
pm_nl_set_limits $ns2 1 1
pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow
test_linkfail=4 speed=20 \
run_tests $ns1 $ns2 10.0.1.1 2>/dev/null &
run_tests $ns1 $ns2 10.0.1.1 &
local tests_pid=$!
wait_mpj $ns2
chk_subflow_nr "before delete" 2
@ -3597,7 +3592,7 @@ endpoint_tests()
wait_mpj $ns2
chk_subflow_nr "after re-add" 2
chk_mptcp_info subflows 1 subflows 1
kill_tests_wait
mptcp_lib_kill_wait $tests_pid
fi
}

View File

@ -6,7 +6,7 @@ readonly KSFT_FAIL=1
readonly KSFT_SKIP=4
# shellcheck disable=SC2155 # declare and assign separately
readonly KSFT_TEST=$(basename "${0}" | sed 's/\.sh$//g')
readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}"
MPTCP_LIB_SUBTESTS=()

View File

@ -1 +1 @@
timeout=1200
timeout=1800

View File

@ -284,12 +284,12 @@ done
setup
run_test 10 10 0 0 "balanced bwidth"
run_test 10 10 1 50 "balanced bwidth with unbalanced delay"
run_test 10 10 1 25 "balanced bwidth with unbalanced delay"
# we still need some additional infrastructure to pass the following test-cases
run_test 30 10 0 0 "unbalanced bwidth"
run_test 30 10 1 50 "unbalanced bwidth with unbalanced delay"
run_test 30 10 50 1 "unbalanced bwidth with opposed, unbalanced delay"
run_test 10 3 0 0 "unbalanced bwidth"
run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay"
run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay"
mptcp_lib_result_print_all_tap
exit $ret

0
tools/testing/selftests/net/net_helper.sh Executable file → Normal file
View File

View File

@ -707,23 +707,23 @@ setup_xfrm6() {
}
setup_xfrm4udp() {
setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0"
setup_nettest_xfrm 4 4500
setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \
setup_nettest_xfrm 4 4500
}
setup_xfrm6udp() {
setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0"
setup_nettest_xfrm 6 4500
setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \
setup_nettest_xfrm 6 4500
}
setup_xfrm4udprouted() {
setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0"
setup_nettest_xfrm 4 4500
setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" && \
setup_nettest_xfrm 4 4500
}
setup_xfrm6udprouted() {
setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0"
setup_nettest_xfrm 6 4500
setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" && \
setup_nettest_xfrm 6 4500
}
setup_routing_old() {
@ -1339,7 +1339,7 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() {
sleep 1
dd if=/dev/zero of=/dev/stdout status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3
dd if=/dev/zero status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3
size=$(du -sb $tmpoutfile)
size=${size%%/tmp/*}

0
tools/testing/selftests/net/setup_loopback.sh Executable file → Normal file
View File

View File

@ -11,7 +11,7 @@ setup_veth_ns() {
local -r ns_mac="$4"
[[ -e /var/run/netns/"${ns_name}" ]] || ip netns add "${ns_name}"
echo 100000 > "/sys/class/net/${ns_dev}/gro_flush_timeout"
echo 1000000 > "/sys/class/net/${ns_dev}/gro_flush_timeout"
ip link set dev "${ns_dev}" netns "${ns_name}" mtu 65535
ip -netns "${ns_name}" link set dev "${ns_dev}" up

View File

@ -0,0 +1,10 @@
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_RMD160=y
CONFIG_CRYPTO_SHA1=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_NET_VRF=y
CONFIG_TCP_AO=y
CONFIG_TCP_MD5SIG=y
CONFIG_VETH=m

View File

@ -417,9 +417,9 @@ struct test_key {
matches_vrf : 1,
is_current : 1,
is_rnext : 1,
used_on_handshake : 1,
used_after_accept : 1,
used_on_client : 1;
used_on_server_tx : 1,
used_on_client_tx : 1,
skip_counters_checks : 1;
};
struct key_collection {
@ -609,16 +609,14 @@ static int key_collection_socket(bool server, unsigned int port)
addr = &this_ip_dest;
sndid = key->client_keyid;
rcvid = key->server_keyid;
set_current = key->is_current;
set_rnext = key->is_rnext;
key->used_on_client_tx = set_current = key->is_current;
key->used_on_server_tx = set_rnext = key->is_rnext;
}
if (test_add_key_cr(sk, key->password, key->len,
*addr, vrf, sndid, rcvid, key->maclen,
key->alg, set_current, set_rnext))
test_key_error("setsockopt(TCP_AO_ADD_KEY)", key);
if (set_current || set_rnext)
key->used_on_handshake = 1;
#ifdef DEBUG
test_print("%s [%u/%u] key: { %s, %u:%u, %u, %u:%u:%u:%u (%u)}",
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
for (i = 0; i < collection.nr_keys; i++) {
struct test_key *key = &collection.keys[i];
uint8_t sndid, rcvid;
bool was_used;
bool rx_cnt_expected;
if (key->skip_counters_checks)
continue;
if (server) {
sndid = key->server_keyid;
rcvid = key->client_keyid;
if (is_listen_sk)
was_used = key->used_on_handshake;
else
was_used = key->used_after_accept;
rx_cnt_expected = key->used_on_client_tx;
} else {
sndid = key->client_keyid;
rcvid = key->server_keyid;
was_used = key->used_on_client;
rx_cnt_expected = key->used_on_server_tx;
}
test_tcp_ao_key_counters_cmp(tst_name, a, b, was_used,
test_tcp_ao_key_counters_cmp(tst_name, a, b,
rx_cnt_expected ? TEST_CNT_KEY_GOOD : 0,
sndid, rcvid);
}
test_tcp_ao_counters_free(a);
@ -843,7 +841,7 @@ static void end_server(const char *tst_name, int sk,
synchronize_threads(); /* 4: verified => closed */
close(sk);
verify_counters(tst_name, true, false, begin, &end);
verify_counters(tst_name, false, true, begin, &end);
synchronize_threads(); /* 5: counters */
}
@ -916,9 +914,8 @@ static int run_client(const char *tst_name, unsigned int port,
current_index = nr_keys - 1;
if (rnext_index < 0)
rnext_index = nr_keys - 1;
collection.keys[current_index].used_on_handshake = 1;
collection.keys[rnext_index].used_after_accept = 1;
collection.keys[rnext_index].used_on_client = 1;
collection.keys[current_index].used_on_client_tx = 1;
collection.keys[rnext_index].used_on_server_tx = 1;
synchronize_threads(); /* 3: accepted => send data */
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,
test_error("Can't change the current key");
if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC))
test_fail("verify failed");
collection.keys[rotate_to_index].used_after_accept = 1;
/* There is a race here: between setting the current_key with
* setsockopt(TCP_AO_INFO) and starting to send some data - there
* might have been a segment received with the desired
* RNext_key set. In turn that would mean that the first outgoing
* segment will have the desired current_key (flipped back).
* Which is what the user/test wants. As it's racy, skip checking
* the counters, yet check what are the resulting current/rnext
* keys on both sides.
*/
collection.keys[rotate_to_index].skip_counters_checks = 1;
end_client(tst_name, sk, nr_keys, current_index, rnext_index, &tmp);
}
@ -1089,7 +1095,7 @@ static void roll_over_keys(const char *tst_name, unsigned int port,
}
verify_current_rnext(tst_name, sk, -1,
collection.keys[i].server_keyid);
collection.keys[i].used_on_client = 1;
collection.keys[i].used_on_server_tx = 1;
synchronize_threads(); /* verify current/rnext */
}
end_client(tst_name, sk, nr_keys, current_index, rnext_index, &tmp);

View File

@ -62,7 +62,9 @@ int test_wait_fd(int sk, time_t sec, bool write)
return -ETIMEDOUT;
}
if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &slen) || ret)
if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &slen))
return -errno;
if (ret)
return -ret;
return 0;
}
@ -584,9 +586,11 @@ int test_client_verify(int sk, const size_t msg_len, const size_t nr,
{
size_t buf_sz = msg_len * nr;
char *buf = alloca(buf_sz);
ssize_t ret;
randomize_buffer(buf, buf_sz);
if (test_client_loop(sk, buf, buf_sz, msg_len, timeout_sec) != buf_sz)
return -1;
return 0;
ret = test_client_loop(sk, buf, buf_sz, msg_len, timeout_sec);
if (ret < 0)
return (int)ret;
return ret != buf_sz ? -1 : 0;
}

View File

@ -1,10 +1,33 @@
// SPDX-License-Identifier: GPL-2.0
/* Author: Dmitry Safonov <dima@arista.com> */
/*
* The test checks that both active and passive reset have correct TCP-AO
* signature. An "active" reset (abort) here is procured from closing
* listen() socket with non-accepted connections in the queue:
* inet_csk_listen_stop() => inet_child_forget() =>
* => tcp_disconnect() => tcp_send_active_reset()
*
* The passive reset is quite hard to get on established TCP connections.
* It could be procured from non-established states, but the synchronization
* part from userspace in order to reliably get RST seems uneasy.
* So, instead it's procured by corrupting SEQ number on TIMED-WAIT state.
*
* It's important to test both passive and active RST as they go through
* different code-paths:
* - tcp_send_active_reset() makes no-data skb, sends it with tcp_transmit_skb()
* - tcp_v*_send_reset() create their reply skbs and send them with
* ip_send_unicast_reply()
*
* In both cases TCP-AO signatures have to be correct, which is verified by
* (1) checking that the TCP-AO connection was reset and (2) TCP-AO counters.
*
* Author: Dmitry Safonov <dima@arista.com>
*/
#include <inttypes.h>
#include "../../../../include/linux/kernel.h"
#include "aolib.h"
const size_t quota = 1000;
const size_t packet_sz = 100;
/*
* Backlog == 0 means 1 connection in queue, see:
* commit 64a146513f8f ("[NET]: Revert incorrect accept queue...")
@ -59,26 +82,6 @@ static void close_forced(int sk)
close(sk);
}
static int test_wait_for_exception(int sk, time_t sec)
{
struct timeval tv = { .tv_sec = sec };
struct timeval *ptv = NULL;
fd_set efds;
int ret;
FD_ZERO(&efds);
FD_SET(sk, &efds);
if (sec)
ptv = &tv;
errno = 0;
ret = select(sk + 1, NULL, NULL, &efds, ptv);
if (ret < 0)
return -errno;
return ret ? sk : 0;
}
static void test_server_active_rst(unsigned int port)
{
struct tcp_ao_counters cnt1, cnt2;
@ -155,17 +158,16 @@ static void test_server_passive_rst(unsigned int port)
test_fail("server returned %zd", bytes);
}
synchronize_threads(); /* 3: chekpoint/restore the connection */
synchronize_threads(); /* 3: checkpoint the client */
synchronize_threads(); /* 4: close the server, creating twsk */
if (test_get_tcp_ao_counters(sk, &ao2))
test_error("test_get_tcp_ao_counters()");
synchronize_threads(); /* 4: terminate server + send more on client */
bytes = test_server_run(sk, quota, TEST_RETRANSMIT_SEC);
close(sk);
synchronize_threads(); /* 5: restore the socket, send more data */
test_tcp_ao_counters_cmp("passive RST server", &ao1, &ao2, TEST_CNT_GOOD);
synchronize_threads(); /* 5: verified => closed */
close(sk);
synchronize_threads(); /* 6: server exits */
}
static void *server_fn(void *arg)
@ -284,7 +286,7 @@ static void test_client_active_rst(unsigned int port)
test_error("test_wait_fds(): %d", err);
synchronize_threads(); /* 3: close listen socket */
if (test_client_verify(sk[0], 100, quota / 100, TEST_TIMEOUT_SEC))
if (test_client_verify(sk[0], packet_sz, quota / packet_sz, TEST_TIMEOUT_SEC))
test_fail("Failed to send data on connected socket");
else
test_ok("Verified established tcp connection");
@ -323,7 +325,6 @@ static void test_client_passive_rst(unsigned int port)
struct tcp_sock_state img;
sockaddr_af saddr;
int sk, err;
socklen_t slen = sizeof(err);
sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0)
@ -337,18 +338,51 @@ static void test_client_passive_rst(unsigned int port)
test_error("failed to connect()");
synchronize_threads(); /* 2: accepted => send data */
if (test_client_verify(sk, 100, quota / 100, TEST_TIMEOUT_SEC))
if (test_client_verify(sk, packet_sz, quota / packet_sz, TEST_TIMEOUT_SEC))
test_fail("Failed to send data on connected socket");
else
test_ok("Verified established tcp connection");
synchronize_threads(); /* 3: chekpoint/restore the connection */
synchronize_threads(); /* 3: checkpoint the client */
test_enable_repair(sk);
test_sock_checkpoint(sk, &img, &saddr);
test_ao_checkpoint(sk, &ao_img);
test_kill_sk(sk);
test_disable_repair(sk);
img.out.seq += quota;
synchronize_threads(); /* 4: close the server, creating twsk */
/*
* The "corruption" in SEQ has to be small enough to fit into TCP
* window, see tcp_timewait_state_process() for out-of-window
* segments.
*/
img.out.seq += 5; /* 5 is more noticeable in tcpdump than 1 */
/*
* FIXME: This is kind-of ugly and dirty, but it works.
*
* At this moment, the server has close'ed(sk).
* The passive RST that is being targeted here is new data after
* half-duplex close, see tcp_timewait_state_process() => TCP_TW_RST
*
* What is needed here is:
* (1) wait for FIN from the server
* (2) make sure that the ACK from the client went out
* (3) make sure that the ACK was received and processed by the server
*
* Otherwise, the data that will be sent from "repaired" socket
* post SEQ corruption may get to the server before it's in
* TCP_FIN_WAIT2.
*
* (1) is easy with select()/poll()
* (2) is possible by polling tcpi_state from TCP_INFO
* (3) is quite complex: as server's socket was already closed,
* probably the way to do it would be tcp-diag.
*/
sleep(TEST_RETRANSMIT_SEC);
synchronize_threads(); /* 5: restore the socket, send more data */
test_kill_sk(sk);
sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0)
@ -366,25 +400,33 @@ static void test_client_passive_rst(unsigned int port)
test_disable_repair(sk);
test_sock_state_free(&img);
synchronize_threads(); /* 4: terminate server + send more on client */
if (test_client_verify(sk, 100, quota / 100, 2 * TEST_TIMEOUT_SEC))
test_ok("client connection broken post-seq-adjust");
/*
* This is how "passive reset" is acquired in this test from TCP_TW_RST:
*
* IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [P.], seq 901:1001, ack 1001, win 249,
* options [tcp-ao keyid 100 rnextkeyid 100 mac 0x10217d6c36a22379086ef3b1], length 100
* IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [F.], seq 1001, ack 1001, win 249,
* options [tcp-ao keyid 100 rnextkeyid 100 mac 0x104ffc99b98c10a5298cc268], length 0
* IP 10.0.1.1.59772 > 10.0.254.1.7011: Flags [.], ack 1002, win 251,
* options [tcp-ao keyid 100 rnextkeyid 100 mac 0xe496dd4f7f5a8a66873c6f93,nop,nop,sack 1 {1001:1002}], length 0
* IP 10.0.1.1.59772 > 10.0.254.1.7011: Flags [P.], seq 1006:1106, ack 1001, win 251,
* options [tcp-ao keyid 100 rnextkeyid 100 mac 0x1b5f3330fb23fbcd0c77d0ca], length 100
* IP 10.0.254.1.7011 > 10.0.1.1.59772: Flags [R], seq 3215596252, win 0,
* options [tcp-ao keyid 100 rnextkeyid 100 mac 0x0bcfbbf497bce844312304b2], length 0
*/
err = test_client_verify(sk, packet_sz, quota / packet_sz, 2 * TEST_TIMEOUT_SEC);
/* Make sure that the connection was reset, not timeouted */
if (err && err == -ECONNRESET)
test_ok("client sock was passively reset post-seq-adjust");
else if (err)
test_fail("client sock was not reset post-seq-adjust: %d", err);
else
test_fail("client connection still works post-seq-adjust");
test_wait_for_exception(sk, TEST_TIMEOUT_SEC);
if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &slen))
test_error("getsockopt()");
if (err != ECONNRESET && err != EPIPE)
test_fail("client connection was not reset: %d", err);
else
test_ok("client connection was reset");
test_fail("client sock is yet connected post-seq-adjust");
if (test_get_tcp_ao_counters(sk, &ao2))
test_error("test_get_tcp_ao_counters()");
synchronize_threads(); /* 5: verified => closed */
synchronize_threads(); /* 6: server exits */
close(sk);
test_tcp_ao_counters_cmp("client passive RST", &ao1, &ao2, TEST_CNT_GOOD);
}
@ -410,6 +452,6 @@ static void *client_fn(void *arg)
int main(int argc, char *argv[])
{
test_init(15, server_fn, client_fn);
test_init(14, server_fn, client_fn);
return 0;
}

View File

@ -0,0 +1 @@
timeout=120

View File

@ -7,7 +7,7 @@ source net_helper.sh
readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)"
BPF_FILE="../bpf/xdp_dummy.bpf.o"
BPF_FILE="xdp_dummy.o"
# set global exit status, but never reset nonzero one.
check_err()
@ -197,7 +197,7 @@ run_all() {
}
if [ ! -f ${BPF_FILE} ]; then
echo "Missing ${BPF_FILE}. Build bpf selftest first"
echo "Missing ${BPF_FILE}. Run 'make' first"
exit -1
fi

View File

@ -7,7 +7,7 @@ source net_helper.sh
readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)"
BPF_FILE="../bpf/xdp_dummy.bpf.o"
BPF_FILE="xdp_dummy.o"
cleanup() {
local -r jobs="$(jobs -p)"
@ -84,7 +84,7 @@ run_all() {
}
if [ ! -f ${BPF_FILE} ]; then
echo "Missing ${BPF_FILE}. Build bpf selftest first"
echo "Missing ${BPF_FILE}. Run 'make' first"
exit -1
fi

View File

@ -7,7 +7,7 @@ source net_helper.sh
readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)"
BPF_FILE="../bpf/xdp_dummy.bpf.o"
BPF_FILE="xdp_dummy.o"
cleanup() {
local -r jobs="$(jobs -p)"
@ -85,12 +85,12 @@ run_all() {
}
if [ ! -f ${BPF_FILE} ]; then
echo "Missing ${BPF_FILE}. Build bpf selftest first"
echo "Missing ${BPF_FILE}. Run 'make' first"
exit -1
fi
if [ ! -f nat6to4.o ]; then
echo "Missing nat6to4 helper. Build bpf nat6to4.o selftest first"
echo "Missing nat6to4 helper. Run 'make' first"
exit -1
fi

View File

@ -1,7 +1,9 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
BPF_FILE="../bpf/xdp_dummy.bpf.o"
source net_helper.sh
BPF_FILE="xdp_dummy.o"
readonly BASE="ns-$(mktemp -u XXXXXX)"
readonly SRC=2
readonly DST=1
@ -119,7 +121,7 @@ run_test() {
ip netns exec $NS_DST $ipt -A INPUT -p udp --dport 8000
ip netns exec $NS_DST ./udpgso_bench_rx -C 1000 -R 10 -n 10 -l 1300 $rx_args &
local spid=$!
sleep 0.1
wait_local_port_listen "$NS_DST" 8000 udp
ip netns exec $NS_SRC ./udpgso_bench_tx $family -M 1 -s 13000 -S 1300 -D $dst
local retc=$?
wait $spid
@ -168,7 +170,7 @@ run_bench() {
ip netns exec $NS_DST bash -c "echo 2 > /sys/class/net/veth$DST/queues/rx-0/rps_cpus"
ip netns exec $NS_DST taskset 0x2 ./udpgso_bench_rx -C 1000 -R 10 &
local spid=$!
sleep 0.1
wait_local_port_listen "$NS_DST" 8000 udp
ip netns exec $NS_SRC taskset 0x1 ./udpgso_bench_tx $family -l 3 -S 1300 -D $dst
local retc=$?
wait $spid

View File

@ -1,7 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
BPF_FILE="../bpf/xdp_dummy.bpf.o"
BPF_FILE="xdp_dummy.o"
readonly STATS="$(mktemp -p /tmp ns-XXXXXX)"
readonly BASE=`basename $STATS`
readonly SRC=2
@ -218,7 +218,7 @@ while getopts "hs:" option; do
done
if [ ! -f ${BPF_FILE} ]; then
echo "Missing ${BPF_FILE}. Build bpf selftest first"
echo "Missing ${BPF_FILE}. Run 'make' first"
exit 1
fi

View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
#define KBUILD_MODNAME "xdp_dummy"
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
SEC("xdp")
int xdp_dummy_prog(struct xdp_md *ctx)
{
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";