Including fixes from bluetooth.

Current release - regressions:
 
  - eth: bnxt_en: fix memory out-of-bounds in bnxt_fill_hw_rss_tbl()
    on older chips
 
 Current release - new code bugs:
 
  - ethtool: fix off-by-one error / kdoc contradicting the code
    for max RSS context IDs
 
  - Bluetooth: hci_qca:
     - QCA6390: fix support on non-DT platforms
     - QCA6390: don't call pwrseq_power_off() twice
     - fix a NULL-pointer derefence at shutdown
 
  - eth: ice: fix incorrect assigns of FEC counters
 
 Previous releases - regressions:
 
  - mptcp: fix handling endpoints with both 'signal' and 'subflow'
    flags set
 
  - virtio-net: fix changing ring count when vq IRQ coalescing not
    supported
 
  - eth: gve: fix use of netif_carrier_ok() during reconfig / reset
 
 Previous releases - always broken:
 
  - eth: idpf: fix bugs in queue re-allocation on reconfig / reset
 
  - ethtool: fix context creation with no parameters
 
 Misc:
 
  - linkwatch: use system_unbound_wq to ease RTNL contention
 
 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAma0+MsACgkQMUZtbf5S
 Iru7UA//e+qaQ4yYQUZnilt4L+HdlMvFGnj6YV2rlXtG2o4leoKBtrvV4Ov5Hrj+
 Lzc9Cz4DQBi3tWvaD8SR2wEPYVmUaQm2DLgxTv3NrwSwbL+yd87y6AqnrxyjLglX
 E/Lg0FKxJC3zVb4Jb6FOX9KwIP60u+kwL5pev7UbpzNU4aVpNovWKo1sICLFYC5L
 2rlCWmd2UHDSxDYIqL3nI68IqmhP5etfJnnURxIzJZInKSLRx4Evkke/3Y+Ju8CE
 LS5HIsTzYmAmgI0+LLPd9fyL8puYuw+tFGMAKSRHLAlzno2Cpre5IEucfbFhQ81+
 7RfJO+lzTvqcIj17bK+QsgAgQUxlRexdct/0KfBG6O/Ll0ptRGl475X5K8hb471r
 m3WLtNkByYznKpr6ORvNoGqTSAVJpx0Xdl0YWt5G5ANWCMi2kA51K9JOHRNfOnvZ
 dq0WMu/kwBq8XJ/l0FjB2lT41bhkOzdbfHiqi60miuixzU3e8rQbs59zHr3wmio2
 7NAVfmOPJTILHpyJ4c3DZrKNkxyXnIS04OyDo4SO6QwvJ/XbXi22/ir/3NyKgOTG
 NqIeA2Ap96n0NzqqUrRMGdSPoKW8Cbl7zNO1opHJj/l57XPMVz+g9qA5mbSCT5k1
 fNu2lURKzRLcoq5OmwySLJR2ASMfpaLpmooFYBrtftPVwl4YQvo=
 =bKTC
 -----END PGP SIGNATURE-----

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

Pull networking fixes from Jakub Kicinski:
 "Including fixes from bluetooth.

  Current release - regressions:

   - eth: bnxt_en: fix memory out-of-bounds in bnxt_fill_hw_rss_tbl() on
     older chips

  Current release - new code bugs:

   - ethtool: fix off-by-one error / kdoc contradicting the code for max
     RSS context IDs

   - Bluetooth: hci_qca:
      - QCA6390: fix support on non-DT platforms
      - QCA6390: don't call pwrseq_power_off() twice
      - fix a NULL-pointer derefence at shutdown

   - eth: ice: fix incorrect assigns of FEC counters

  Previous releases - regressions:

   - mptcp: fix handling endpoints with both 'signal' and 'subflow'
     flags set

   - virtio-net: fix changing ring count when vq IRQ coalescing not
     supported

   - eth: gve: fix use of netif_carrier_ok() during reconfig / reset

  Previous releases - always broken:

   - eth: idpf: fix bugs in queue re-allocation on reconfig / reset

   - ethtool: fix context creation with no parameters

  Misc:

   - linkwatch: use system_unbound_wq to ease RTNL contention"

* tag 'net-6.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (41 commits)
  net: dsa: microchip: disable EEE for KSZ8567/KSZ9567/KSZ9896/KSZ9897.
  ethtool: Fix context creation with no parameters
  net: ethtool: fix off-by-one error in max RSS context IDs
  net: pse-pd: tps23881: include missing bitfield.h header
  net: fec: Stop PPS on driver remove
  net: bcmgenet: Properly overlay PHY and MAC Wake-on-LAN capabilities
  l2tp: fix lockdep splat
  net: stmmac: dwmac4: fix PCS duplex mode decode
  idpf: fix UAFs when destroying the queues
  idpf: fix memleak in vport interrupt configuration
  idpf: fix memory leaks and crashes while performing a soft reset
  bnxt_en : Fix memory out-of-bounds in bnxt_fill_hw_rss_tbl()
  net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register()
  net/smc: add the max value of fallback reason count
  Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv monitor
  Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
  Bluetooth: hci_qca: fix a NULL-pointer derefence at shutdown
  Bluetooth: hci_qca: fix QCA6390 support on non-DT platforms
  Bluetooth: hci_qca: don't call pwrseq_power_off() twice for QCA6390
  ice: Fix incorrect assigns of FEC counts
  ...
This commit is contained in:
Linus Torvalds 2024-08-08 13:51:44 -07:00
commit ee9a43b7cf
33 changed files with 276 additions and 176 deletions

View File

@ -13541,7 +13541,7 @@ MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
M: Mirko Lindner <mlindner@marvell.com>
M: Stephen Hemminger <stephen@networkplumber.org>
L: netdev@vger.kernel.org
S: Maintained
S: Odd fixes
F: drivers/net/ethernet/marvell/sk*
MARVELL LIBERTAS WIRELESS DRIVER

View File

@ -2160,7 +2160,7 @@ static void qca_power_shutdown(struct hci_uart *hu)
qcadev = serdev_device_get_drvdata(hu->serdev);
power = qcadev->bt_power;
if (power->pwrseq) {
if (power && power->pwrseq) {
pwrseq_power_off(power->pwrseq);
set_bit(QCA_BT_OFF, &qca->flags);
return;
@ -2187,10 +2187,6 @@ static void qca_power_shutdown(struct hci_uart *hu)
}
break;
case QCA_QCA6390:
pwrseq_power_off(qcadev->bt_power->pwrseq);
break;
default:
gpiod_set_value_cansleep(qcadev->bt_en, 0);
}
@ -2416,11 +2412,14 @@ static int qca_serdev_probe(struct serdev_device *serdev)
break;
case QCA_QCA6390:
qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
"bluetooth");
if (IS_ERR(qcadev->bt_power->pwrseq))
return PTR_ERR(qcadev->bt_power->pwrseq);
break;
if (dev_of_node(&serdev->dev)) {
qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
"bluetooth");
if (IS_ERR(qcadev->bt_power->pwrseq))
return PTR_ERR(qcadev->bt_power->pwrseq);
break;
}
fallthrough;
default:
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",

View File

@ -675,8 +675,10 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
of_remove_property(child, prop);
phydev = of_phy_find_device(child);
if (phydev)
if (phydev) {
phy_device_remove(phydev);
phy_device_free(phydev);
}
}
err = mdiobus_register(priv->user_mii_bus);

View File

@ -2578,7 +2578,11 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
if (!port)
return MICREL_KSZ8_P1_ERRATA;
break;
case KSZ8567_CHIP_ID:
case KSZ9477_CHIP_ID:
case KSZ9567_CHIP_ID:
case KSZ9896_CHIP_ID:
case KSZ9897_CHIP_ID:
/* KSZ9477 Errata DS80000754C
*
* Module 4: Energy Efficient Ethernet (EEE) feature select must
@ -2588,6 +2592,13 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
* controls. If not disabled, the PHY ports can auto-negotiate
* to enable EEE, and this feature can cause link drops when
* linked to another device supporting EEE.
*
* The same item appears in the errata for the KSZ9567, KSZ9896,
* and KSZ9897.
*
* A similar item appears in the errata for the KSZ8567, but
* provides an alternative workaround. For now, use the simple
* workaround of disabling the EEE feature for this device too.
*/
return MICREL_NO_EEE;
}
@ -3764,6 +3775,11 @@ static int ksz_port_set_mac_address(struct dsa_switch *ds, int port,
return -EBUSY;
}
/* Need to initialize variable as the code to fill in settings may
* not be executed.
*/
wol.wolopts = 0;
ksz_get_wol(ds, dp->index, &wol);
if (wol.wolopts & WAKE_MAGIC) {
dev_err(ds->dev,

View File

@ -7591,19 +7591,20 @@ static bool bnxt_need_reserve_rings(struct bnxt *bp)
int rx = bp->rx_nr_rings, stat;
int vnic, grp = rx;
if (hw_resc->resv_tx_rings != bp->tx_nr_rings &&
bp->hwrm_spec_code >= 0x10601)
return true;
/* Old firmware does not need RX ring reservations but we still
* need to setup a default RSS map when needed. With new firmware
* we go through RX ring reservations first and then set up the
* RSS map for the successfully reserved RX rings when needed.
*/
if (!BNXT_NEW_RM(bp)) {
if (!BNXT_NEW_RM(bp))
bnxt_check_rss_tbl_no_rmgr(bp);
if (hw_resc->resv_tx_rings != bp->tx_nr_rings &&
bp->hwrm_spec_code >= 0x10601)
return true;
if (!BNXT_NEW_RM(bp))
return false;
}
vnic = bnxt_get_total_vnics(bp, rx);

View File

@ -5290,7 +5290,7 @@ void bnxt_ethtool_free(struct bnxt *bp)
const struct ethtool_ops bnxt_ethtool_ops = {
.cap_link_lanes_supported = 1,
.cap_rss_ctx_supported = 1,
.rxfh_max_context_id = BNXT_MAX_ETH_RSS_CTX,
.rxfh_max_num_contexts = BNXT_MAX_ETH_RSS_CTX + 1,
.rxfh_indir_space = BNXT_MAX_RSS_TABLE_ENTRIES_P5,
.rxfh_priv_size = sizeof(struct bnxt_rss_ctx),
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |

View File

@ -42,19 +42,15 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = &priv->pdev->dev;
if (dev->phydev) {
if (dev->phydev)
phy_ethtool_get_wol(dev->phydev, wol);
if (wol->supported)
return;
}
if (!device_can_wakeup(kdev)) {
wol->supported = 0;
wol->wolopts = 0;
/* MAC is not wake-up capable, return what the PHY does */
if (!device_can_wakeup(kdev))
return;
}
wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
/* Overlay MAC capabilities with that of the PHY queried before */
wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
wol->wolopts = priv->wolopts;
memset(wol->sopass, 0, sizeof(wol->sopass));

View File

@ -775,6 +775,9 @@ void fec_ptp_stop(struct platform_device *pdev)
struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev);
if (fep->pps_enable)
fec_ptp_enable_pps(fep, 0);
cancel_delayed_work_sync(&fep->time_keep);
hrtimer_cancel(&fep->perout_timer);
if (fep->ptp_clock)

View File

@ -495,7 +495,7 @@ static int gve_set_channels(struct net_device *netdev,
return -EINVAL;
}
if (!netif_carrier_ok(netdev)) {
if (!netif_running(netdev)) {
priv->tx_cfg.num_queues = new_tx;
priv->rx_cfg.num_queues = new_rx;
return 0;

View File

@ -1566,7 +1566,7 @@ static int gve_set_xdp(struct gve_priv *priv, struct bpf_prog *prog,
u32 status;
old_prog = READ_ONCE(priv->xdp_prog);
if (!netif_carrier_ok(priv->dev)) {
if (!netif_running(priv->dev)) {
WRITE_ONCE(priv->xdp_prog, prog);
if (old_prog)
bpf_prog_put(old_prog);
@ -1847,7 +1847,7 @@ int gve_adjust_queues(struct gve_priv *priv,
rx_alloc_cfg.qcfg = &new_rx_config;
tx_alloc_cfg.num_rings = new_tx_config.num_queues;
if (netif_carrier_ok(priv->dev)) {
if (netif_running(priv->dev)) {
err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg);
return err;
}
@ -2064,7 +2064,7 @@ static int gve_set_features(struct net_device *netdev,
if ((netdev->features & NETIF_F_LRO) != (features & NETIF_F_LRO)) {
netdev->features ^= NETIF_F_LRO;
if (netif_carrier_ok(netdev)) {
if (netif_running(netdev)) {
err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg);
if (err)
goto revert_features;
@ -2359,7 +2359,7 @@ err:
int gve_reset(struct gve_priv *priv, bool attempt_teardown)
{
bool was_up = netif_carrier_ok(priv->dev);
bool was_up = netif_running(priv->dev);
int err;
dev_info(&priv->pdev->dev, "Performing reset\n");
@ -2700,7 +2700,7 @@ static void gve_shutdown(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct gve_priv *priv = netdev_priv(netdev);
bool was_up = netif_carrier_ok(priv->dev);
bool was_up = netif_running(priv->dev);
rtnl_lock();
if (was_up && gve_close(priv->dev)) {
@ -2718,7 +2718,7 @@ static int gve_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct gve_priv *priv = netdev_priv(netdev);
bool was_up = netif_carrier_ok(priv->dev);
bool was_up = netif_running(priv->dev);
priv->suspend_cnt++;
rtnl_lock();

View File

@ -4673,10 +4673,10 @@ static int ice_get_port_fec_stats(struct ice_hw *hw, u16 pcs_quad, u16 pcs_port,
if (err)
return err;
fec_stats->uncorrectable_blocks.total = (fec_corr_high_val << 16) +
fec_corr_low_val;
fec_stats->corrected_blocks.total = (fec_uncorr_high_val << 16) +
fec_uncorr_low_val;
fec_stats->corrected_blocks.total = (fec_corr_high_val << 16) +
fec_corr_low_val;
fec_stats->uncorrectable_blocks.total = (fec_uncorr_high_val << 16) +
fec_uncorr_low_val;
return 0;
}

View File

@ -559,6 +559,8 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
if (test_bit(ICE_PREPARED_FOR_RESET, pf->state))
return;
synchronize_irq(pf->oicr_irq.virq);
ice_unplug_aux_dev(pf);
/* Notify VFs of impending reset */

View File

@ -1477,6 +1477,10 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
/* Update cached link status for this port immediately */
ptp_port->link_up = linkup;
/* Skip HW writes if reset is in progress */
if (pf->hw.reset_ongoing)
return;
switch (hw->ptp.phy_model) {
case ICE_PHY_E810:
/* Do not reconfigure E810 PHY */

View File

@ -900,8 +900,8 @@ static void idpf_vport_stop(struct idpf_vport *vport)
vport->link_up = false;
idpf_vport_intr_deinit(vport);
idpf_vport_intr_rel(vport);
idpf_vport_queues_rel(vport);
idpf_vport_intr_rel(vport);
np->state = __IDPF_VPORT_DOWN;
}
@ -1335,9 +1335,8 @@ static void idpf_rx_init_buf_tail(struct idpf_vport *vport)
/**
* idpf_vport_open - Bring up a vport
* @vport: vport to bring up
* @alloc_res: allocate queue resources
*/
static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res)
static int idpf_vport_open(struct idpf_vport *vport)
{
struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
struct idpf_adapter *adapter = vport->adapter;
@ -1350,45 +1349,43 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res)
/* we do not allow interface up just yet */
netif_carrier_off(vport->netdev);
if (alloc_res) {
err = idpf_vport_queues_alloc(vport);
if (err)
return err;
}
err = idpf_vport_intr_alloc(vport);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to allocate interrupts for vport %u: %d\n",
vport->vport_id, err);
goto queues_rel;
return err;
}
err = idpf_vport_queues_alloc(vport);
if (err)
goto intr_rel;
err = idpf_vport_queue_ids_init(vport);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize queue ids for vport %u: %d\n",
vport->vport_id, err);
goto intr_rel;
goto queues_rel;
}
err = idpf_vport_intr_init(vport);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize interrupts for vport %u: %d\n",
vport->vport_id, err);
goto intr_rel;
goto queues_rel;
}
err = idpf_rx_bufs_init_all(vport);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize RX buffers for vport %u: %d\n",
vport->vport_id, err);
goto intr_rel;
goto queues_rel;
}
err = idpf_queue_reg_init(vport);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize queue registers for vport %u: %d\n",
vport->vport_id, err);
goto intr_rel;
goto queues_rel;
}
idpf_rx_init_buf_tail(vport);
@ -1455,10 +1452,10 @@ unmap_queue_vectors:
idpf_send_map_unmap_queue_vector_msg(vport, false);
intr_deinit:
idpf_vport_intr_deinit(vport);
intr_rel:
idpf_vport_intr_rel(vport);
queues_rel:
idpf_vport_queues_rel(vport);
intr_rel:
idpf_vport_intr_rel(vport);
return err;
}
@ -1539,7 +1536,7 @@ void idpf_init_task(struct work_struct *work)
np = netdev_priv(vport->netdev);
np->state = __IDPF_VPORT_DOWN;
if (test_and_clear_bit(IDPF_VPORT_UP_REQUESTED, vport_config->flags))
idpf_vport_open(vport, true);
idpf_vport_open(vport);
/* Spawn and return 'idpf_init_task' work queue until all the
* default vports are created
@ -1898,9 +1895,6 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
goto free_vport;
}
err = idpf_vport_queues_alloc(new_vport);
if (err)
goto free_vport;
if (current_state <= __IDPF_VPORT_DOWN) {
idpf_send_delete_queues_msg(vport);
} else {
@ -1932,17 +1926,23 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
err = idpf_set_real_num_queues(vport);
if (err)
goto err_reset;
goto err_open;
if (current_state == __IDPF_VPORT_UP)
err = idpf_vport_open(vport, false);
err = idpf_vport_open(vport);
kfree(new_vport);
return err;
err_reset:
idpf_vport_queues_rel(new_vport);
idpf_send_add_queues_msg(vport, vport->num_txq, vport->num_complq,
vport->num_rxq, vport->num_bufq);
err_open:
if (current_state == __IDPF_VPORT_UP)
idpf_vport_open(vport);
free_vport:
kfree(new_vport);
@ -2171,7 +2171,7 @@ static int idpf_open(struct net_device *netdev)
idpf_vport_ctrl_lock(netdev);
vport = idpf_netdev_to_vport(netdev);
err = idpf_vport_open(vport, true);
err = idpf_vport_open(vport);
idpf_vport_ctrl_unlock(netdev);

View File

@ -3576,9 +3576,7 @@ static void idpf_vport_intr_napi_dis_all(struct idpf_vport *vport)
*/
void idpf_vport_intr_rel(struct idpf_vport *vport)
{
int i, j, v_idx;
for (v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
for (u32 v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
struct idpf_q_vector *q_vector = &vport->q_vectors[v_idx];
kfree(q_vector->complq);
@ -3593,26 +3591,6 @@ void idpf_vport_intr_rel(struct idpf_vport *vport)
free_cpumask_var(q_vector->affinity_mask);
}
/* Clean up the mapping of queues to vectors */
for (i = 0; i < vport->num_rxq_grp; i++) {
struct idpf_rxq_group *rx_qgrp = &vport->rxq_grps[i];
if (idpf_is_queue_model_split(vport->rxq_model))
for (j = 0; j < rx_qgrp->splitq.num_rxq_sets; j++)
rx_qgrp->splitq.rxq_sets[j]->rxq.q_vector = NULL;
else
for (j = 0; j < rx_qgrp->singleq.num_rxq; j++)
rx_qgrp->singleq.rxqs[j]->q_vector = NULL;
}
if (idpf_is_queue_model_split(vport->txq_model))
for (i = 0; i < vport->num_txq_grp; i++)
vport->txq_grps[i].complq->q_vector = NULL;
else
for (i = 0; i < vport->num_txq_grp; i++)
for (j = 0; j < vport->txq_grps[i].num_txq; j++)
vport->txq_grps[i].txqs[j]->q_vector = NULL;
kfree(vport->q_vectors);
vport->q_vectors = NULL;
}
@ -3780,13 +3758,15 @@ void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector)
/**
* idpf_vport_intr_req_irq - get MSI-X vectors from the OS for the vport
* @vport: main vport structure
* @basename: name for the vector
*/
static int idpf_vport_intr_req_irq(struct idpf_vport *vport, char *basename)
static int idpf_vport_intr_req_irq(struct idpf_vport *vport)
{
struct idpf_adapter *adapter = vport->adapter;
const char *drv_name, *if_name, *vec_name;
int vector, err, irq_num, vidx;
const char *vec_name;
drv_name = dev_driver_string(&adapter->pdev->dev);
if_name = netdev_name(vport->netdev);
for (vector = 0; vector < vport->num_q_vectors; vector++) {
struct idpf_q_vector *q_vector = &vport->q_vectors[vector];
@ -3804,8 +3784,8 @@ static int idpf_vport_intr_req_irq(struct idpf_vport *vport, char *basename)
else
continue;
name = kasprintf(GFP_KERNEL, "%s-%s-%d", basename, vec_name,
vidx);
name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name, if_name,
vec_name, vidx);
err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0,
name, q_vector);
@ -4326,7 +4306,6 @@ error:
*/
int idpf_vport_intr_init(struct idpf_vport *vport)
{
char *int_name;
int err;
err = idpf_vport_intr_init_vec_idx(vport);
@ -4340,11 +4319,7 @@ int idpf_vport_intr_init(struct idpf_vport *vport)
if (err)
goto unroll_vectors_alloc;
int_name = kasprintf(GFP_KERNEL, "%s-%s",
dev_driver_string(&vport->adapter->pdev->dev),
vport->netdev->name);
err = idpf_vport_intr_req_irq(vport, int_name);
err = idpf_vport_intr_req_irq(vport);
if (err)
goto unroll_vectors_alloc;

View File

@ -573,8 +573,6 @@ static inline u32 mtl_low_credx_base_addr(const struct dwmac4_addrs *addrs,
#define GMAC_PHYIF_CTRLSTATUS_LNKSTS BIT(19)
#define GMAC_PHYIF_CTRLSTATUS_JABTO BIT(20)
#define GMAC_PHYIF_CTRLSTATUS_FALSECARDET BIT(21)
/* LNKMOD */
#define GMAC_PHYIF_CTRLSTATUS_LNKMOD_MASK 0x1
/* LNKSPEED */
#define GMAC_PHYIF_CTRLSTATUS_SPEED_125 0x2
#define GMAC_PHYIF_CTRLSTATUS_SPEED_25 0x1

View File

@ -786,7 +786,7 @@ static void dwmac4_phystatus(void __iomem *ioaddr, struct stmmac_extra_stats *x)
else
x->pcs_speed = SPEED_10;
x->pcs_duplex = (status & GMAC_PHYIF_CTRLSTATUS_LNKMOD_MASK);
x->pcs_duplex = (status & GMAC_PHYIF_CTRLSTATUS_LNKMOD);
pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed,
x->pcs_duplex ? "Full" : "Half");

View File

@ -5,6 +5,7 @@
* Copyright (c) 2023 Bootlin, Kory Maincent <kory.maincent@bootlin.com>
*/
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
@ -29,6 +30,8 @@
#define TPS23881_REG_TPON BIT(0)
#define TPS23881_REG_FWREV 0x41
#define TPS23881_REG_DEVID 0x43
#define TPS23881_REG_DEVID_MASK 0xF0
#define TPS23881_DEVICE_ID 0x02
#define TPS23881_REG_SRAM_CTRL 0x60
#define TPS23881_REG_SRAM_DATA 0x61
@ -750,7 +753,7 @@ static int tps23881_i2c_probe(struct i2c_client *client)
if (ret < 0)
return ret;
if (ret != 0x22) {
if (FIELD_GET(TPS23881_REG_DEVID_MASK, ret) != TPS23881_DEVICE_ID) {
dev_err(dev, "Wrong device ID\n");
return -ENXIO;
}

View File

@ -201,6 +201,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
break;
default:
/* not ip - do not know what to do */
kfree_skb(skbn);
goto skip;
}
@ -1431,6 +1432,7 @@ static const struct usb_device_id products[] = {
{QMI_QUIRK_SET_DTR(0x1546, 0x1312, 4)}, /* u-blox LARA-R6 01B */
{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
{QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
{QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}, /* MeiG Smart SRM825L */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */

View File

@ -3658,6 +3658,9 @@ static int virtnet_send_rx_ctrl_coal_vq_cmd(struct virtnet_info *vi,
{
int err;
if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
return -EOPNOTSUPP;
err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue),
max_usecs, max_packets);
if (err)
@ -3675,6 +3678,9 @@ static int virtnet_send_tx_ctrl_coal_vq_cmd(struct virtnet_info *vi,
{
int err;
if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
return -EOPNOTSUPP;
err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue),
max_usecs, max_packets);
if (err)
@ -3743,7 +3749,11 @@ static int virtnet_set_ringparam(struct net_device *dev,
err = virtnet_send_tx_ctrl_coal_vq_cmd(vi, i,
vi->intr_coal_tx.max_usecs,
vi->intr_coal_tx.max_packets);
if (err)
/* Don't break the tx resize action if the vq coalescing is not
* supported. The same is true for rx resize below.
*/
if (err && err != -EOPNOTSUPP)
return err;
}
@ -3758,7 +3768,7 @@ static int virtnet_set_ringparam(struct net_device *dev,
vi->intr_coal_rx.max_usecs,
vi->intr_coal_rx.max_packets);
mutex_unlock(&vi->rq[i].dim_lock);
if (err)
if (err && err != -EOPNOTSUPP)
return err;
}
}

View File

@ -736,10 +736,10 @@ struct kernel_ethtool_ts_info {
* @rxfh_key_space: same as @rxfh_indir_space, but for the key.
* @rxfh_priv_size: size of the driver private data area the core should
* allocate for an RSS context (in &struct ethtool_rxfh_context).
* @rxfh_max_context_id: maximum (exclusive) supported RSS context ID. If this
* is zero then the core may choose any (nonzero) ID, otherwise the core
* will only use IDs strictly less than this value, as the @rss_context
* argument to @create_rxfh_context and friends.
* @rxfh_max_num_contexts: maximum (exclusive) supported RSS context ID.
* If this is zero then the core may choose any (nonzero) ID, otherwise
* the core will only use IDs strictly less than this value, as the
* @rss_context argument to @create_rxfh_context and friends.
* @supported_coalesce_params: supported types of interrupt coalescing.
* @supported_ring_params: supported ring params.
* @get_drvinfo: Report driver/device information. Modern drivers no
@ -954,7 +954,7 @@ struct ethtool_ops {
u32 rxfh_indir_space;
u16 rxfh_key_space;
u16 rxfh_priv_size;
u32 rxfh_max_context_id;
u32 rxfh_max_num_contexts;
u32 supported_coalesce_params;
u32 supported_ring_params;
void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);

View File

@ -3019,6 +3019,20 @@ static int hci_passive_scan_sync(struct hci_dev *hdev)
} else if (hci_is_adv_monitoring(hdev)) {
window = hdev->le_scan_window_adv_monitor;
interval = hdev->le_scan_int_adv_monitor;
/* Disable duplicates filter when scanning for advertisement
* monitor for the following reasons.
*
* For HW pattern filtering (ex. MSFT), Realtek and Qualcomm
* controllers ignore RSSI_Sampling_Period when the duplicates
* filter is enabled.
*
* For SW pattern filtering, when we're not doing interleaved
* scanning, it is necessary to disable duplicates filter,
* otherwise hosts can only receive one advertisement and it's
* impossible to know if a peer is still in range.
*/
filter_dups = LE_SCAN_FILTER_DUP_DISABLE;
} else {
window = hdev->le_scan_window;
interval = hdev->le_scan_interval;

View File

@ -6774,6 +6774,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
bt_cb(skb)->l2cap.psm = psm;
if (!chan->ops->recv(chan, skb)) {
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return;
}

View File

@ -2045,16 +2045,14 @@ void br_multicast_del_port(struct net_bridge_port *port)
{
struct net_bridge *br = port->br;
struct net_bridge_port_group *pg;
HLIST_HEAD(deleted_head);
struct hlist_node *n;
/* Take care of the remaining groups, only perm ones should be left */
spin_lock_bh(&br->multicast_lock);
hlist_for_each_entry_safe(pg, n, &port->mglist, mglist)
br_multicast_find_del_pg(br, pg);
hlist_move_list(&br->mcast_gc_list, &deleted_head);
spin_unlock_bh(&br->multicast_lock);
br_multicast_gc(&deleted_head);
flush_work(&br->mcast_gc_work);
br_multicast_port_ctx_deinit(&port->multicast_ctx);
free_percpu(port->mcast_stats);
}

View File

@ -148,9 +148,9 @@ static void linkwatch_schedule_work(int urgent)
* override the existing timer.
*/
if (test_bit(LW_URGENT, &linkwatch_flags))
mod_delayed_work(system_wq, &linkwatch_work, 0);
mod_delayed_work(system_unbound_wq, &linkwatch_work, 0);
else
schedule_delayed_work(&linkwatch_work, delay);
queue_delayed_work(system_unbound_wq, &linkwatch_work, delay);
}

View File

@ -1369,14 +1369,17 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
return -EOPNOTSUPP;
create = rxfh.rss_context == ETH_RXFH_CONTEXT_ALLOC;
/* If either indir, hash key or function is valid, proceed further.
* Must request at least one change: indir size, hash key, function
* or input transformation.
*/
if ((rxfh.indir_size &&
rxfh.indir_size != ETH_RXFH_INDIR_NO_CHANGE &&
rxfh.indir_size != dev_indir_size) ||
(rxfh.key_size && (rxfh.key_size != dev_key_size)) ||
(rxfh.key_size && rxfh.key_size != dev_key_size))
return -EINVAL;
/* Must request at least one change: indir size, hash key, function
* or input transformation.
* There's no need for any of it in case of context creation.
*/
if (!create &&
(rxfh.indir_size == ETH_RXFH_INDIR_NO_CHANGE &&
rxfh.key_size == 0 && rxfh.hfunc == ETH_RSS_HASH_NO_CHANGE &&
rxfh.input_xfrm == RXH_XFRM_NO_CHANGE))
@ -1449,12 +1452,13 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
}
if (ops->create_rxfh_context) {
u32 limit = ops->rxfh_max_context_id ?: U32_MAX;
u32 limit = ops->rxfh_max_num_contexts ?: U32_MAX;
u32 ctx_id;
/* driver uses new API, core allocates ID */
ret = xa_alloc(&dev->ethtool->rss_ctx, &ctx_id, ctx,
XA_LIMIT(1, limit), GFP_KERNEL_ACCOUNT);
XA_LIMIT(1, limit - 1),
GFP_KERNEL_ACCOUNT);
if (ret < 0) {
kfree(ctx);
goto out;

View File

@ -267,32 +267,49 @@ static void tcp_ao_key_free_rcu(struct rcu_head *head)
kfree_sensitive(key);
}
void tcp_ao_destroy_sock(struct sock *sk, bool twsk)
static void tcp_ao_info_free_rcu(struct rcu_head *head)
{
struct tcp_ao_info *ao;
struct tcp_ao_info *ao = container_of(head, struct tcp_ao_info, rcu);
struct tcp_ao_key *key;
struct hlist_node *n;
hlist_for_each_entry_safe(key, n, &ao->head, node) {
hlist_del(&key->node);
tcp_sigpool_release(key->tcp_sigpool_id);
kfree_sensitive(key);
}
kfree(ao);
static_branch_slow_dec_deferred(&tcp_ao_needed);
}
static void tcp_ao_sk_omem_free(struct sock *sk, struct tcp_ao_info *ao)
{
size_t total_ao_sk_mem = 0;
struct tcp_ao_key *key;
hlist_for_each_entry(key, &ao->head, node)
total_ao_sk_mem += tcp_ao_sizeof_key(key);
atomic_sub(total_ao_sk_mem, &sk->sk_omem_alloc);
}
void tcp_ao_destroy_sock(struct sock *sk, bool twsk)
{
struct tcp_ao_info *ao;
if (twsk) {
ao = rcu_dereference_protected(tcp_twsk(sk)->ao_info, 1);
tcp_twsk(sk)->ao_info = NULL;
rcu_assign_pointer(tcp_twsk(sk)->ao_info, NULL);
} else {
ao = rcu_dereference_protected(tcp_sk(sk)->ao_info, 1);
tcp_sk(sk)->ao_info = NULL;
rcu_assign_pointer(tcp_sk(sk)->ao_info, NULL);
}
if (!ao || !refcount_dec_and_test(&ao->refcnt))
return;
hlist_for_each_entry_safe(key, n, &ao->head, node) {
hlist_del_rcu(&key->node);
if (!twsk)
atomic_sub(tcp_ao_sizeof_key(key), &sk->sk_omem_alloc);
call_rcu(&key->rcu, tcp_ao_key_free_rcu);
}
kfree_rcu(ao, rcu);
static_branch_slow_dec_deferred(&tcp_ao_needed);
if (!twsk)
tcp_ao_sk_omem_free(sk, ao);
call_rcu(&ao->rcu, tcp_ao_info_free_rcu);
}
void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp)

View File

@ -86,6 +86,11 @@
/* Default trace flags */
#define L2TP_DEFAULT_DEBUG_FLAGS 0
#define L2TP_DEPTH_NESTING 2
#if L2TP_DEPTH_NESTING == SINGLE_DEPTH_NESTING
#error "L2TP requires its own lockdep subclass"
#endif
/* Private data stored for received packets in the skb.
*/
struct l2tp_skb_cb {
@ -1124,7 +1129,13 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
nf_reset_ct(skb);
bh_lock_sock_nested(sk);
/* L2TP uses its own lockdep subclass to avoid lockdep splats caused by
* nested socket calls on the same lockdep socket class. This can
* happen when data from a user socket is routed over l2tp, which uses
* another userspace socket.
*/
spin_lock_nested(&sk->sk_lock.slock, L2TP_DEPTH_NESTING);
if (sock_owned_by_user(sk)) {
kfree_skb(skb);
ret = NET_XMIT_DROP;
@ -1176,7 +1187,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
ret = l2tp_xmit_queue(tunnel, skb, &inet->cork.fl);
out_unlock:
bh_unlock_sock(sk);
spin_unlock(&sk->sk_lock.slock);
return ret;
}

View File

@ -958,7 +958,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
if (subflow->remote_key_valid &&
(((mp_opt->suboptions & OPTION_MPTCP_DSS) && mp_opt->use_ack) ||
((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && !mp_opt->echo))) {
((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) &&
(!mp_opt->echo || subflow->mp_join)))) {
/* subflows are fully established as soon as we get any
* additional ack, including ADD_ADDR.
*/

View File

@ -348,7 +348,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
add_entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
if (add_entry) {
if (mptcp_pm_is_kernel(msk))
if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk)))
return false;
sk_reset_timer(sk, &add_entry->add_timer,
@ -512,8 +512,8 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{
struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL;
struct sock *sk = (struct sock *)msk;
struct mptcp_pm_addr_entry *local;
unsigned int add_addr_signal_max;
unsigned int local_addr_max;
struct pm_nl_pernet *pernet;
@ -555,8 +555,6 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
/* check first for announce */
if (msk->pm.add_addr_signaled < add_addr_signal_max) {
local = select_signal_address(pernet, msk);
/* due to racing events on both ends we can reach here while
* previous add address is still running: if we invoke now
* mptcp_pm_announce_addr(), that will fail and the
@ -567,16 +565,26 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
return;
if (local) {
if (mptcp_pm_alloc_anno_list(msk, &local->addr)) {
__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
msk->pm.add_addr_signaled++;
mptcp_pm_announce_addr(msk, &local->addr, false);
mptcp_pm_nl_addr_send_ack(msk);
}
}
local = select_signal_address(pernet, msk);
if (!local)
goto subflow;
/* If the alloc fails, we are on memory pressure, not worth
* continuing, and trying to create subflows.
*/
if (!mptcp_pm_alloc_anno_list(msk, &local->addr))
return;
__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
msk->pm.add_addr_signaled++;
mptcp_pm_announce_addr(msk, &local->addr, false);
mptcp_pm_nl_addr_send_ack(msk);
if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
signal_and_subflow = local;
}
subflow:
/* check if should create a new subflow */
while (msk->pm.local_addr_used < local_addr_max &&
msk->pm.subflows < subflows_max) {
@ -584,9 +592,14 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
bool fullmesh;
int i, nr;
local = select_local_address(pernet, msk);
if (!local)
break;
if (signal_and_subflow) {
local = signal_and_subflow;
signal_and_subflow = NULL;
} else {
local = select_local_address(pernet, msk);
if (!local)
break;
}
fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
@ -1328,8 +1341,8 @@ int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
if (ret < 0)
return ret;
if (addr.addr.port && !(addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
GENL_SET_ERR_MSG(info, "flags must have signal when using port");
if (addr.addr.port && !address_use_port(&addr)) {
GENL_SET_ERR_MSG(info, "flags must have signal and not subflow when using port");
return -EINVAL;
}

View File

@ -735,15 +735,19 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
struct sock *sk = ep->base.sk;
struct net *net = sock_net(sk);
struct sctp_hashbucket *head;
int err = 0;
ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port);
head = &sctp_ep_hashtable[ep->hashent];
write_lock(&head->lock);
if (sk->sk_reuseport) {
bool any = sctp_is_ep_boundall(sk);
struct sctp_endpoint *ep2;
struct list_head *list;
int cnt = 0, err = 1;
int cnt = 0;
err = 1;
list_for_each(list, &ep->base.bind_addr.address_list)
cnt++;
@ -761,24 +765,24 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep)
if (!err) {
err = reuseport_add_sock(sk, sk2, any);
if (err)
return err;
goto out;
break;
} else if (err < 0) {
return err;
goto out;
}
}
if (err) {
err = reuseport_alloc(sk, any);
if (err)
return err;
goto out;
}
}
write_lock(&head->lock);
hlist_add_head(&ep->node, &head->chain);
out:
write_unlock(&head->lock);
return 0;
return err;
}
/* Add an endpoint to the hash. Local BH-safe. */
@ -803,10 +807,9 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
head = &sctp_ep_hashtable[ep->hashent];
write_lock(&head->lock);
if (rcu_access_pointer(sk->sk_reuseport_cb))
reuseport_detach_sock(sk);
write_lock(&head->lock);
hlist_del_init(&ep->node);
write_unlock(&head->lock);
}

View File

@ -19,7 +19,7 @@
#include "smc_clc.h"
#define SMC_MAX_FBACK_RSN_CNT 30
#define SMC_MAX_FBACK_RSN_CNT 36
enum {
SMC_BUF_8K,

View File

@ -1415,18 +1415,28 @@ chk_add_nr()
local add_nr=$1
local echo_nr=$2
local port_nr=${3:-0}
local syn_nr=${4:-$port_nr}
local syn_ack_nr=${5:-$port_nr}
local ack_nr=${6:-$port_nr}
local mis_syn_nr=${7:-0}
local mis_ack_nr=${8:-0}
local ns_invert=${4:-""}
local syn_nr=$port_nr
local syn_ack_nr=$port_nr
local ack_nr=$port_nr
local mis_syn_nr=0
local mis_ack_nr=0
local ns_tx=$ns1
local ns_rx=$ns2
local extra_msg=""
local count
local timeout
timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout)
if [[ $ns_invert = "invert" ]]; then
ns_tx=$ns2
ns_rx=$ns1
extra_msg="invert"
fi
timeout=$(ip netns exec ${ns_tx} sysctl -n net.mptcp.add_addr_timeout)
print_check "add"
count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtAddAddr")
count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtAddAddr")
if [ -z "$count" ]; then
print_skip
# if the test configured a short timeout tolerate greater then expected
@ -1438,7 +1448,7 @@ chk_add_nr()
fi
print_check "echo"
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtEchoAdd")
count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtEchoAdd")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$echo_nr" ]; then
@ -1449,7 +1459,7 @@ chk_add_nr()
if [ $port_nr -gt 0 ]; then
print_check "pt"
count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtPortAdd")
count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtPortAdd")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$port_nr" ]; then
@ -1459,7 +1469,7 @@ chk_add_nr()
fi
print_check "syn"
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortSynRx")
count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortSynRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$syn_nr" ]; then
@ -1470,7 +1480,7 @@ chk_add_nr()
fi
print_check "synack"
count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinPortSynAckRx")
count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPJoinPortSynAckRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$syn_ack_nr" ]; then
@ -1481,7 +1491,7 @@ chk_add_nr()
fi
print_check "ack"
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortAckRx")
count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortAckRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$ack_nr" ]; then
@ -1492,7 +1502,7 @@ chk_add_nr()
fi
print_check "syn"
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortSynRx")
count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortSynRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$mis_syn_nr" ]; then
@ -1503,7 +1513,7 @@ chk_add_nr()
fi
print_check "ack"
count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortAckRx")
count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortAckRx")
if [ -z "$count" ]; then
print_skip
elif [ "$count" != "$mis_ack_nr" ]; then
@ -1513,6 +1523,8 @@ chk_add_nr()
print_ok
fi
fi
print_info "$extra_msg"
}
chk_add_tx_nr()
@ -1977,6 +1989,21 @@ signal_address_tests()
chk_add_nr 1 1
fi
# uncommon: subflow and signal flags on the same endpoint
# or because the user wrongly picked both, but still expects the client
# to create additional subflows
if reset "subflow and signal together"; then
pm_nl_set_limits $ns1 0 2
pm_nl_set_limits $ns2 0 2
pm_nl_add_endpoint $ns2 10.0.3.2 flags signal,subflow
run_tests $ns1 $ns2 10.0.1.1
chk_join_nr 1 1 1
chk_add_nr 1 1 0 invert # only initiated by ns2
chk_add_nr 0 0 0 # none initiated by ns1
chk_rst_nr 0 0 invert # no RST sent by the client
chk_rst_nr 0 0 # no RST sent by the server
fi
# accept and use add_addr with additional subflows
if reset "multiple subflows and signal"; then
pm_nl_set_limits $ns1 0 3