mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
Including fixes from netfilter and wireless.
Current release - fix to a fix: - net: do not write to msg_get_inq in callee - arp: do not assume dev_hard_header() does not change skb->head Current release - regressions: - wifi: mac80211: don't iterate not running interfaces - eth: mlx5: fix NULL pointer dereference in ioctl module EEPROM Current release - new code bugs: - eth: bnge: add AUXILIARY_BUS to Kconfig dependencies Previous releases - regressions: - eth: mlx5: dealloc forgotten PSP RX modify header Previous releases - always broken: - ping: fix ICMP out SNMP stats double-counting with ICMP sockets - bonding: preserve NETIF_F_ALL_FOR_ALL across TSO updates - bridge: fix C-VLAN preservation in 802.1ad vlan_tunnel egress - eth: bnxt: fix potential data corruption with HW GRO/LRO Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmlf6N8ACgkQMUZtbf5S Irt9lxAAote4zPojTEJvE1DkABVsx31gPm6DF8zEae39XsFKtOMfb876s5bchOUA Rkd27+k28l/U5HFrrhUhqDlaOikjXx6baT12qTPsuxGrOL6Um23EfIgVuNFzxMwE lcBgkSNe1tfT8WBirWEVWLc5xme+vvll7ViX7kkQJ7fEdk1mvTPZ5roIq1+pE1U0 V5Gu4l9QBcWC/IymAO8Z2UE08terMcYt1G4H6mSIoooeMM1QElbPwVEiRWAzJ/NP 9cTjvnHJDAdRnA4bMa76CGWxg4wgPhgj3+ydlouWjgJADL6hlMj4sIZxaXgjDuoE XyCEuk6Y/rUTSmX1yn7rha9FQwJOyMu9XlEjnNSvH0LRdnSa7xO7NzeXtrWv7HSg kQOMTnMVgVlabOuMbR6xNqY6UyulQgK/2E56RgOO4Iw6U7crZsbyZx3OFkIKhq8g ZWaRBQNdYBBftjJA7FwQSyj/K75sLfbYAS5YizguNyFPBCBhSBJdgFWoGb+XhT0/ k0KwsX/NWN0apHmZNiD4mT/UdX2PhJRdiTWPczNyEzqJcxh1P2HMWHVZOsIyZQHT EK3w6LLqp1eshEERPqFsqCFYX4LUuifQbPPF0kBkL1hTMa2NuXnkIsOzbcWal88o qdej9TY9VC5ycabgDI4/9ZNhnAzho1Nk/e6YuHsBcu2pIVDKgNI= =vR9r -----END PGP SIGNATURE----- Merge tag 'net-6.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from netfilter and wireless. Current release - fix to a fix: - net: do not write to msg_get_inq in callee - arp: do not assume dev_hard_header() does not change skb->head Current release - regressions: - wifi: mac80211: don't iterate not running interfaces - eth: mlx5: fix NULL pointer dereference in ioctl module EEPROM Current release - new code bugs: - eth: bnge: add AUXILIARY_BUS to Kconfig dependencies Previous releases - regressions: - eth: mlx5: dealloc forgotten PSP RX modify header Previous releases - always broken: - ping: fix ICMP out SNMP stats double-counting with ICMP sockets - bonding: preserve NETIF_F_ALL_FOR_ALL across TSO updates - bridge: fix C-VLAN preservation in 802.1ad vlan_tunnel egress - eth: bnxt: fix potential data corruption with HW GRO/LRO" * tag 'net-6.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (70 commits) arp: do not assume dev_hard_header() does not change skb->head net: enetc: fix build warning when PAGE_SIZE is greater than 128K atm: Fix dma_free_coherent() size tools: ynl: don't install tests net: do not write to msg_get_inq in callee bnxt_en: Fix NULL pointer crash in bnxt_ptp_enable during error cleanup net: usb: pegasus: fix memory leak in update_eth_regs_async() net: 3com: 3c59x: fix possible null dereference in vortex_probe1() net/sched: sch_qfq: Fix NULL deref when deactivating inactive aggregate in qfq_reset wifi: mac80211: collect station statistics earlier when disconnect wifi: mac80211: restore non-chanctx injection behaviour wifi: mac80211_hwsim: disable BHs for hwsim_radio_lock wifi: mac80211: don't iterate not running interfaces wifi: mac80211_hwsim: fix typo in frequency notification wifi: avoid kernel-infoleak from struct iw_point net: airoha: Fix schedule while atomic in airoha_ppe_deinit() selftests: netdevsim: add carrier state consistency test net: netdevsim: fix inconsistent carrier state after link/unlink selftests: drv-net: Bring back tool() to driver __init__s net/sched: act_api: avoid dereferencing ERR_PTR in tcf_idrinfo_destroy ...
This commit is contained in:
commit
f2a3b12b30
1
.mailmap
1
.mailmap
@ -416,6 +416,7 @@ Juha Yrjola <at solidboot.com>
|
||||
Juha Yrjola <juha.yrjola@nokia.com>
|
||||
Juha Yrjola <juha.yrjola@solidboot.com>
|
||||
Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com>
|
||||
Justin Iurman <justin.iurman@gmail.com> <justin.iurman@uliege.be>
|
||||
Iskren Chernev <me@iskren.info> <iskren.chernev@gmail.com>
|
||||
Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org>
|
||||
Kalle Valo <kvalo@kernel.org> <quic_kvalo@quicinc.com>
|
||||
|
||||
@ -142,7 +142,7 @@ attribute-sets:
|
||||
name: ifindex
|
||||
doc: |
|
||||
ifindex of the netdev to which the pool belongs.
|
||||
May be reported as 0 if the page pool was allocated for a netdev
|
||||
May not be reported if the page pool was allocated for a netdev
|
||||
which got destroyed already (page pools may outlast their netdevs
|
||||
because they wait for all memory to be returned).
|
||||
type: u32
|
||||
@ -601,7 +601,9 @@ operations:
|
||||
name: page-pool-get
|
||||
doc: |
|
||||
Get / dump information about Page Pools.
|
||||
(Only Page Pools associated with a net_device can be listed.)
|
||||
Only Page Pools associated by the driver with a net_device
|
||||
can be listed. ifindex will not be reported if the net_device
|
||||
no longer exists.
|
||||
attribute-set: page-pool
|
||||
do:
|
||||
request:
|
||||
|
||||
@ -1283,6 +1283,7 @@ F: include/uapi/drm/amdxdna_accel.h
|
||||
|
||||
AMD XGBE DRIVER
|
||||
M: "Shyam Sundar S K" <Shyam-sundar.S-k@amd.com>
|
||||
M: Raju Rangoju <Raju.Rangoju@amd.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
|
||||
@ -18283,7 +18284,7 @@ X: net/wireless/
|
||||
X: tools/testing/selftests/net/can/
|
||||
|
||||
NETWORKING [IOAM]
|
||||
M: Justin Iurman <justin.iurman@uliege.be>
|
||||
M: Justin Iurman <justin.iurman@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/networking/ioam6*
|
||||
F: include/linux/ioam6*
|
||||
|
||||
@ -1587,7 +1587,8 @@ he_stop(struct he_dev *he_dev)
|
||||
he_dev->tbrq_base, he_dev->tbrq_phys);
|
||||
|
||||
if (he_dev->tpdrq_base)
|
||||
dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq),
|
||||
dma_free_coherent(&he_dev->pci_dev->dev,
|
||||
CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq),
|
||||
he_dev->tpdrq_base, he_dev->tpdrq_phys);
|
||||
|
||||
dma_pool_destroy(he_dev->tpd_pool);
|
||||
|
||||
@ -3364,13 +3364,10 @@ static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
|
||||
|
||||
static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
struct device_node *phy_handle = NULL;
|
||||
struct fwnode_handle *ports_fwnode;
|
||||
struct fwnode_handle *port_fwnode;
|
||||
struct dsa_switch *ds = chip->ds;
|
||||
struct mv88e6xxx_port *p;
|
||||
struct dsa_port *dp;
|
||||
int tx_amp;
|
||||
int err;
|
||||
u16 reg;
|
||||
u32 val;
|
||||
@ -3582,23 +3579,6 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (chip->info->ops->serdes_set_tx_amplitude) {
|
||||
dp = dsa_to_port(ds, port);
|
||||
if (dp)
|
||||
phy_handle = of_parse_phandle(dp->dn, "phy-handle", 0);
|
||||
|
||||
if (phy_handle && !of_property_read_u32(phy_handle,
|
||||
"tx-p2p-microvolt",
|
||||
&tx_amp))
|
||||
err = chip->info->ops->serdes_set_tx_amplitude(chip,
|
||||
port, tx_amp);
|
||||
if (phy_handle) {
|
||||
of_node_put(phy_handle);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Port based VLAN map: give each port the same default address
|
||||
* database, and allow bidirectional communication between the
|
||||
* CPU and DSA port(s), and the other ports.
|
||||
@ -4768,7 +4748,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_get_caps = mv88e6352_phylink_get_caps,
|
||||
.pcs_ops = &mv88e6352_pcs_ops,
|
||||
@ -5044,7 +5023,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
@ -5481,7 +5459,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
.serdes_get_stats = mv88e6352_serdes_get_stats,
|
||||
.serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
|
||||
.serdes_get_regs = mv88e6352_serdes_get_regs,
|
||||
.serdes_set_tx_amplitude = mv88e6352_serdes_set_tx_amplitude,
|
||||
.phylink_get_caps = mv88e6352_phylink_get_caps,
|
||||
.pcs_ops = &mv88e6352_pcs_ops,
|
||||
};
|
||||
|
||||
@ -642,10 +642,6 @@ struct mv88e6xxx_ops {
|
||||
void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port,
|
||||
void *_p);
|
||||
|
||||
/* SERDES SGMII/Fiber Output Amplitude */
|
||||
int (*serdes_set_tx_amplitude)(struct mv88e6xxx_chip *chip, int port,
|
||||
int val);
|
||||
|
||||
/* Address Translation Unit operations */
|
||||
int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash);
|
||||
int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
|
||||
|
||||
@ -25,14 +25,6 @@ static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
|
||||
reg, val);
|
||||
}
|
||||
|
||||
static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
|
||||
u16 val)
|
||||
{
|
||||
return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
|
||||
MV88E6352_SERDES_PAGE_FIBER,
|
||||
reg, val);
|
||||
}
|
||||
|
||||
static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
|
||||
int lane, int device, int reg, u16 *val)
|
||||
{
|
||||
@ -506,41 +498,3 @@ void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p)
|
||||
p[i] = reg;
|
||||
}
|
||||
}
|
||||
|
||||
static const int mv88e6352_serdes_p2p_to_reg[] = {
|
||||
/* Index of value in microvolts corresponds to the register value */
|
||||
14000, 112000, 210000, 308000, 406000, 504000, 602000, 700000,
|
||||
};
|
||||
|
||||
int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
|
||||
int val)
|
||||
{
|
||||
bool found = false;
|
||||
u16 ctrl, reg;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
|
||||
if (err <= 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_p2p_to_reg); ++i) {
|
||||
if (mv88e6352_serdes_p2p_to_reg[i] == val) {
|
||||
reg = i;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -EINVAL;
|
||||
|
||||
err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_SPEC_CTRL2, &ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ctrl &= ~MV88E6352_SERDES_OUT_AMP_MASK;
|
||||
ctrl |= reg;
|
||||
|
||||
return mv88e6352_serdes_write(chip, MV88E6352_SERDES_SPEC_CTRL2, ctrl);
|
||||
}
|
||||
|
||||
@ -29,8 +29,6 @@ struct phylink_link_state;
|
||||
#define MV88E6352_SERDES_INT_FIBRE_ENERGY BIT(4)
|
||||
#define MV88E6352_SERDES_INT_STATUS 0x13
|
||||
|
||||
#define MV88E6352_SERDES_SPEC_CTRL2 0x1a
|
||||
#define MV88E6352_SERDES_OUT_AMP_MASK 0x0007
|
||||
|
||||
#define MV88E6341_PORT5_LANE 0x15
|
||||
|
||||
@ -140,9 +138,6 @@ void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
|
||||
int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
|
||||
void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
|
||||
|
||||
int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
|
||||
int val);
|
||||
|
||||
/* Return the (first) SERDES lane address a port is using, -errno otherwise. */
|
||||
static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
|
||||
int port)
|
||||
|
||||
@ -1473,7 +1473,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
|
||||
return 0;
|
||||
|
||||
free_ring:
|
||||
dma_free_coherent(&pdev->dev,
|
||||
dma_free_coherent(gendev,
|
||||
sizeof(struct boom_rx_desc) * RX_RING_SIZE +
|
||||
sizeof(struct boom_tx_desc) * TX_RING_SIZE,
|
||||
vp->rx_ring, vp->rx_ring_dma);
|
||||
|
||||
@ -1547,13 +1547,16 @@ void airoha_ppe_deinit(struct airoha_eth *eth)
|
||||
{
|
||||
struct airoha_npu *npu;
|
||||
|
||||
rcu_read_lock();
|
||||
npu = rcu_dereference(eth->npu);
|
||||
mutex_lock(&flow_offload_mutex);
|
||||
|
||||
npu = rcu_replace_pointer(eth->npu, NULL,
|
||||
lockdep_is_held(&flow_offload_mutex));
|
||||
if (npu) {
|
||||
npu->ops.ppe_deinit(npu);
|
||||
airoha_npu_put(npu);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
mutex_unlock(&flow_offload_mutex);
|
||||
|
||||
rhashtable_destroy(ð->ppe->l2_flows);
|
||||
rhashtable_destroy(ð->flow_table);
|
||||
|
||||
@ -53,10 +53,12 @@ void ena_devlink_disable_phc_param(struct devlink *devlink)
|
||||
{
|
||||
union devlink_param_value value;
|
||||
|
||||
devl_lock(devlink);
|
||||
value.vbool = false;
|
||||
devl_param_driverinit_value_set(devlink,
|
||||
DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC,
|
||||
value);
|
||||
devl_unlock(devlink);
|
||||
}
|
||||
|
||||
static void ena_devlink_port_register(struct devlink *devlink)
|
||||
@ -145,10 +147,12 @@ static int ena_devlink_configure_params(struct devlink *devlink)
|
||||
return rc;
|
||||
}
|
||||
|
||||
devl_lock(devlink);
|
||||
value.vbool = ena_phc_is_enabled(adapter);
|
||||
devl_param_driverinit_value_set(devlink,
|
||||
DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC,
|
||||
value);
|
||||
devl_unlock(devlink);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -259,6 +259,7 @@ config BNGE
|
||||
depends on PCI
|
||||
select NET_DEVLINK
|
||||
select PAGE_POOL
|
||||
select AUXILIARY_BUS
|
||||
help
|
||||
This driver supports Broadcom ThorUltra 50/100/200/400/800 gigabit
|
||||
Ethernet cards. The module will be called bng_en. To compile this
|
||||
|
||||
@ -1482,9 +1482,11 @@ static u16 bnxt_alloc_agg_idx(struct bnxt_rx_ring_info *rxr, u16 agg_id)
|
||||
struct bnxt_tpa_idx_map *map = rxr->rx_tpa_idx_map;
|
||||
u16 idx = agg_id & MAX_TPA_P5_MASK;
|
||||
|
||||
if (test_bit(idx, map->agg_idx_bmap))
|
||||
idx = find_first_zero_bit(map->agg_idx_bmap,
|
||||
BNXT_AGG_IDX_BMAP_SIZE);
|
||||
if (test_bit(idx, map->agg_idx_bmap)) {
|
||||
idx = find_first_zero_bit(map->agg_idx_bmap, MAX_TPA_P5);
|
||||
if (idx >= MAX_TPA_P5)
|
||||
return INVALID_HW_RING_ID;
|
||||
}
|
||||
__set_bit(idx, map->agg_idx_bmap);
|
||||
map->agg_id_tbl[agg_id] = idx;
|
||||
return idx;
|
||||
@ -1548,6 +1550,13 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
|
||||
agg_id = TPA_START_AGG_ID_P5(tpa_start);
|
||||
agg_id = bnxt_alloc_agg_idx(rxr, agg_id);
|
||||
if (unlikely(agg_id == INVALID_HW_RING_ID)) {
|
||||
netdev_warn(bp->dev, "Unable to allocate agg ID for ring %d, agg 0x%x\n",
|
||||
rxr->bnapi->index,
|
||||
TPA_START_AGG_ID_P5(tpa_start));
|
||||
bnxt_sched_reset_rxr(bp, rxr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
agg_id = TPA_START_AGG_ID(tpa_start);
|
||||
}
|
||||
@ -16882,12 +16891,12 @@ init_err_dl:
|
||||
|
||||
init_err_pci_clean:
|
||||
bnxt_hwrm_func_drv_unrgtr(bp);
|
||||
bnxt_free_hwrm_resources(bp);
|
||||
bnxt_hwmon_uninit(bp);
|
||||
bnxt_ethtool_free(bp);
|
||||
bnxt_ptp_clear(bp);
|
||||
kfree(bp->ptp_cfg);
|
||||
bp->ptp_cfg = NULL;
|
||||
bnxt_free_hwrm_resources(bp);
|
||||
bnxt_hwmon_uninit(bp);
|
||||
bnxt_ethtool_free(bp);
|
||||
kfree(bp->fw_health);
|
||||
bp->fw_health = NULL;
|
||||
bnxt_cleanup_pci(bp);
|
||||
|
||||
@ -1080,11 +1080,9 @@ struct bnxt_tpa_info {
|
||||
struct rx_agg_cmp *agg_arr;
|
||||
};
|
||||
|
||||
#define BNXT_AGG_IDX_BMAP_SIZE (MAX_TPA_P5 / BITS_PER_LONG)
|
||||
|
||||
struct bnxt_tpa_idx_map {
|
||||
u16 agg_id_tbl[1024];
|
||||
unsigned long agg_idx_bmap[BNXT_AGG_IDX_BMAP_SIZE];
|
||||
DECLARE_BITMAP(agg_idx_bmap, MAX_TPA_P5);
|
||||
};
|
||||
|
||||
struct bnxt_rx_ring_info {
|
||||
|
||||
@ -79,9 +79,9 @@ struct enetc_lso_t {
|
||||
#define ENETC_RXB_TRUESIZE (PAGE_SIZE >> 1)
|
||||
#define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */
|
||||
#define ENETC_RXB_DMA_SIZE \
|
||||
(SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD)
|
||||
min(SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD, 0xffff)
|
||||
#define ENETC_RXB_DMA_SIZE_XDP \
|
||||
(SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - XDP_PACKET_HEADROOM)
|
||||
min(SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - XDP_PACKET_HEADROOM, 0xffff)
|
||||
|
||||
struct enetc_rx_swbd {
|
||||
dma_addr_t dma;
|
||||
|
||||
@ -284,8 +284,7 @@ struct idpf_port_stats {
|
||||
|
||||
struct idpf_fsteer_fltr {
|
||||
struct list_head list;
|
||||
u32 loc;
|
||||
u32 q_index;
|
||||
struct ethtool_rx_flow_spec fs;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -424,14 +423,12 @@ enum idpf_user_flags {
|
||||
* @rss_key: RSS hash key
|
||||
* @rss_lut_size: Size of RSS lookup table
|
||||
* @rss_lut: RSS lookup table
|
||||
* @cached_lut: Used to restore previously init RSS lut
|
||||
*/
|
||||
struct idpf_rss_data {
|
||||
u16 rss_key_size;
|
||||
u8 *rss_key;
|
||||
u16 rss_lut_size;
|
||||
u32 *rss_lut;
|
||||
u32 *cached_lut;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -558,6 +555,7 @@ struct idpf_vector_lifo {
|
||||
* @max_q: Maximum possible queues
|
||||
* @req_qs_chunks: Queue chunk data for requested queues
|
||||
* @mac_filter_list_lock: Lock to protect mac filters
|
||||
* @flow_steer_list_lock: Lock to protect fsteer filters
|
||||
* @flags: See enum idpf_vport_config_flags
|
||||
*/
|
||||
struct idpf_vport_config {
|
||||
@ -565,6 +563,7 @@ struct idpf_vport_config {
|
||||
struct idpf_vport_max_q max_q;
|
||||
struct virtchnl2_add_queues *req_qs_chunks;
|
||||
spinlock_t mac_filter_list_lock;
|
||||
spinlock_t flow_steer_list_lock;
|
||||
DECLARE_BITMAP(flags, IDPF_VPORT_CONFIG_FLAGS_NBITS);
|
||||
};
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
||||
{
|
||||
struct idpf_netdev_priv *np = netdev_priv(netdev);
|
||||
struct idpf_vport_user_config_data *user_config;
|
||||
struct idpf_vport_config *vport_config;
|
||||
struct idpf_fsteer_fltr *f;
|
||||
struct idpf_vport *vport;
|
||||
unsigned int cnt = 0;
|
||||
@ -44,7 +45,8 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
||||
|
||||
idpf_vport_ctrl_lock(netdev);
|
||||
vport = idpf_netdev_to_vport(netdev);
|
||||
user_config = &np->adapter->vport_config[np->vport_idx]->user_config;
|
||||
vport_config = np->adapter->vport_config[np->vport_idx];
|
||||
user_config = &vport_config->user_config;
|
||||
|
||||
switch (cmd->cmd) {
|
||||
case ETHTOOL_GRXCLSRLCNT:
|
||||
@ -52,26 +54,34 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
|
||||
cmd->data = idpf_fsteer_max_rules(vport);
|
||||
break;
|
||||
case ETHTOOL_GRXCLSRULE:
|
||||
err = -EINVAL;
|
||||
err = -ENOENT;
|
||||
spin_lock_bh(&vport_config->flow_steer_list_lock);
|
||||
list_for_each_entry(f, &user_config->flow_steer_list, list)
|
||||
if (f->loc == cmd->fs.location) {
|
||||
cmd->fs.ring_cookie = f->q_index;
|
||||
if (f->fs.location == cmd->fs.location) {
|
||||
/* Avoid infoleak from padding: zero first,
|
||||
* then assign fields
|
||||
*/
|
||||
memset(&cmd->fs, 0, sizeof(cmd->fs));
|
||||
cmd->fs = f->fs;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
spin_unlock_bh(&vport_config->flow_steer_list_lock);
|
||||
break;
|
||||
case ETHTOOL_GRXCLSRLALL:
|
||||
cmd->data = idpf_fsteer_max_rules(vport);
|
||||
spin_lock_bh(&vport_config->flow_steer_list_lock);
|
||||
list_for_each_entry(f, &user_config->flow_steer_list, list) {
|
||||
if (cnt == cmd->rule_cnt) {
|
||||
err = -EMSGSIZE;
|
||||
break;
|
||||
}
|
||||
rule_locs[cnt] = f->loc;
|
||||
rule_locs[cnt] = f->fs.location;
|
||||
cnt++;
|
||||
}
|
||||
if (!err)
|
||||
cmd->rule_cnt = user_config->num_fsteer_fltrs;
|
||||
spin_unlock_bh(&vport_config->flow_steer_list_lock);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -168,7 +178,7 @@ static int idpf_add_flow_steer(struct net_device *netdev,
|
||||
struct idpf_vport *vport;
|
||||
u32 flow_type, q_index;
|
||||
u16 num_rxq;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
vport = idpf_netdev_to_vport(netdev);
|
||||
vport_config = vport->adapter->vport_config[np->vport_idx];
|
||||
@ -194,6 +204,29 @@ static int idpf_add_flow_steer(struct net_device *netdev,
|
||||
if (!rule)
|
||||
return -ENOMEM;
|
||||
|
||||
fltr = kzalloc(sizeof(*fltr), GFP_KERNEL);
|
||||
if (!fltr) {
|
||||
err = -ENOMEM;
|
||||
goto out_free_rule;
|
||||
}
|
||||
|
||||
/* detect duplicate entry and reject before adding rules */
|
||||
spin_lock_bh(&vport_config->flow_steer_list_lock);
|
||||
list_for_each_entry(f, &user_config->flow_steer_list, list) {
|
||||
if (f->fs.location == fsp->location) {
|
||||
err = -EEXIST;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->fs.location > fsp->location)
|
||||
break;
|
||||
parent = f;
|
||||
}
|
||||
spin_unlock_bh(&vport_config->flow_steer_list_lock);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
rule->vport_id = cpu_to_le32(vport->vport_id);
|
||||
rule->count = cpu_to_le32(1);
|
||||
info = &rule->rule_info[0];
|
||||
@ -232,26 +265,20 @@ static int idpf_add_flow_steer(struct net_device *netdev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
fltr = kzalloc(sizeof(*fltr), GFP_KERNEL);
|
||||
if (!fltr) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fltr->loc = fsp->location;
|
||||
fltr->q_index = q_index;
|
||||
list_for_each_entry(f, &user_config->flow_steer_list, list) {
|
||||
if (f->loc >= fltr->loc)
|
||||
break;
|
||||
parent = f;
|
||||
}
|
||||
/* Save a copy of the user's flow spec so ethtool can later retrieve it */
|
||||
fltr->fs = *fsp;
|
||||
|
||||
spin_lock_bh(&vport_config->flow_steer_list_lock);
|
||||
parent ? list_add(&fltr->list, &parent->list) :
|
||||
list_add(&fltr->list, &user_config->flow_steer_list);
|
||||
|
||||
user_config->num_fsteer_fltrs++;
|
||||
spin_unlock_bh(&vport_config->flow_steer_list_lock);
|
||||
goto out_free_rule;
|
||||
|
||||
out:
|
||||
kfree(fltr);
|
||||
out_free_rule:
|
||||
kfree(rule);
|
||||
return err;
|
||||
}
|
||||
@ -302,17 +329,20 @@ static int idpf_del_flow_steer(struct net_device *netdev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_bh(&vport_config->flow_steer_list_lock);
|
||||
list_for_each_entry_safe(f, iter,
|
||||
&user_config->flow_steer_list, list) {
|
||||
if (f->loc == fsp->location) {
|
||||
if (f->fs.location == fsp->location) {
|
||||
list_del(&f->list);
|
||||
kfree(f);
|
||||
user_config->num_fsteer_fltrs--;
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
err = -EINVAL;
|
||||
err = -ENOENT;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_bh(&vport_config->flow_steer_list_lock);
|
||||
out:
|
||||
kfree(rule);
|
||||
return err;
|
||||
@ -381,7 +411,10 @@ static u32 idpf_get_rxfh_indir_size(struct net_device *netdev)
|
||||
* @netdev: network interface device structure
|
||||
* @rxfh: pointer to param struct (indir, key, hfunc)
|
||||
*
|
||||
* Reads the indirection table directly from the hardware. Always returns 0.
|
||||
* RSS LUT and Key information are read from driver's cached
|
||||
* copy. When rxhash is off, rss lut will be displayed as zeros.
|
||||
*
|
||||
* Return: 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int idpf_get_rxfh(struct net_device *netdev,
|
||||
struct ethtool_rxfh_param *rxfh)
|
||||
@ -389,10 +422,13 @@ static int idpf_get_rxfh(struct net_device *netdev,
|
||||
struct idpf_netdev_priv *np = netdev_priv(netdev);
|
||||
struct idpf_rss_data *rss_data;
|
||||
struct idpf_adapter *adapter;
|
||||
struct idpf_vport *vport;
|
||||
bool rxhash_ena;
|
||||
int err = 0;
|
||||
u16 i;
|
||||
|
||||
idpf_vport_ctrl_lock(netdev);
|
||||
vport = idpf_netdev_to_vport(netdev);
|
||||
|
||||
adapter = np->adapter;
|
||||
|
||||
@ -402,9 +438,8 @@ static int idpf_get_rxfh(struct net_device *netdev,
|
||||
}
|
||||
|
||||
rss_data = &adapter->vport_config[np->vport_idx]->user_config.rss_data;
|
||||
if (!test_bit(IDPF_VPORT_UP, np->state))
|
||||
goto unlock_mutex;
|
||||
|
||||
rxhash_ena = idpf_is_feature_ena(vport, NETIF_F_RXHASH);
|
||||
rxfh->hfunc = ETH_RSS_HASH_TOP;
|
||||
|
||||
if (rxfh->key)
|
||||
@ -412,7 +447,7 @@ static int idpf_get_rxfh(struct net_device *netdev,
|
||||
|
||||
if (rxfh->indir) {
|
||||
for (i = 0; i < rss_data->rss_lut_size; i++)
|
||||
rxfh->indir[i] = rss_data->rss_lut[i];
|
||||
rxfh->indir[i] = rxhash_ena ? rss_data->rss_lut[i] : 0;
|
||||
}
|
||||
|
||||
unlock_mutex:
|
||||
@ -452,8 +487,6 @@ static int idpf_set_rxfh(struct net_device *netdev,
|
||||
}
|
||||
|
||||
rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data;
|
||||
if (!test_bit(IDPF_VPORT_UP, np->state))
|
||||
goto unlock_mutex;
|
||||
|
||||
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
|
||||
rxfh->hfunc != ETH_RSS_HASH_TOP) {
|
||||
@ -469,7 +502,8 @@ static int idpf_set_rxfh(struct net_device *netdev,
|
||||
rss_data->rss_lut[lut] = rxfh->indir[lut];
|
||||
}
|
||||
|
||||
err = idpf_config_rss(vport);
|
||||
if (test_bit(IDPF_VPORT_UP, np->state))
|
||||
err = idpf_config_rss(vport);
|
||||
|
||||
unlock_mutex:
|
||||
idpf_vport_ctrl_unlock(netdev);
|
||||
|
||||
@ -322,7 +322,7 @@ static void idpf_idc_vport_dev_down(struct idpf_adapter *adapter)
|
||||
for (i = 0; i < adapter->num_alloc_vports; i++) {
|
||||
struct idpf_vport *vport = adapter->vports[i];
|
||||
|
||||
if (!vport)
|
||||
if (!vport || !vport->vdev_info)
|
||||
continue;
|
||||
|
||||
idpf_unplug_aux_dev(vport->vdev_info->adev);
|
||||
|
||||
@ -442,6 +442,29 @@ send_dealloc_vecs:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_del_all_flow_steer_filters - Delete all flow steer filters in list
|
||||
* @vport: main vport struct
|
||||
*
|
||||
* Takes flow_steer_list_lock spinlock. Deletes all filters
|
||||
*/
|
||||
static void idpf_del_all_flow_steer_filters(struct idpf_vport *vport)
|
||||
{
|
||||
struct idpf_vport_config *vport_config;
|
||||
struct idpf_fsteer_fltr *f, *ftmp;
|
||||
|
||||
vport_config = vport->adapter->vport_config[vport->idx];
|
||||
|
||||
spin_lock_bh(&vport_config->flow_steer_list_lock);
|
||||
list_for_each_entry_safe(f, ftmp, &vport_config->user_config.flow_steer_list,
|
||||
list) {
|
||||
list_del(&f->list);
|
||||
kfree(f);
|
||||
}
|
||||
vport_config->user_config.num_fsteer_fltrs = 0;
|
||||
spin_unlock_bh(&vport_config->flow_steer_list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_find_mac_filter - Search filter list for specific mac filter
|
||||
* @vconfig: Vport config structure
|
||||
@ -729,6 +752,65 @@ static int idpf_init_mac_addr(struct idpf_vport *vport,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void idpf_detach_and_close(struct idpf_adapter *adapter)
|
||||
{
|
||||
int max_vports = adapter->max_vports;
|
||||
|
||||
for (int i = 0; i < max_vports; i++) {
|
||||
struct net_device *netdev = adapter->netdevs[i];
|
||||
|
||||
/* If the interface is in detached state, that means the
|
||||
* previous reset was not handled successfully for this
|
||||
* vport.
|
||||
*/
|
||||
if (!netif_device_present(netdev))
|
||||
continue;
|
||||
|
||||
/* Hold RTNL to protect racing with callbacks */
|
||||
rtnl_lock();
|
||||
netif_device_detach(netdev);
|
||||
if (netif_running(netdev)) {
|
||||
set_bit(IDPF_VPORT_UP_REQUESTED,
|
||||
adapter->vport_config[i]->flags);
|
||||
dev_close(netdev);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void idpf_attach_and_open(struct idpf_adapter *adapter)
|
||||
{
|
||||
int max_vports = adapter->max_vports;
|
||||
|
||||
for (int i = 0; i < max_vports; i++) {
|
||||
struct idpf_vport *vport = adapter->vports[i];
|
||||
struct idpf_vport_config *vport_config;
|
||||
struct net_device *netdev;
|
||||
|
||||
/* In case of a critical error in the init task, the vport
|
||||
* will be freed. Only continue to restore the netdevs
|
||||
* if the vport is allocated.
|
||||
*/
|
||||
if (!vport)
|
||||
continue;
|
||||
|
||||
/* No need for RTNL on attach as this function is called
|
||||
* following detach and dev_close(). We do take RTNL for
|
||||
* dev_open() below as it can race with external callbacks
|
||||
* following the call to netif_device_attach().
|
||||
*/
|
||||
netdev = adapter->netdevs[i];
|
||||
netif_device_attach(netdev);
|
||||
vport_config = adapter->vport_config[vport->idx];
|
||||
if (test_and_clear_bit(IDPF_VPORT_UP_REQUESTED,
|
||||
vport_config->flags)) {
|
||||
rtnl_lock();
|
||||
dev_open(netdev, NULL);
|
||||
rtnl_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_cfg_netdev - Allocate, configure and register a netdev
|
||||
* @vport: main vport structure
|
||||
@ -991,7 +1073,7 @@ static void idpf_vport_rel(struct idpf_vport *vport)
|
||||
u16 idx = vport->idx;
|
||||
|
||||
vport_config = adapter->vport_config[vport->idx];
|
||||
idpf_deinit_rss(vport);
|
||||
idpf_deinit_rss_lut(vport);
|
||||
rss_data = &vport_config->user_config.rss_data;
|
||||
kfree(rss_data->rss_key);
|
||||
rss_data->rss_key = NULL;
|
||||
@ -1023,6 +1105,8 @@ static void idpf_vport_rel(struct idpf_vport *vport)
|
||||
kfree(adapter->vport_config[idx]->req_qs_chunks);
|
||||
adapter->vport_config[idx]->req_qs_chunks = NULL;
|
||||
}
|
||||
kfree(vport->rx_ptype_lkup);
|
||||
vport->rx_ptype_lkup = NULL;
|
||||
kfree(vport);
|
||||
adapter->num_alloc_vports--;
|
||||
}
|
||||
@ -1041,12 +1125,15 @@ static void idpf_vport_dealloc(struct idpf_vport *vport)
|
||||
idpf_idc_deinit_vport_aux_device(vport->vdev_info);
|
||||
|
||||
idpf_deinit_mac_addr(vport);
|
||||
idpf_vport_stop(vport, true);
|
||||
|
||||
if (!test_bit(IDPF_HR_RESET_IN_PROG, adapter->flags))
|
||||
if (!test_bit(IDPF_HR_RESET_IN_PROG, adapter->flags)) {
|
||||
idpf_vport_stop(vport, true);
|
||||
idpf_decfg_netdev(vport);
|
||||
if (test_bit(IDPF_REMOVE_IN_PROG, adapter->flags))
|
||||
}
|
||||
if (test_bit(IDPF_REMOVE_IN_PROG, adapter->flags)) {
|
||||
idpf_del_all_mac_filters(vport);
|
||||
idpf_del_all_flow_steer_filters(vport);
|
||||
}
|
||||
|
||||
if (adapter->netdevs[i]) {
|
||||
struct idpf_netdev_priv *np = netdev_priv(adapter->netdevs[i]);
|
||||
@ -1139,6 +1226,7 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
u16 idx = adapter->next_vport;
|
||||
struct idpf_vport *vport;
|
||||
u16 num_max_q;
|
||||
int err;
|
||||
|
||||
if (idx == IDPF_NO_FREE_SLOT)
|
||||
return NULL;
|
||||
@ -1189,10 +1277,11 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
|
||||
idpf_vport_init(vport, max_q);
|
||||
|
||||
/* This alloc is done separate from the LUT because it's not strictly
|
||||
* dependent on how many queues we have. If we change number of queues
|
||||
* and soft reset we'll need a new LUT but the key can remain the same
|
||||
* for as long as the vport exists.
|
||||
/* LUT and key are both initialized here. Key is not strictly dependent
|
||||
* on how many queues we have. If we change number of queues and soft
|
||||
* reset is initiated, LUT will be freed and a new LUT will be allocated
|
||||
* as per the updated number of queues during vport bringup. However,
|
||||
* the key remains the same for as long as the vport exists.
|
||||
*/
|
||||
rss_data = &adapter->vport_config[idx]->user_config.rss_data;
|
||||
rss_data->rss_key = kzalloc(rss_data->rss_key_size, GFP_KERNEL);
|
||||
@ -1202,6 +1291,11 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
/* Initialize default rss key */
|
||||
netdev_rss_key_fill((void *)rss_data->rss_key, rss_data->rss_key_size);
|
||||
|
||||
/* Initialize default rss LUT */
|
||||
err = idpf_init_rss_lut(vport);
|
||||
if (err)
|
||||
goto free_rss_key;
|
||||
|
||||
/* fill vport slot in the adapter struct */
|
||||
adapter->vports[idx] = vport;
|
||||
adapter->vport_ids[idx] = idpf_get_vport_id(vport);
|
||||
@ -1212,6 +1306,8 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
|
||||
|
||||
return vport;
|
||||
|
||||
free_rss_key:
|
||||
kfree(rss_data->rss_key);
|
||||
free_vector_idxs:
|
||||
kfree(vport->q_vector_idxs);
|
||||
free_vport:
|
||||
@ -1388,7 +1484,6 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
|
||||
{
|
||||
struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
|
||||
struct idpf_adapter *adapter = vport->adapter;
|
||||
struct idpf_vport_config *vport_config;
|
||||
int err;
|
||||
|
||||
if (test_bit(IDPF_VPORT_UP, np->state))
|
||||
@ -1429,14 +1524,14 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
|
||||
if (err) {
|
||||
dev_err(&adapter->pdev->dev, "Failed to initialize queue registers for vport %u: %d\n",
|
||||
vport->vport_id, err);
|
||||
goto queues_rel;
|
||||
goto intr_deinit;
|
||||
}
|
||||
|
||||
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 queues_rel;
|
||||
goto intr_deinit;
|
||||
}
|
||||
|
||||
idpf_rx_init_buf_tail(vport);
|
||||
@ -1482,13 +1577,9 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
|
||||
|
||||
idpf_restore_features(vport);
|
||||
|
||||
vport_config = adapter->vport_config[vport->idx];
|
||||
if (vport_config->user_config.rss_data.rss_lut)
|
||||
err = idpf_config_rss(vport);
|
||||
else
|
||||
err = idpf_init_rss(vport);
|
||||
err = idpf_config_rss(vport);
|
||||
if (err) {
|
||||
dev_err(&adapter->pdev->dev, "Failed to initialize RSS for vport %u: %d\n",
|
||||
dev_err(&adapter->pdev->dev, "Failed to configure RSS for vport %u: %d\n",
|
||||
vport->vport_id, err);
|
||||
goto disable_vport;
|
||||
}
|
||||
@ -1497,7 +1588,7 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
|
||||
if (err) {
|
||||
dev_err(&adapter->pdev->dev, "Failed to complete interface up for vport %u: %d\n",
|
||||
vport->vport_id, err);
|
||||
goto deinit_rss;
|
||||
goto disable_vport;
|
||||
}
|
||||
|
||||
if (rtnl)
|
||||
@ -1505,8 +1596,6 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
|
||||
|
||||
return 0;
|
||||
|
||||
deinit_rss:
|
||||
idpf_deinit_rss(vport);
|
||||
disable_vport:
|
||||
idpf_send_disable_vport_msg(vport);
|
||||
disable_queues:
|
||||
@ -1544,7 +1633,6 @@ void idpf_init_task(struct work_struct *work)
|
||||
struct idpf_vport_config *vport_config;
|
||||
struct idpf_vport_max_q max_q;
|
||||
struct idpf_adapter *adapter;
|
||||
struct idpf_netdev_priv *np;
|
||||
struct idpf_vport *vport;
|
||||
u16 num_default_vports;
|
||||
struct pci_dev *pdev;
|
||||
@ -1579,10 +1667,15 @@ void idpf_init_task(struct work_struct *work)
|
||||
goto unwind_vports;
|
||||
}
|
||||
|
||||
err = idpf_send_get_rx_ptype_msg(vport);
|
||||
if (err)
|
||||
goto unwind_vports;
|
||||
|
||||
index = vport->idx;
|
||||
vport_config = adapter->vport_config[index];
|
||||
|
||||
spin_lock_init(&vport_config->mac_filter_list_lock);
|
||||
spin_lock_init(&vport_config->flow_steer_list_lock);
|
||||
|
||||
INIT_LIST_HEAD(&vport_config->user_config.mac_filter_list);
|
||||
INIT_LIST_HEAD(&vport_config->user_config.flow_steer_list);
|
||||
@ -1590,21 +1683,11 @@ void idpf_init_task(struct work_struct *work)
|
||||
err = idpf_check_supported_desc_ids(vport);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to get required descriptor ids\n");
|
||||
goto cfg_netdev_err;
|
||||
goto unwind_vports;
|
||||
}
|
||||
|
||||
if (idpf_cfg_netdev(vport))
|
||||
goto cfg_netdev_err;
|
||||
|
||||
err = idpf_send_get_rx_ptype_msg(vport);
|
||||
if (err)
|
||||
goto handle_err;
|
||||
|
||||
/* Once state is put into DOWN, driver is ready for dev_open */
|
||||
np = netdev_priv(vport->netdev);
|
||||
clear_bit(IDPF_VPORT_UP, np->state);
|
||||
if (test_and_clear_bit(IDPF_VPORT_UP_REQUESTED, vport_config->flags))
|
||||
idpf_vport_open(vport, true);
|
||||
goto unwind_vports;
|
||||
|
||||
/* Spawn and return 'idpf_init_task' work queue until all the
|
||||
* default vports are created
|
||||
@ -1635,21 +1718,15 @@ void idpf_init_task(struct work_struct *work)
|
||||
set_bit(IDPF_VPORT_REG_NETDEV, vport_config->flags);
|
||||
}
|
||||
|
||||
/* As all the required vports are created, clear the reset flag
|
||||
* unconditionally here in case we were in reset and the link was down.
|
||||
*/
|
||||
/* Clear the reset and load bits as all vports are created */
|
||||
clear_bit(IDPF_HR_RESET_IN_PROG, adapter->flags);
|
||||
clear_bit(IDPF_HR_DRV_LOAD, adapter->flags);
|
||||
/* Start the statistics task now */
|
||||
queue_delayed_work(adapter->stats_wq, &adapter->stats_task,
|
||||
msecs_to_jiffies(10 * (pdev->devfn & 0x07)));
|
||||
|
||||
return;
|
||||
|
||||
handle_err:
|
||||
idpf_decfg_netdev(vport);
|
||||
cfg_netdev_err:
|
||||
idpf_vport_rel(vport);
|
||||
adapter->vports[index] = NULL;
|
||||
unwind_vports:
|
||||
if (default_vport) {
|
||||
for (index = 0; index < adapter->max_vports; index++) {
|
||||
@ -1657,6 +1734,15 @@ unwind_vports:
|
||||
idpf_vport_dealloc(adapter->vports[index]);
|
||||
}
|
||||
}
|
||||
/* Cleanup after vc_core_init, which has no way of knowing the
|
||||
* init task failed on driver load.
|
||||
*/
|
||||
if (test_and_clear_bit(IDPF_HR_DRV_LOAD, adapter->flags)) {
|
||||
cancel_delayed_work_sync(&adapter->serv_task);
|
||||
cancel_delayed_work_sync(&adapter->mbx_task);
|
||||
}
|
||||
idpf_ptp_release(adapter);
|
||||
|
||||
clear_bit(IDPF_HR_RESET_IN_PROG, adapter->flags);
|
||||
}
|
||||
|
||||
@ -1786,27 +1872,6 @@ static int idpf_check_reset_complete(struct idpf_hw *hw,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_set_vport_state - Set the vport state to be after the reset
|
||||
* @adapter: Driver specific private structure
|
||||
*/
|
||||
static void idpf_set_vport_state(struct idpf_adapter *adapter)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < adapter->max_vports; i++) {
|
||||
struct idpf_netdev_priv *np;
|
||||
|
||||
if (!adapter->netdevs[i])
|
||||
continue;
|
||||
|
||||
np = netdev_priv(adapter->netdevs[i]);
|
||||
if (test_bit(IDPF_VPORT_UP, np->state))
|
||||
set_bit(IDPF_VPORT_UP_REQUESTED,
|
||||
adapter->vport_config[i]->flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_init_hard_reset - Initiate a hardware reset
|
||||
* @adapter: Driver specific private structure
|
||||
@ -1815,37 +1880,25 @@ static void idpf_set_vport_state(struct idpf_adapter *adapter)
|
||||
* reallocate. Also reinitialize the mailbox. Return 0 on success,
|
||||
* negative on failure.
|
||||
*/
|
||||
static int idpf_init_hard_reset(struct idpf_adapter *adapter)
|
||||
static void idpf_init_hard_reset(struct idpf_adapter *adapter)
|
||||
{
|
||||
struct idpf_reg_ops *reg_ops = &adapter->dev_ops.reg_ops;
|
||||
struct device *dev = &adapter->pdev->dev;
|
||||
struct net_device *netdev;
|
||||
int err;
|
||||
u16 i;
|
||||
|
||||
idpf_detach_and_close(adapter);
|
||||
mutex_lock(&adapter->vport_ctrl_lock);
|
||||
|
||||
dev_info(dev, "Device HW Reset initiated\n");
|
||||
|
||||
/* Avoid TX hangs on reset */
|
||||
for (i = 0; i < adapter->max_vports; i++) {
|
||||
netdev = adapter->netdevs[i];
|
||||
if (!netdev)
|
||||
continue;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
netif_tx_disable(netdev);
|
||||
}
|
||||
|
||||
/* Prepare for reset */
|
||||
if (test_and_clear_bit(IDPF_HR_DRV_LOAD, adapter->flags)) {
|
||||
if (test_bit(IDPF_HR_DRV_LOAD, adapter->flags)) {
|
||||
reg_ops->trigger_reset(adapter, IDPF_HR_DRV_LOAD);
|
||||
} else if (test_and_clear_bit(IDPF_HR_FUNC_RESET, adapter->flags)) {
|
||||
bool is_reset = idpf_is_reset_detected(adapter);
|
||||
|
||||
idpf_idc_issue_reset_event(adapter->cdev_info);
|
||||
|
||||
idpf_set_vport_state(adapter);
|
||||
idpf_vc_core_deinit(adapter);
|
||||
if (!is_reset)
|
||||
reg_ops->trigger_reset(adapter, IDPF_HR_FUNC_RESET);
|
||||
@ -1892,11 +1945,14 @@ static int idpf_init_hard_reset(struct idpf_adapter *adapter)
|
||||
unlock_mutex:
|
||||
mutex_unlock(&adapter->vport_ctrl_lock);
|
||||
|
||||
/* Wait until all vports are created to init RDMA CORE AUX */
|
||||
if (!err)
|
||||
err = idpf_idc_init(adapter);
|
||||
|
||||
return err;
|
||||
/* Attempt to restore netdevs and initialize RDMA CORE AUX device,
|
||||
* provided vc_core_init succeeded. It is still possible that
|
||||
* vports are not allocated at this point if the init task failed.
|
||||
*/
|
||||
if (!err) {
|
||||
idpf_attach_and_open(adapter);
|
||||
idpf_idc_init(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1997,7 +2053,6 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
|
||||
idpf_vport_stop(vport, false);
|
||||
}
|
||||
|
||||
idpf_deinit_rss(vport);
|
||||
/* We're passing in vport here because we need its wait_queue
|
||||
* to send a message and it should be getting all the vport
|
||||
* config data out of the adapter but we need to be careful not
|
||||
@ -2023,6 +2078,10 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
|
||||
if (err)
|
||||
goto err_open;
|
||||
|
||||
if (reset_cause == IDPF_SR_Q_CHANGE &&
|
||||
!netif_is_rxfh_configured(vport->netdev))
|
||||
idpf_fill_dflt_rss_lut(vport);
|
||||
|
||||
if (vport_is_up)
|
||||
err = idpf_vport_open(vport, false);
|
||||
|
||||
@ -2165,40 +2224,6 @@ static void idpf_set_rx_mode(struct net_device *netdev)
|
||||
dev_err(dev, "Failed to set promiscuous mode: %d\n", err);
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_vport_manage_rss_lut - disable/enable RSS
|
||||
* @vport: the vport being changed
|
||||
*
|
||||
* In the event of disable request for RSS, this function will zero out RSS
|
||||
* LUT, while in the event of enable request for RSS, it will reconfigure RSS
|
||||
* LUT with the default LUT configuration.
|
||||
*/
|
||||
static int idpf_vport_manage_rss_lut(struct idpf_vport *vport)
|
||||
{
|
||||
bool ena = idpf_is_feature_ena(vport, NETIF_F_RXHASH);
|
||||
struct idpf_rss_data *rss_data;
|
||||
u16 idx = vport->idx;
|
||||
int lut_size;
|
||||
|
||||
rss_data = &vport->adapter->vport_config[idx]->user_config.rss_data;
|
||||
lut_size = rss_data->rss_lut_size * sizeof(u32);
|
||||
|
||||
if (ena) {
|
||||
/* This will contain the default or user configured LUT */
|
||||
memcpy(rss_data->rss_lut, rss_data->cached_lut, lut_size);
|
||||
} else {
|
||||
/* Save a copy of the current LUT to be restored later if
|
||||
* requested.
|
||||
*/
|
||||
memcpy(rss_data->cached_lut, rss_data->rss_lut, lut_size);
|
||||
|
||||
/* Zero out the current LUT to disable */
|
||||
memset(rss_data->rss_lut, 0, lut_size);
|
||||
}
|
||||
|
||||
return idpf_config_rss(vport);
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_set_features - set the netdev feature flags
|
||||
* @netdev: ptr to the netdev being adjusted
|
||||
@ -2224,10 +2249,19 @@ static int idpf_set_features(struct net_device *netdev,
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_RXHASH) {
|
||||
struct idpf_netdev_priv *np = netdev_priv(netdev);
|
||||
|
||||
netdev->features ^= NETIF_F_RXHASH;
|
||||
err = idpf_vport_manage_rss_lut(vport);
|
||||
if (err)
|
||||
goto unlock_mutex;
|
||||
|
||||
/* If the interface is not up when changing the rxhash, update
|
||||
* to the HW is skipped. The updated LUT will be committed to
|
||||
* the HW when the interface is brought up.
|
||||
*/
|
||||
if (test_bit(IDPF_VPORT_UP, np->state)) {
|
||||
err = idpf_config_rss(vport);
|
||||
if (err)
|
||||
goto unlock_mutex;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_GRO_HW) {
|
||||
|
||||
@ -695,9 +695,10 @@ err:
|
||||
static int idpf_rx_bufs_init_singleq(struct idpf_rx_queue *rxq)
|
||||
{
|
||||
struct libeth_fq fq = {
|
||||
.count = rxq->desc_count,
|
||||
.type = LIBETH_FQE_MTU,
|
||||
.nid = idpf_q_vector_to_mem(rxq->q_vector),
|
||||
.count = rxq->desc_count,
|
||||
.type = LIBETH_FQE_MTU,
|
||||
.buf_len = IDPF_RX_MAX_BUF_SZ,
|
||||
.nid = idpf_q_vector_to_mem(rxq->q_vector),
|
||||
};
|
||||
int ret;
|
||||
|
||||
@ -754,6 +755,7 @@ static int idpf_rx_bufs_init(struct idpf_buf_queue *bufq,
|
||||
.truesize = bufq->truesize,
|
||||
.count = bufq->desc_count,
|
||||
.type = type,
|
||||
.buf_len = IDPF_RX_MAX_BUF_SZ,
|
||||
.hsplit = idpf_queue_has(HSPLIT_EN, bufq),
|
||||
.xdp = idpf_xdp_enabled(bufq->q_vector->vport),
|
||||
.nid = idpf_q_vector_to_mem(bufq->q_vector),
|
||||
@ -4641,7 +4643,7 @@ int idpf_config_rss(struct idpf_vport *vport)
|
||||
* idpf_fill_dflt_rss_lut - Fill the indirection table with the default values
|
||||
* @vport: virtual port structure
|
||||
*/
|
||||
static void idpf_fill_dflt_rss_lut(struct idpf_vport *vport)
|
||||
void idpf_fill_dflt_rss_lut(struct idpf_vport *vport)
|
||||
{
|
||||
struct idpf_adapter *adapter = vport->adapter;
|
||||
u16 num_active_rxq = vport->num_rxq;
|
||||
@ -4650,57 +4652,47 @@ static void idpf_fill_dflt_rss_lut(struct idpf_vport *vport)
|
||||
|
||||
rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data;
|
||||
|
||||
for (i = 0; i < rss_data->rss_lut_size; i++) {
|
||||
for (i = 0; i < rss_data->rss_lut_size; i++)
|
||||
rss_data->rss_lut[i] = i % num_active_rxq;
|
||||
rss_data->cached_lut[i] = rss_data->rss_lut[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_init_rss - Allocate and initialize RSS resources
|
||||
* idpf_init_rss_lut - Allocate and initialize RSS LUT
|
||||
* @vport: virtual port
|
||||
*
|
||||
* Return 0 on success, negative on failure
|
||||
* Return: 0 on success, negative on failure
|
||||
*/
|
||||
int idpf_init_rss(struct idpf_vport *vport)
|
||||
int idpf_init_rss_lut(struct idpf_vport *vport)
|
||||
{
|
||||
struct idpf_adapter *adapter = vport->adapter;
|
||||
struct idpf_rss_data *rss_data;
|
||||
u32 lut_size;
|
||||
|
||||
rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data;
|
||||
if (!rss_data->rss_lut) {
|
||||
u32 lut_size;
|
||||
|
||||
lut_size = rss_data->rss_lut_size * sizeof(u32);
|
||||
rss_data->rss_lut = kzalloc(lut_size, GFP_KERNEL);
|
||||
if (!rss_data->rss_lut)
|
||||
return -ENOMEM;
|
||||
|
||||
rss_data->cached_lut = kzalloc(lut_size, GFP_KERNEL);
|
||||
if (!rss_data->cached_lut) {
|
||||
kfree(rss_data->rss_lut);
|
||||
rss_data->rss_lut = NULL;
|
||||
|
||||
return -ENOMEM;
|
||||
lut_size = rss_data->rss_lut_size * sizeof(u32);
|
||||
rss_data->rss_lut = kzalloc(lut_size, GFP_KERNEL);
|
||||
if (!rss_data->rss_lut)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Fill the default RSS lut values */
|
||||
idpf_fill_dflt_rss_lut(vport);
|
||||
|
||||
return idpf_config_rss(vport);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* idpf_deinit_rss - Release RSS resources
|
||||
* idpf_deinit_rss_lut - Release RSS LUT
|
||||
* @vport: virtual port
|
||||
*/
|
||||
void idpf_deinit_rss(struct idpf_vport *vport)
|
||||
void idpf_deinit_rss_lut(struct idpf_vport *vport)
|
||||
{
|
||||
struct idpf_adapter *adapter = vport->adapter;
|
||||
struct idpf_rss_data *rss_data;
|
||||
|
||||
rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data;
|
||||
kfree(rss_data->cached_lut);
|
||||
rss_data->cached_lut = NULL;
|
||||
kfree(rss_data->rss_lut);
|
||||
rss_data->rss_lut = NULL;
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ do { \
|
||||
idx = 0; \
|
||||
} while (0)
|
||||
|
||||
#define IDPF_RX_MAX_BUF_SZ (16384 - 128)
|
||||
#define IDPF_RX_BUF_STRIDE 32
|
||||
#define IDPF_RX_BUF_POST_STRIDE 16
|
||||
#define IDPF_LOW_WATERMARK 64
|
||||
@ -1085,9 +1086,10 @@ void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector);
|
||||
void idpf_vport_intr_deinit(struct idpf_vport *vport);
|
||||
int idpf_vport_intr_init(struct idpf_vport *vport);
|
||||
void idpf_vport_intr_ena(struct idpf_vport *vport);
|
||||
void idpf_fill_dflt_rss_lut(struct idpf_vport *vport);
|
||||
int idpf_config_rss(struct idpf_vport *vport);
|
||||
int idpf_init_rss(struct idpf_vport *vport);
|
||||
void idpf_deinit_rss(struct idpf_vport *vport);
|
||||
int idpf_init_rss_lut(struct idpf_vport *vport);
|
||||
void idpf_deinit_rss_lut(struct idpf_vport *vport);
|
||||
int idpf_rx_bufs_init_all(struct idpf_vport *vport);
|
||||
|
||||
struct idpf_q_vector *idpf_find_rxq_vec(const struct idpf_vport *vport,
|
||||
|
||||
@ -2804,6 +2804,10 @@ int idpf_send_get_stats_msg(struct idpf_vport *vport)
|
||||
* @vport: virtual port data structure
|
||||
* @get: flag to set or get rss look up table
|
||||
*
|
||||
* When rxhash is disabled, RSS LUT will be configured with zeros. If rxhash
|
||||
* is enabled, the LUT values stored in driver's soft copy will be used to setup
|
||||
* the HW.
|
||||
*
|
||||
* Returns 0 on success, negative on failure.
|
||||
*/
|
||||
int idpf_send_get_set_rss_lut_msg(struct idpf_vport *vport, bool get)
|
||||
@ -2814,10 +2818,12 @@ int idpf_send_get_set_rss_lut_msg(struct idpf_vport *vport, bool get)
|
||||
struct idpf_rss_data *rss_data;
|
||||
int buf_size, lut_buf_size;
|
||||
ssize_t reply_sz;
|
||||
bool rxhash_ena;
|
||||
int i;
|
||||
|
||||
rss_data =
|
||||
&vport->adapter->vport_config[vport->idx]->user_config.rss_data;
|
||||
rxhash_ena = idpf_is_feature_ena(vport, NETIF_F_RXHASH);
|
||||
buf_size = struct_size(rl, lut, rss_data->rss_lut_size);
|
||||
rl = kzalloc(buf_size, GFP_KERNEL);
|
||||
if (!rl)
|
||||
@ -2839,7 +2845,8 @@ int idpf_send_get_set_rss_lut_msg(struct idpf_vport *vport, bool get)
|
||||
} else {
|
||||
rl->lut_entries = cpu_to_le16(rss_data->rss_lut_size);
|
||||
for (i = 0; i < rss_data->rss_lut_size; i++)
|
||||
rl->lut[i] = cpu_to_le32(rss_data->rss_lut[i]);
|
||||
rl->lut[i] = rxhash_ena ?
|
||||
cpu_to_le32(rss_data->rss_lut[i]) : 0;
|
||||
|
||||
xn_params.vc_op = VIRTCHNL2_OP_SET_RSS_LUT;
|
||||
}
|
||||
@ -3570,6 +3577,7 @@ init_failed:
|
||||
*/
|
||||
void idpf_vc_core_deinit(struct idpf_adapter *adapter)
|
||||
{
|
||||
struct idpf_hw *hw = &adapter->hw;
|
||||
bool remove_in_prog;
|
||||
|
||||
if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags))
|
||||
@ -3593,6 +3601,9 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter)
|
||||
|
||||
idpf_vport_params_buf_rel(adapter);
|
||||
|
||||
kfree(hw->lan_regs);
|
||||
hw->lan_regs = NULL;
|
||||
|
||||
kfree(adapter->vports);
|
||||
adapter->vports = NULL;
|
||||
|
||||
|
||||
@ -387,6 +387,8 @@ struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev)
|
||||
|
||||
dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch),
|
||||
dev->dev);
|
||||
if (!dl)
|
||||
return NULL;
|
||||
|
||||
return devlink_priv(dl);
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ struct mlx5e_accel_fs_psp_prot {
|
||||
struct mlx5_flow_table *ft;
|
||||
struct mlx5_flow_group *miss_group;
|
||||
struct mlx5_flow_handle *miss_rule;
|
||||
struct mlx5_modify_hdr *rx_modify_hdr;
|
||||
struct mlx5_flow_destination default_dest;
|
||||
struct mlx5e_psp_rx_err rx_err;
|
||||
u32 refcnt;
|
||||
@ -286,13 +287,19 @@ out_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void accel_psp_fs_rx_fs_destroy(struct mlx5e_accel_fs_psp_prot *fs_prot)
|
||||
static void accel_psp_fs_rx_fs_destroy(struct mlx5e_psp_fs *fs,
|
||||
struct mlx5e_accel_fs_psp_prot *fs_prot)
|
||||
{
|
||||
if (fs_prot->def_rule) {
|
||||
mlx5_del_flow_rules(fs_prot->def_rule);
|
||||
fs_prot->def_rule = NULL;
|
||||
}
|
||||
|
||||
if (fs_prot->rx_modify_hdr) {
|
||||
mlx5_modify_header_dealloc(fs->mdev, fs_prot->rx_modify_hdr);
|
||||
fs_prot->rx_modify_hdr = NULL;
|
||||
}
|
||||
|
||||
if (fs_prot->miss_rule) {
|
||||
mlx5_del_flow_rules(fs_prot->miss_rule);
|
||||
fs_prot->miss_rule = NULL;
|
||||
@ -396,6 +403,7 @@ static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs,
|
||||
modify_hdr = NULL;
|
||||
goto out_err;
|
||||
}
|
||||
fs_prot->rx_modify_hdr = modify_hdr;
|
||||
|
||||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
|
||||
MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT |
|
||||
@ -416,7 +424,7 @@ static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs,
|
||||
goto out;
|
||||
|
||||
out_err:
|
||||
accel_psp_fs_rx_fs_destroy(fs_prot);
|
||||
accel_psp_fs_rx_fs_destroy(fs, fs_prot);
|
||||
out:
|
||||
kvfree(flow_group_in);
|
||||
kvfree(spec);
|
||||
@ -433,7 +441,7 @@ static int accel_psp_fs_rx_destroy(struct mlx5e_psp_fs *fs, enum accel_fs_psp_ty
|
||||
/* The netdev unreg already happened, so all offloaded rule are already removed */
|
||||
fs_prot = &accel_psp->fs_prot[type];
|
||||
|
||||
accel_psp_fs_rx_fs_destroy(fs_prot);
|
||||
accel_psp_fs_rx_fs_destroy(fs, fs_prot);
|
||||
|
||||
accel_psp_fs_rx_err_destroy_ft(fs, &fs_prot->rx_err);
|
||||
|
||||
|
||||
@ -1608,12 +1608,13 @@ void mlx5e_stats_fec_get(struct mlx5e_priv *priv,
|
||||
{
|
||||
int mode = fec_active_mode(priv->mdev);
|
||||
|
||||
if (mode == MLX5E_FEC_NOFEC ||
|
||||
!MLX5_CAP_PCAM_FEATURE(priv->mdev, ppcnt_statistical_group))
|
||||
if (mode == MLX5E_FEC_NOFEC)
|
||||
return;
|
||||
|
||||
fec_set_corrected_bits_total(priv, fec_stats);
|
||||
fec_set_block_stats(priv, mode, fec_stats);
|
||||
if (MLX5_CAP_PCAM_FEATURE(priv->mdev, ppcnt_statistical_group)) {
|
||||
fec_set_corrected_bits_total(priv, fec_stats);
|
||||
fec_set_block_stats(priv, mode, fec_stats);
|
||||
}
|
||||
|
||||
if (MLX5_CAP_PCAM_REG(priv->mdev, pphcr))
|
||||
fec_set_histograms_stats(priv, mode, hist);
|
||||
|
||||
@ -173,10 +173,15 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, unsigned long event,
|
||||
}
|
||||
|
||||
/* Handle multipath entry with lower priority value */
|
||||
if (mp->fib.mfi && mp->fib.mfi != fi &&
|
||||
if (mp->fib.mfi &&
|
||||
(mp->fib.dst != fen_info->dst || mp->fib.dst_len != fen_info->dst_len) &&
|
||||
fi->fib_priority >= mp->fib.priority)
|
||||
mp->fib.dst_len <= fen_info->dst_len &&
|
||||
!(mp->fib.dst_len == fen_info->dst_len &&
|
||||
fi->fib_priority < mp->fib.priority)) {
|
||||
mlx5_core_dbg(ldev->pf[idx].dev,
|
||||
"Multipath entry with lower priority was rejected\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nh_dev0 = mlx5_lag_get_next_fib_dev(ldev, fi, NULL);
|
||||
nh_dev1 = mlx5_lag_get_next_fib_dev(ldev, fi, nh_dev0);
|
||||
|
||||
@ -393,9 +393,11 @@ static int mlx5_query_mcia(struct mlx5_core_dev *dev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*status = MLX5_GET(mcia_reg, out, status);
|
||||
if (*status)
|
||||
if (MLX5_GET(mcia_reg, out, status)) {
|
||||
if (status)
|
||||
*status = MLX5_GET(mcia_reg, out, status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0);
|
||||
memcpy(data, ptr, size);
|
||||
@ -429,7 +431,8 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||
mlx5_qsfp_eeprom_params_set(&query.i2c_address, &query.page, &offset);
|
||||
break;
|
||||
default:
|
||||
mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id);
|
||||
mlx5_core_dbg(dev, "Module ID not recognized: 0x%x\n",
|
||||
module_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@ -2307,14 +2307,16 @@ static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
|
||||
|
||||
/* Now, set PGIDs for each active LAG */
|
||||
for (lag = 0; lag < ocelot->num_phys_ports; lag++) {
|
||||
struct net_device *bond = ocelot->ports[lag]->bond;
|
||||
struct ocelot_port *ocelot_port = ocelot->ports[lag];
|
||||
int num_active_ports = 0;
|
||||
struct net_device *bond;
|
||||
unsigned long bond_mask;
|
||||
u8 aggr_idx[16];
|
||||
|
||||
if (!bond || (visited & BIT(lag)))
|
||||
if (!ocelot_port || !ocelot_port->bond || (visited & BIT(lag)))
|
||||
continue;
|
||||
|
||||
bond = ocelot_port->bond;
|
||||
bond_mask = ocelot_get_bond_mask(ocelot, bond);
|
||||
|
||||
for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) {
|
||||
|
||||
@ -332,6 +332,11 @@ static ssize_t link_device_store(const struct bus_type *bus, const char *buf, si
|
||||
rcu_assign_pointer(nsim_a->peer, nsim_b);
|
||||
rcu_assign_pointer(nsim_b->peer, nsim_a);
|
||||
|
||||
if (netif_running(dev_a) && netif_running(dev_b)) {
|
||||
netif_carrier_on(dev_a);
|
||||
netif_carrier_on(dev_b);
|
||||
}
|
||||
|
||||
out_err:
|
||||
put_net(ns_b);
|
||||
put_net(ns_a);
|
||||
@ -381,6 +386,9 @@ static ssize_t unlink_device_store(const struct bus_type *bus, const char *buf,
|
||||
if (!peer)
|
||||
goto out_put_netns;
|
||||
|
||||
netif_carrier_off(dev);
|
||||
netif_carrier_off(peer->netdev);
|
||||
|
||||
err = 0;
|
||||
RCU_INIT_POINTER(nsim->peer, NULL);
|
||||
RCU_INIT_POINTER(peer->peer, NULL);
|
||||
|
||||
@ -938,6 +938,9 @@ static struct phy_driver mxl_phy_drvs[] = {
|
||||
PHY_ID_MATCH_EXACT(PHY_ID_MXL86110),
|
||||
.name = "MXL86110 Gigabit Ethernet",
|
||||
.config_init = mxl86110_config_init,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_wol = mxl86110_get_wol,
|
||||
.set_wol = mxl86110_set_wol,
|
||||
.led_brightness_set = mxl86110_led_brightness_set,
|
||||
|
||||
@ -765,7 +765,7 @@ static int sfp_smbus_byte_write(struct sfp *sfp, bool a2, u8 dev_addr,
|
||||
dev_addr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return data - (u8 *)buf;
|
||||
}
|
||||
|
||||
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
|
||||
|
||||
@ -168,6 +168,8 @@ static int update_eth_regs_async(pegasus_t *pegasus)
|
||||
netif_device_detach(pegasus->net);
|
||||
netif_err(pegasus, drv, pegasus->net,
|
||||
"%s returned %d\n", __func__, ret);
|
||||
usb_free_urb(async_urb);
|
||||
kfree(req);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3791,7 +3791,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
|
||||
if (vi->has_rss && !netif_is_rxfh_configured(dev)) {
|
||||
old_rss_hdr = vi->rss_hdr;
|
||||
old_rss_trailer = vi->rss_trailer;
|
||||
vi->rss_hdr = devm_kzalloc(&dev->dev, virtnet_rss_hdr_size(vi), GFP_KERNEL);
|
||||
vi->rss_hdr = devm_kzalloc(&vi->vdev->dev, virtnet_rss_hdr_size(vi), GFP_KERNEL);
|
||||
if (!vi->rss_hdr) {
|
||||
vi->rss_hdr = old_rss_hdr;
|
||||
return -ENOMEM;
|
||||
@ -3802,7 +3802,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
|
||||
|
||||
if (!virtnet_commit_rss_command(vi)) {
|
||||
/* restore ctrl_rss if commit_rss_command failed */
|
||||
devm_kfree(&dev->dev, vi->rss_hdr);
|
||||
devm_kfree(&vi->vdev->dev, vi->rss_hdr);
|
||||
vi->rss_hdr = old_rss_hdr;
|
||||
vi->rss_trailer = old_rss_trailer;
|
||||
|
||||
@ -3810,7 +3810,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
|
||||
queue_pairs);
|
||||
return -EINVAL;
|
||||
}
|
||||
devm_kfree(&dev->dev, old_rss_hdr);
|
||||
devm_kfree(&vi->vdev->dev, old_rss_hdr);
|
||||
goto succ;
|
||||
}
|
||||
|
||||
|
||||
@ -4040,7 +4040,7 @@ mac80211_hwsim_nan_dw_start(struct hrtimer *timer)
|
||||
ieee80211_vif_to_wdev(data->nan_device_vif);
|
||||
|
||||
if (data->nan_curr_dw_band == NL80211_BAND_5GHZ)
|
||||
ch = ieee80211_get_channel(hw->wiphy, 5475);
|
||||
ch = ieee80211_get_channel(hw->wiphy, 5745);
|
||||
else
|
||||
ch = ieee80211_get_channel(hw->wiphy, 2437);
|
||||
|
||||
@ -4112,14 +4112,14 @@ static int mac80211_hwsim_stop_nan(struct ieee80211_hw *hw,
|
||||
hrtimer_cancel(&data->nan_timer);
|
||||
data->nan_device_vif = NULL;
|
||||
|
||||
spin_lock(&hwsim_radio_lock);
|
||||
spin_lock_bh(&hwsim_radio_lock);
|
||||
list_for_each_entry(data2, &hwsim_radios, list) {
|
||||
if (data2->nan_device_vif) {
|
||||
nan_cluster_running = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&hwsim_radio_lock);
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
|
||||
if (!nan_cluster_running)
|
||||
memset(hwsim_nan_cluster_id, 0, ETH_ALEN);
|
||||
|
||||
@ -456,6 +456,7 @@ void ipc_mux_deinit(struct iosm_mux *ipc_mux)
|
||||
struct sk_buff_head *free_list;
|
||||
union mux_msg mux_msg;
|
||||
struct sk_buff *skb;
|
||||
int i;
|
||||
|
||||
if (!ipc_mux->initialized)
|
||||
return;
|
||||
@ -479,5 +480,10 @@ void ipc_mux_deinit(struct iosm_mux *ipc_mux)
|
||||
ipc_mux->channel->dl_pipe.is_open = false;
|
||||
}
|
||||
|
||||
if (ipc_mux->protocol != MUX_LITE) {
|
||||
for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++)
|
||||
kfree(ipc_mux->ul_adb.pp_qlt[i]);
|
||||
}
|
||||
|
||||
kfree(ipc_mux);
|
||||
}
|
||||
|
||||
@ -5323,7 +5323,8 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
|
||||
static inline netdev_features_t netdev_add_tso_features(netdev_features_t features,
|
||||
netdev_features_t mask)
|
||||
{
|
||||
return netdev_increment_features(features, NETIF_F_ALL_TSO, mask);
|
||||
return netdev_increment_features(features, NETIF_F_ALL_TSO |
|
||||
NETIF_F_ALL_FOR_ALL, mask);
|
||||
}
|
||||
|
||||
int __netdev_update_features(struct net_device *dev);
|
||||
|
||||
@ -71,12 +71,12 @@ static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev,
|
||||
#define NPU_RX1_DESC_NUM 512
|
||||
|
||||
/* CTRL */
|
||||
#define NPU_RX_DMA_DESC_LAST_MASK BIT(29)
|
||||
#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15)
|
||||
#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1)
|
||||
#define NPU_RX_DMA_DESC_LAST_MASK BIT(27)
|
||||
#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(26, 14)
|
||||
#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(13, 1)
|
||||
#define NPU_RX_DMA_DESC_DONE_MASK BIT(0)
|
||||
/* INFO */
|
||||
#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28)
|
||||
#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 29)
|
||||
#define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26)
|
||||
#define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21)
|
||||
#define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16)
|
||||
|
||||
@ -189,7 +189,6 @@ int br_handle_egress_vlan_tunnel(struct sk_buff *skb,
|
||||
IP_TUNNEL_DECLARE_FLAGS(flags) = { };
|
||||
struct metadata_dst *tunnel_dst;
|
||||
__be64 tunnel_id;
|
||||
int err;
|
||||
|
||||
if (!vlan)
|
||||
return 0;
|
||||
@ -199,9 +198,13 @@ int br_handle_egress_vlan_tunnel(struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
skb_dst_drop(skb);
|
||||
err = skb_vlan_pop(skb);
|
||||
if (err)
|
||||
return err;
|
||||
/* For 802.1ad (QinQ), skb_vlan_pop() incorrectly moves the C-VLAN
|
||||
* from payload to hwaccel after clearing S-VLAN. We only need to
|
||||
* clear the hwaccel S-VLAN; the C-VLAN must stay in payload for
|
||||
* correct VXLAN encapsulation. This is also correct for 802.1Q
|
||||
* where no C-VLAN exists in payload.
|
||||
*/
|
||||
__vlan_hwaccel_clear_tag(skb);
|
||||
|
||||
if (BR_INPUT_SKB_CB(skb)->backup_nhid) {
|
||||
__set_bit(IP_TUNNEL_KEY_BIT, flags);
|
||||
|
||||
@ -1299,7 +1299,7 @@ int ebt_register_template(const struct ebt_table *t, int (*table_init)(struct ne
|
||||
list_for_each_entry(tmpl, &template_tables, list) {
|
||||
if (WARN_ON_ONCE(strcmp(t->name, tmpl->name) == 0)) {
|
||||
mutex_unlock(&ebt_mutex);
|
||||
return -EEXIST;
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4636,12 +4636,14 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
|
||||
{
|
||||
struct sk_buff *list_skb = skb_shinfo(skb)->frag_list;
|
||||
unsigned int tnl_hlen = skb_tnl_header_len(skb);
|
||||
unsigned int delta_truesize = 0;
|
||||
unsigned int delta_len = 0;
|
||||
struct sk_buff *tail = NULL;
|
||||
struct sk_buff *nskb, *tmp;
|
||||
int len_diff, err;
|
||||
|
||||
/* Only skb_gro_receive_list generated skbs arrive here */
|
||||
DEBUG_NET_WARN_ON_ONCE(!(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST));
|
||||
|
||||
skb_push(skb, -skb_network_offset(skb) + offset);
|
||||
|
||||
/* Ensure the head is writeable before touching the shared info */
|
||||
@ -4655,8 +4657,9 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
|
||||
nskb = list_skb;
|
||||
list_skb = list_skb->next;
|
||||
|
||||
DEBUG_NET_WARN_ON_ONCE(nskb->sk);
|
||||
|
||||
err = 0;
|
||||
delta_truesize += nskb->truesize;
|
||||
if (skb_shared(nskb)) {
|
||||
tmp = skb_clone(nskb, GFP_ATOMIC);
|
||||
if (tmp) {
|
||||
@ -4699,7 +4702,6 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
|
||||
goto err_linearize;
|
||||
}
|
||||
|
||||
skb->truesize = skb->truesize - delta_truesize;
|
||||
skb->data_len = skb->data_len - delta_len;
|
||||
skb->len = skb->len - delta_len;
|
||||
|
||||
|
||||
@ -3896,7 +3896,7 @@ void sock_enable_timestamp(struct sock *sk, enum sock_flags flag)
|
||||
int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
|
||||
int level, int type)
|
||||
{
|
||||
struct sock_exterr_skb *serr;
|
||||
struct sock_extended_err ee;
|
||||
struct sk_buff *skb;
|
||||
int copied, err;
|
||||
|
||||
@ -3916,8 +3916,9 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
|
||||
|
||||
sock_recv_timestamp(msg, sk, skb);
|
||||
|
||||
serr = SKB_EXT_ERR(skb);
|
||||
put_cmsg(msg, level, type, sizeof(serr->ee), &serr->ee);
|
||||
/* We must use a bounce buffer for CONFIG_HARDENED_USERCOPY=y */
|
||||
ee = SKB_EXT_ERR(skb)->ee;
|
||||
put_cmsg(msg, level, type, sizeof(ee), &ee);
|
||||
|
||||
msg->msg_flags |= MSG_ERRQUEUE;
|
||||
err = copied;
|
||||
|
||||
@ -564,7 +564,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
|
||||
|
||||
skb_reserve(skb, hlen);
|
||||
skb_reset_network_header(skb);
|
||||
arp = skb_put(skb, arp_hdr_len(dev));
|
||||
skb_put(skb, arp_hdr_len(dev));
|
||||
skb->dev = dev;
|
||||
skb->protocol = htons(ETH_P_ARP);
|
||||
if (!src_hw)
|
||||
@ -572,12 +572,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
|
||||
if (!dest_hw)
|
||||
dest_hw = dev->broadcast;
|
||||
|
||||
/*
|
||||
* Fill the device header for the ARP frame
|
||||
/* Fill the device header for the ARP frame.
|
||||
* Note: skb->head can be changed.
|
||||
*/
|
||||
if (dev_hard_header(skb, dev, ptype, dest_hw, src_hw, skb->len) < 0)
|
||||
goto out;
|
||||
|
||||
arp = arp_hdr(skb);
|
||||
/*
|
||||
* Fill out the arp protocol part.
|
||||
*
|
||||
|
||||
@ -488,6 +488,8 @@ int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
FRAG_CB(skb)->ip_defrag_offset = offset;
|
||||
if (offset)
|
||||
nf_reset_ct(skb);
|
||||
|
||||
return IPFRAG_OK;
|
||||
}
|
||||
|
||||
@ -828,10 +828,8 @@ out:
|
||||
out_free:
|
||||
if (free)
|
||||
kfree(ipc.opt);
|
||||
if (!err) {
|
||||
icmp_out_count(sock_net(sk), user_icmph.type);
|
||||
if (!err)
|
||||
return len;
|
||||
}
|
||||
return err;
|
||||
|
||||
do_confirm:
|
||||
|
||||
@ -2652,10 +2652,8 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
|
||||
if (sk->sk_state == TCP_LISTEN)
|
||||
goto out;
|
||||
|
||||
if (tp->recvmsg_inq) {
|
||||
if (tp->recvmsg_inq)
|
||||
*cmsg_flags = TCP_CMSG_INQ;
|
||||
msg->msg_get_inq = 1;
|
||||
}
|
||||
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
|
||||
|
||||
/* Urgent data needs to be handled specially. */
|
||||
@ -2929,10 +2927,10 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
|
||||
ret = tcp_recvmsg_locked(sk, msg, len, flags, &tss, &cmsg_flags);
|
||||
release_sock(sk);
|
||||
|
||||
if ((cmsg_flags || msg->msg_get_inq) && ret >= 0) {
|
||||
if ((cmsg_flags | msg->msg_get_inq) && ret >= 0) {
|
||||
if (cmsg_flags & TCP_CMSG_TS)
|
||||
tcp_recv_timestamp(msg, sk, &tss);
|
||||
if (msg->msg_get_inq) {
|
||||
if ((cmsg_flags & TCP_CMSG_INQ) | msg->msg_get_inq) {
|
||||
msg->msg_inq = tcp_inq_hint(sk);
|
||||
if (cmsg_flags & TCP_CMSG_INQ)
|
||||
put_cmsg(msg, SOL_TCP, TCP_CM_INQ,
|
||||
|
||||
@ -1851,6 +1851,7 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
|
||||
sk_peek_offset_bwd(sk, len);
|
||||
|
||||
if (!skb_shared(skb)) {
|
||||
skb_orphan(skb);
|
||||
skb_attempt_defer_free(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -90,6 +90,9 @@ next_interface:
|
||||
/* next (or first) interface */
|
||||
iter->sdata = list_prepare_entry(iter->sdata, &local->interfaces, list);
|
||||
list_for_each_entry_continue(iter->sdata, &local->interfaces, list) {
|
||||
if (!ieee80211_sdata_running(iter->sdata))
|
||||
continue;
|
||||
|
||||
/* AP_VLAN has a chanctx pointer but follows AP */
|
||||
if (iter->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
continue;
|
||||
|
||||
@ -1533,6 +1533,10 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc)
|
||||
}
|
||||
}
|
||||
|
||||
sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
|
||||
if (sinfo)
|
||||
sta_set_sinfo(sta, sinfo, true);
|
||||
|
||||
if (sta->uploaded) {
|
||||
ret = drv_sta_state(local, sdata, sta, IEEE80211_STA_NONE,
|
||||
IEEE80211_STA_NOTEXIST);
|
||||
@ -1541,9 +1545,6 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc)
|
||||
|
||||
sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr);
|
||||
|
||||
sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
|
||||
if (sinfo)
|
||||
sta_set_sinfo(sta, sinfo, true);
|
||||
cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
|
||||
kfree(sinfo);
|
||||
|
||||
|
||||
@ -2397,6 +2397,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
|
||||
|
||||
if (chanctx_conf)
|
||||
chandef = &chanctx_conf->def;
|
||||
else if (local->emulate_chanctx)
|
||||
chandef = &local->hw.conf.chandef;
|
||||
else
|
||||
goto fail_rcu;
|
||||
|
||||
|
||||
@ -229,6 +229,7 @@ static int __nf_conncount_add(struct net *net,
|
||||
|
||||
nf_ct_put(found_ct);
|
||||
}
|
||||
list->last_gc = (u32)jiffies;
|
||||
|
||||
add_new_node:
|
||||
if (WARN_ON_ONCE(list->count > INT_MAX)) {
|
||||
@ -248,7 +249,6 @@ add_new_node:
|
||||
conn->jiffies32 = (u32)jiffies;
|
||||
list_add_tail(&conn->node, &list->head);
|
||||
list->count++;
|
||||
list->last_gc = (u32)jiffies;
|
||||
|
||||
out_put:
|
||||
if (refcounted)
|
||||
|
||||
@ -89,7 +89,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
|
||||
if (pf == NFPROTO_UNSPEC) {
|
||||
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) {
|
||||
if (rcu_access_pointer(loggers[i][logger->type])) {
|
||||
ret = -EEXIST;
|
||||
ret = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
@ -97,7 +97,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
|
||||
rcu_assign_pointer(loggers[i][logger->type], logger);
|
||||
} else {
|
||||
if (rcu_access_pointer(loggers[pf][logger->type])) {
|
||||
ret = -EEXIST;
|
||||
ret = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
rcu_assign_pointer(loggers[pf][logger->type], logger);
|
||||
|
||||
@ -4439,7 +4439,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
|
||||
if (!nft_use_inc(&chain->use)) {
|
||||
err = -EMFILE;
|
||||
goto err_release_rule;
|
||||
goto err_destroy_flow;
|
||||
}
|
||||
|
||||
if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
|
||||
@ -4489,6 +4489,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
|
||||
|
||||
err_destroy_flow_rule:
|
||||
nft_use_dec_restore(&chain->use);
|
||||
err_destroy_flow:
|
||||
if (flow)
|
||||
nft_flow_rule_destroy(flow);
|
||||
err_release_rule:
|
||||
|
||||
@ -1317,8 +1317,8 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
|
||||
else
|
||||
dup_end = dup_key;
|
||||
|
||||
if (!memcmp(start, dup_key->data, sizeof(*dup_key->data)) &&
|
||||
!memcmp(end, dup_end->data, sizeof(*dup_end->data))) {
|
||||
if (!memcmp(start, dup_key->data, set->klen) &&
|
||||
!memcmp(end, dup_end->data, set->klen)) {
|
||||
*elem_priv = &dup->priv;
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ static void nft_synproxy_eval_v4(const struct nft_synproxy *priv,
|
||||
struct tcphdr *_tcph,
|
||||
struct synproxy_options *opts)
|
||||
{
|
||||
struct nf_synproxy_info info = priv->info;
|
||||
struct nf_synproxy_info info = READ_ONCE(priv->info);
|
||||
struct net *net = nft_net(pkt);
|
||||
struct synproxy_net *snet = synproxy_pernet(net);
|
||||
struct sk_buff *skb = pkt->skb;
|
||||
@ -79,7 +79,7 @@ static void nft_synproxy_eval_v6(const struct nft_synproxy *priv,
|
||||
struct tcphdr *_tcph,
|
||||
struct synproxy_options *opts)
|
||||
{
|
||||
struct nf_synproxy_info info = priv->info;
|
||||
struct nf_synproxy_info info = READ_ONCE(priv->info);
|
||||
struct net *net = nft_net(pkt);
|
||||
struct synproxy_net *snet = synproxy_pernet(net);
|
||||
struct sk_buff *skb = pkt->skb;
|
||||
@ -340,7 +340,7 @@ static void nft_synproxy_obj_update(struct nft_object *obj,
|
||||
struct nft_synproxy *newpriv = nft_obj_data(newobj);
|
||||
struct nft_synproxy *priv = nft_obj_data(obj);
|
||||
|
||||
priv->info = newpriv->info;
|
||||
WRITE_ONCE(priv->info, newpriv->info);
|
||||
}
|
||||
|
||||
static struct nft_object_type nft_synproxy_obj_type;
|
||||
|
||||
@ -1764,7 +1764,7 @@ EXPORT_SYMBOL_GPL(xt_hook_ops_alloc);
|
||||
int xt_register_template(const struct xt_table *table,
|
||||
int (*table_init)(struct net *net))
|
||||
{
|
||||
int ret = -EEXIST, af = table->af;
|
||||
int ret = -EBUSY, af = table->af;
|
||||
struct xt_template *t;
|
||||
|
||||
mutex_lock(&xt[af].mutex);
|
||||
|
||||
@ -940,6 +940,8 @@ void tcf_idrinfo_destroy(const struct tc_action_ops *ops,
|
||||
int ret;
|
||||
|
||||
idr_for_each_entry_ul(idr, p, tmp, id) {
|
||||
if (IS_ERR(p))
|
||||
continue;
|
||||
if (tc_act_in_hw(p) && !mutex_taken) {
|
||||
rtnl_lock();
|
||||
mutex_taken = true;
|
||||
|
||||
@ -266,21 +266,9 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
|
||||
goto err_cant_do;
|
||||
}
|
||||
|
||||
/* we could easily avoid the clone only if called by ingress and clsact;
|
||||
* since we can't easily detect the clsact caller, skip clone only for
|
||||
* ingress - that covers the TC S/W datapath.
|
||||
*/
|
||||
at_ingress = skb_at_tc_ingress(skb);
|
||||
dont_clone = skb_at_tc_ingress(skb) && is_redirect &&
|
||||
tcf_mirred_can_reinsert(retval);
|
||||
if (!dont_clone) {
|
||||
skb_to_send = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!skb_to_send)
|
||||
goto err_cant_do;
|
||||
}
|
||||
|
||||
want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
|
||||
|
||||
at_ingress = skb_at_tc_ingress(skb);
|
||||
if (dev == skb->dev && want_ingress == at_ingress) {
|
||||
pr_notice_once("tc mirred: Loop (%s:%s --> %s:%s)\n",
|
||||
netdev_name(skb->dev),
|
||||
@ -290,6 +278,18 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
|
||||
goto err_cant_do;
|
||||
}
|
||||
|
||||
/* we could easily avoid the clone only if called by ingress and clsact;
|
||||
* since we can't easily detect the clsact caller, skip clone only for
|
||||
* ingress - that covers the TC S/W datapath.
|
||||
*/
|
||||
dont_clone = skb_at_tc_ingress(skb) && is_redirect &&
|
||||
tcf_mirred_can_reinsert(retval);
|
||||
if (!dont_clone) {
|
||||
skb_to_send = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!skb_to_send)
|
||||
goto err_cant_do;
|
||||
}
|
||||
|
||||
/* All mirred/redirected skbs should clear previous ct info */
|
||||
nf_reset_ct(skb_to_send);
|
||||
if (want_ingress && !at_ingress) /* drop dst for egress -> ingress */
|
||||
|
||||
@ -1481,7 +1481,7 @@ static void qfq_reset_qdisc(struct Qdisc *sch)
|
||||
|
||||
for (i = 0; i < q->clhash.hashsize; i++) {
|
||||
hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) {
|
||||
if (cl->qdisc->q.qlen > 0)
|
||||
if (cl_is_active(cl))
|
||||
qfq_deactivate_class(q, cl);
|
||||
|
||||
qdisc_reset(cl->qdisc);
|
||||
|
||||
@ -2904,7 +2904,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
||||
unsigned int last_len;
|
||||
struct unix_sock *u;
|
||||
int copied = 0;
|
||||
bool do_cmsg;
|
||||
int err = 0;
|
||||
long timeo;
|
||||
int target;
|
||||
@ -2930,9 +2929,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
|
||||
|
||||
u = unix_sk(sk);
|
||||
|
||||
do_cmsg = READ_ONCE(u->recvmsg_inq);
|
||||
if (do_cmsg)
|
||||
msg->msg_get_inq = 1;
|
||||
redo:
|
||||
/* Lock the socket to prevent queue disordering
|
||||
* while sleeps in memcpy_tomsg
|
||||
@ -3090,9 +3086,11 @@ unlock:
|
||||
|
||||
mutex_unlock(&u->iolock);
|
||||
if (msg) {
|
||||
bool do_cmsg = READ_ONCE(u->recvmsg_inq);
|
||||
|
||||
scm_recv_unix(sock, msg, &scm, flags);
|
||||
|
||||
if (msg->msg_get_inq && (copied ?: err) >= 0) {
|
||||
if ((do_cmsg | msg->msg_get_inq) && (copied ?: err) >= 0) {
|
||||
msg->msg_inq = READ_ONCE(u->inq_len);
|
||||
if (do_cmsg)
|
||||
put_cmsg(msg, SOL_SOCKET, SCM_INQ,
|
||||
|
||||
@ -1787,6 +1787,10 @@ static int vsock_accept(struct socket *sock, struct socket *newsock,
|
||||
} else {
|
||||
newsock->state = SS_CONNECTED;
|
||||
sock_graft(connected, newsock);
|
||||
|
||||
set_bit(SOCK_CUSTOM_SOCKOPT,
|
||||
&connected->sk_socket->flags);
|
||||
|
||||
if (vsock_msgzerocopy_allow(vconnected->transport))
|
||||
set_bit(SOCK_SUPPORT_ZC,
|
||||
&connected->sk_socket->flags);
|
||||
|
||||
@ -1101,6 +1101,10 @@ static int compat_standard_call(struct net_device *dev,
|
||||
return ioctl_standard_call(dev, iwr, cmd, info, handler);
|
||||
|
||||
iwp_compat = (struct compat_iw_point *) &iwr->u.data;
|
||||
|
||||
/* struct iw_point has a 32bit hole on 64bit arches. */
|
||||
memset(&iwp, 0, sizeof(iwp));
|
||||
|
||||
iwp.pointer = compat_ptr(iwp_compat->pointer);
|
||||
iwp.length = iwp_compat->length;
|
||||
iwp.flags = iwp_compat->flags;
|
||||
|
||||
@ -228,6 +228,10 @@ int compat_private_call(struct net_device *dev, struct iwreq *iwr,
|
||||
struct iw_point iwp;
|
||||
|
||||
iwp_compat = (struct compat_iw_point *) &iwr->u.data;
|
||||
|
||||
/* struct iw_point has a 32bit hole on 64bit arches. */
|
||||
memset(&iwp, 0, sizeof(iwp));
|
||||
|
||||
iwp.pointer = compat_ptr(iwp_compat->pointer);
|
||||
iwp.length = iwp_compat->length;
|
||||
iwp.flags = iwp_compat->flags;
|
||||
|
||||
@ -51,7 +51,6 @@ install: libynl.a lib/*.h
|
||||
@echo -e "\tINSTALL pyynl"
|
||||
@pip install --prefix=$(DESTDIR)$(prefix) .
|
||||
@make -C generated install
|
||||
@make -C tests install
|
||||
|
||||
run_tests:
|
||||
@$(MAKE) -C tests run_tests
|
||||
|
||||
@ -22,7 +22,7 @@ try:
|
||||
NlError, RtnlFamily, DevlinkFamily, PSPFamily
|
||||
from net.lib.py import CmdExitFailure
|
||||
from net.lib.py import bkg, cmd, bpftool, bpftrace, defer, ethtool, \
|
||||
fd_read_timeout, ip, rand_port, wait_port_listen, wait_file
|
||||
fd_read_timeout, ip, rand_port, wait_port_listen, wait_file, tool
|
||||
from net.lib.py import KsftSkipEx, KsftFailEx, KsftXfailEx
|
||||
from net.lib.py import ksft_disruptive, ksft_exit, ksft_pr, ksft_run, \
|
||||
ksft_setup, ksft_variants, KsftNamedVariant
|
||||
@ -37,7 +37,7 @@ try:
|
||||
"CmdExitFailure",
|
||||
"bkg", "cmd", "bpftool", "bpftrace", "defer", "ethtool",
|
||||
"fd_read_timeout", "ip", "rand_port",
|
||||
"wait_port_listen", "wait_file",
|
||||
"wait_port_listen", "wait_file", "tool",
|
||||
"KsftSkipEx", "KsftFailEx", "KsftXfailEx",
|
||||
"ksft_disruptive", "ksft_exit", "ksft_pr", "ksft_run",
|
||||
"ksft_setup", "ksft_variants", "KsftNamedVariant",
|
||||
|
||||
@ -52,6 +52,39 @@ cleanup_ns()
|
||||
ip netns del nssv
|
||||
}
|
||||
|
||||
is_carrier_up()
|
||||
{
|
||||
local netns="$1"
|
||||
local nsim_dev="$2"
|
||||
|
||||
test "$(ip netns exec "$netns" \
|
||||
cat /sys/class/net/"$nsim_dev"/carrier 2>/dev/null)" -eq 1
|
||||
}
|
||||
|
||||
assert_carrier_up()
|
||||
{
|
||||
local netns="$1"
|
||||
local nsim_dev="$2"
|
||||
|
||||
if ! is_carrier_up "$netns" "$nsim_dev"; then
|
||||
echo "$nsim_dev's carrier should be UP, but it isn't"
|
||||
cleanup_ns
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_carrier_down()
|
||||
{
|
||||
local netns="$1"
|
||||
local nsim_dev="$2"
|
||||
|
||||
if is_carrier_up "$netns" "$nsim_dev"; then
|
||||
echo "$nsim_dev's carrier should be DOWN, but it isn't"
|
||||
cleanup_ns
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
###
|
||||
### Code start
|
||||
###
|
||||
@ -113,6 +146,32 @@ if [ $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# netdevsim carrier state consistency checking
|
||||
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
|
||||
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
|
||||
|
||||
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > "$NSIM_DEV_SYS_UNLINK"
|
||||
|
||||
assert_carrier_down nssv "$NSIM_DEV_1_NAME"
|
||||
assert_carrier_down nscl "$NSIM_DEV_2_NAME"
|
||||
|
||||
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" down
|
||||
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up
|
||||
|
||||
assert_carrier_down nssv "$NSIM_DEV_1_NAME"
|
||||
assert_carrier_down nscl "$NSIM_DEV_2_NAME"
|
||||
|
||||
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
|
||||
|
||||
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
|
||||
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
|
||||
|
||||
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" down
|
||||
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up
|
||||
|
||||
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
|
||||
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
|
||||
|
||||
# send/recv packets
|
||||
|
||||
tmp_file=$(mktemp)
|
||||
|
||||
@ -13,7 +13,7 @@ from .ksft import KsftFailEx, KsftSkipEx, KsftXfailEx, ksft_pr, ksft_eq, \
|
||||
from .netns import NetNS, NetNSEnter
|
||||
from .nsim import NetdevSim, NetdevSimDev
|
||||
from .utils import CmdExitFailure, fd_read_timeout, cmd, bkg, defer, \
|
||||
bpftool, ip, ethtool, bpftrace, rand_port, wait_port_listen, wait_file
|
||||
bpftool, ip, ethtool, bpftrace, rand_port, wait_port_listen, wait_file, tool
|
||||
from .ynl import NlError, YnlFamily, EthtoolFamily, NetdevFamily, RtnlFamily, RtnlAddrFamily
|
||||
from .ynl import NetshaperFamily, DevlinkFamily, PSPFamily
|
||||
|
||||
@ -26,7 +26,7 @@ __all__ = ["KSRC",
|
||||
"NetNS", "NetNSEnter",
|
||||
"CmdExitFailure", "fd_read_timeout", "cmd", "bkg", "defer",
|
||||
"bpftool", "ip", "ethtool", "bpftrace", "rand_port",
|
||||
"wait_port_listen", "wait_file",
|
||||
"wait_port_listen", "wait_file", "tool",
|
||||
"NetdevSim", "NetdevSimDev",
|
||||
"NetshaperFamily", "DevlinkFamily", "PSPFamily", "NlError",
|
||||
"YnlFamily", "EthtoolFamily", "NetdevFamily", "RtnlFamily",
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
top_srcdir = ../../../../..
|
||||
|
||||
CFLAGS += -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INCLUDES)
|
||||
CFLAGS += -I$(top_srcdir)/tools/include
|
||||
|
||||
TEST_PROGS := \
|
||||
diag.sh \
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/time_types.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
extern int optind;
|
||||
|
||||
@ -140,7 +141,7 @@ static void die_usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void xerror(const char *fmt, ...)
|
||||
static void __noreturn xerror(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/inet_diag.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/tcp.h>
|
||||
@ -87,7 +88,7 @@ enum {
|
||||
|
||||
#define rta_getattr(type, value) (*(type *)RTA_DATA(value))
|
||||
|
||||
static void die_perror(const char *msg)
|
||||
static void __noreturn die_perror(const char *msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(1);
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifndef IPPROTO_MPTCP
|
||||
#define IPPROTO_MPTCP 262
|
||||
@ -40,7 +41,7 @@ static int pf = AF_INET;
|
||||
static int proto_tx = IPPROTO_MPTCP;
|
||||
static int proto_rx = IPPROTO_MPTCP;
|
||||
|
||||
static void die_perror(const char *msg)
|
||||
static void __noreturn die_perror(const char *msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(1);
|
||||
@ -52,7 +53,7 @@ static void die_usage(int r)
|
||||
exit(r);
|
||||
}
|
||||
|
||||
static void xerror(const char *fmt, ...)
|
||||
static void __noreturn xerror(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
static int pf = AF_INET;
|
||||
|
||||
@ -127,7 +128,7 @@ struct so_state {
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
static void die_perror(const char *msg)
|
||||
static void __noreturn die_perror(const char *msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(1);
|
||||
@ -139,7 +140,7 @@ static void die_usage(int r)
|
||||
exit(r);
|
||||
}
|
||||
|
||||
static void xerror(const char *fmt, ...)
|
||||
static void __noreturn xerror(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto
|
||||
net6_port_net6_port net_port_mac_proto_net"
|
||||
|
||||
# Reported bugs, also described by TYPE_ variables below
|
||||
BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate"
|
||||
BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate insert_overlap"
|
||||
|
||||
# List of possible paths to pktgen script from kernel tree for performance tests
|
||||
PKTGEN_SCRIPT_PATHS="
|
||||
@ -420,6 +420,18 @@ race_repeat 0
|
||||
perf_duration 0
|
||||
"
|
||||
|
||||
TYPE_insert_overlap="
|
||||
display reject overlapping range on add
|
||||
type_spec ipv4_addr . ipv4_addr
|
||||
chain_spec ip saddr . ip daddr
|
||||
dst addr4
|
||||
proto icmp
|
||||
|
||||
race_repeat 0
|
||||
|
||||
perf_duration 0
|
||||
"
|
||||
|
||||
# Set template for all tests, types and rules are filled in depending on test
|
||||
set_template='
|
||||
flush ruleset
|
||||
@ -1954,6 +1966,37 @@ EOF
|
||||
return 0
|
||||
}
|
||||
|
||||
add_fail()
|
||||
{
|
||||
if nft add element inet filter test "$1" 2>/dev/null ; then
|
||||
err "Returned success for add ${1} given set:"
|
||||
err "$(nft -a list set inet filter test )"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_bug_insert_overlap()
|
||||
{
|
||||
local elements="1.2.3.4 . 1.2.4.1"
|
||||
|
||||
setup veth send_"${proto}" set || return ${ksft_skip}
|
||||
|
||||
add "{ $elements }" || return 1
|
||||
|
||||
elements="1.2.3.0-1.2.3.4 . 1.2.4.1"
|
||||
add_fail "{ $elements }" || return 1
|
||||
|
||||
elements="1.2.3.0-1.2.3.4 . 1.2.4.2"
|
||||
add "{ $elements }" || return 1
|
||||
|
||||
elements="1.2.3.4 . 1.2.4.1-1.2.4.2"
|
||||
add_fail "{ $elements }" || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_reported_issues() {
|
||||
eval test_bug_"${subtest}"
|
||||
}
|
||||
|
||||
@ -1098,5 +1098,52 @@
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "4ed9",
|
||||
"name": "Try to redirect to self on egress with clsact",
|
||||
"category": [
|
||||
"filter",
|
||||
"mirred"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": [
|
||||
"nsPlugin"
|
||||
]
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.10.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY clsact",
|
||||
"$TC filter add dev $DUMMY egress protocol ip prio 10 matchall action mirred egress redirect dev $DUMMY index 1"
|
||||
],
|
||||
"cmdUnderTest": "ping -c1 -W0.01 -I $DUMMY 10.10.10.1",
|
||||
"expExitCode": "1",
|
||||
"verifyCmd": "$TC -j -s actions get action mirred index 1",
|
||||
"matchJSON": [
|
||||
{
|
||||
"total acts": 0
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"order": 1,
|
||||
"kind": "mirred",
|
||||
"mirred_action": "redirect",
|
||||
"direction": "egress",
|
||||
"index": 1,
|
||||
"stats": {
|
||||
"packets": 1,
|
||||
"overlimits": 1
|
||||
},
|
||||
"not_in_hw": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY clsact"
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
@ -2192,6 +2192,33 @@ static void test_stream_nolinger_server(const struct test_opts *opts)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_accepted_setsockopt_client(const struct test_opts *opts)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
|
||||
if (fd < 0) {
|
||||
perror("connect");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_accepted_setsockopt_server(const struct test_opts *opts)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
|
||||
if (fd < 0) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
enable_so_zerocopy_check(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static struct test_case test_cases[] = {
|
||||
{
|
||||
.name = "SOCK_STREAM connection reset",
|
||||
@ -2371,6 +2398,11 @@ static struct test_case test_cases[] = {
|
||||
.run_client = test_seqpacket_unread_bytes_client,
|
||||
.run_server = test_seqpacket_unread_bytes_server,
|
||||
},
|
||||
{
|
||||
.name = "SOCK_STREAM accept()ed socket custom setsockopt()",
|
||||
.run_client = test_stream_accepted_setsockopt_client,
|
||||
.run_server = test_stream_accepted_setsockopt_server,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user