Networking fixes for 5.16-rc6, including fixes from mac80211, wifi, bpf.
Current release - regressions: - dpaa2-eth: fix buffer overrun when reporting ethtool statistics Current release - new code bugs: - bpf: fix incorrect state pruning for <8B spill/fill - iavf: - add missing unlocks in iavf_watchdog_task() - do not override the adapter state in the watchdog task (again) - mlxsw: spectrum_router: consolidate MAC profiles when possible Previous releases - regressions: - mac80211, fix: - rate control, avoid driver crash for retransmitted frames - regression in SSN handling of addba tx - a memory leak where sta_info is not freed - marking TX-during-stop for TX in in_reconfig, prevent stall - cfg80211: acquire wiphy mutex on regulatory work - wifi drivers: fix build regressions and LED config dependency - virtio_net: fix rx_drops stat for small pkts - dsa: mv88e6xxx: unforce speed & duplex in mac_link_down() Previous releases - always broken: - bpf, fix: - kernel address leakage in atomic fetch - kernel address leakage in atomic cmpxchg's r0 aux reg - signed bounds propagation after mov32 - extable fixup offset - extable address check - mac80211: - fix the size used for building probe request - send ADDBA requests using the tid/queue of the aggregation session - agg-tx: don't schedule_and_wake_txq() under sta->lock, avoid deadlocks - validate extended element ID is present - mptcp: - never allow the PM to close a listener subflow (null-defer) - clear 'kern' flag from fallback sockets, prevent crash - fix deadlock in __mptcp_push_pending() - inet_diag: fix kernel-infoleak for UDP sockets - xsk: do not sleep in poll() when need_wakeup set - smc: avoid very long waits in smc_release() - sch_ets: don't remove idle classes from the round-robin list - netdevsim: - zero-initialize memory for bpf map's value, prevent info leak - don't let user space overwrite read only (max) ethtool parms - ixgbe: set X550 MDIO speed before talking to PHY - stmmac: - fix null-deref in flower deletion w/ VLAN prio Rx steering - dwmac-rk: fix oob read in rk_gmac_setup - ice: time stamping fixes - systemport: add global locking for descriptor life cycle Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmG7rdUACgkQMUZtbf5S IrtRvw//etsgeg2+zxe+fBSbe7ZihcCB4yzWUoRDdNzPrLNLsnWxKT1wYblDcZft b1f/SpTy9ycfg+fspn2qET8gzydn4m9xHkjmlQPzmXB9tdIDF6mECFTAXYlar1hQ RQIijpfZYyrZeGdgHpsyq72YC4dpNdbZrxmQFVdpMr3cK8P2N0Dn32bBVa//+jb+ LCv3Uw9C0yNbqhtRIiukkWIE20+/pXtKm0uErDVmvonqFMWPo6mYD0C2PwC20PwR Kv5ok6jH+44fCSwDoLChbB+Wes0AtrIQdUvUwXGXaF3MDfZl+24oLkX5xJl3EHWT 90Mh0k0NhRORgBZ3NItwK7OliohrRHCYxlAXPjg1Dicxl+kxl0wPlva8v64eAA+u ZhwXwaQpCrZNdKoxHJw9kQ/CmbggtxcWkVolbZp3TzDjYY1E7qxuwg51YMhGmGT1 FPjradYGvHKi+thizJiEdiZaMKRc8bpaL0hbpROxFQvfjNwFOwREQhtnXYP3W5Kd lK88fWaH86dxqL+ABvbrMnSZKuNlSL8R/CROWpZuF+vyLRXaxhAvYRrL79bgmkKq zvImnh1mFovdyKGJhibFMdy92X14z8FzoyX3VQuFcl9EB+2NQXnNZ6abDLJlufZX A0jQ5r46Ce/yyaXXmS61PrP7Pf5sxhs/69fqAIDQfSSzpyUKHd4= =VIbd -----END PGP SIGNATURE----- Merge tag 'net-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Networking fixes, including fixes from mac80211, wifi, bpf. Relatively large batches of fixes from BPF and the WiFi stack, calm in general networking. Current release - regressions: - dpaa2-eth: fix buffer overrun when reporting ethtool statistics Current release - new code bugs: - bpf: fix incorrect state pruning for <8B spill/fill - iavf: - add missing unlocks in iavf_watchdog_task() - do not override the adapter state in the watchdog task (again) - mlxsw: spectrum_router: consolidate MAC profiles when possible Previous releases - regressions: - mac80211 fixes: - rate control, avoid driver crash for retransmitted frames - regression in SSN handling of addba tx - a memory leak where sta_info is not freed - marking TX-during-stop for TX in in_reconfig, prevent stall - cfg80211: acquire wiphy mutex on regulatory work - wifi drivers: fix build regressions and LED config dependency - virtio_net: fix rx_drops stat for small pkts - dsa: mv88e6xxx: unforce speed & duplex in mac_link_down() Previous releases - always broken: - bpf fixes: - kernel address leakage in atomic fetch - kernel address leakage in atomic cmpxchg's r0 aux reg - signed bounds propagation after mov32 - extable fixup offset - extable address check - mac80211: - fix the size used for building probe request - send ADDBA requests using the tid/queue of the aggregation session - agg-tx: don't schedule_and_wake_txq() under sta->lock, avoid deadlocks - validate extended element ID is present - mptcp: - never allow the PM to close a listener subflow (null-defer) - clear 'kern' flag from fallback sockets, prevent crash - fix deadlock in __mptcp_push_pending() - inet_diag: fix kernel-infoleak for UDP sockets - xsk: do not sleep in poll() when need_wakeup set - smc: avoid very long waits in smc_release() - sch_ets: don't remove idle classes from the round-robin list - netdevsim: - zero-initialize memory for bpf map's value, prevent info leak - don't let user space overwrite read only (max) ethtool parms - ixgbe: set X550 MDIO speed before talking to PHY - stmmac: - fix null-deref in flower deletion w/ VLAN prio Rx steering - dwmac-rk: fix oob read in rk_gmac_setup - ice: time stamping fixes - systemport: add global locking for descriptor life cycle" * tag 'net-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (89 commits) bpf, selftests: Fix racing issue in btf_skc_cls_ingress test selftest/bpf: Add a test that reads various addresses. bpf: Fix extable address check. bpf: Fix extable fixup offset. bpf, selftests: Add test case trying to taint map value pointer bpf: Make 32->64 bounds propagation slightly more robust bpf: Fix signed bounds propagation after mov32 sit: do not call ipip6_dev_free() from sit_init_net() net: systemport: Add global locking for descriptor lifecycle net/smc: Prevent smc_release() from long blocking net: Fix double 0x prefix print in SKB dump virtio_net: fix rx_drops stat for small pkts dsa: mv88e6xxx: fix debug print for SPEED_UNFORCED sfc_ef100: potential dereference of null pointer net: stmmac: dwmac-rk: fix oob read in rk_gmac_setup net: usb: lan78xx: add Allied Telesis AT29M2-AF net/packet: rx_owner_map depends on pg_vec netdevsim: Zero-initialize memory for new map's value in function nsim_bpf_map_alloc dpaa2-eth: fix ethtool statistics ixgbe: set X550 MDIO speed before talking to PHY ...
This commit is contained in:
commit
180f3bcfe3
|
@ -440,6 +440,22 @@ NOTE: For 82599-based network connections, if you are enabling jumbo frames in
|
|||
a virtual function (VF), jumbo frames must first be enabled in the physical
|
||||
function (PF). The VF MTU setting cannot be larger than the PF MTU.
|
||||
|
||||
NBASE-T Support
|
||||
---------------
|
||||
The ixgbe driver supports NBASE-T on some devices. However, the advertisement
|
||||
of NBASE-T speeds is suppressed by default, to accommodate broken network
|
||||
switches which cannot cope with advertised NBASE-T speeds. Use the ethtool
|
||||
command to enable advertising NBASE-T speeds on devices which support it::
|
||||
|
||||
ethtool -s eth? advertise 0x1800000001028
|
||||
|
||||
On Linux systems with INTERFACES(5), this can be specified as a pre-up command
|
||||
in /etc/network/interfaces so that the interface is always brought up with
|
||||
NBASE-T support, e.g.::
|
||||
|
||||
iface eth? inet dhcp
|
||||
pre-up ethtool -s eth? advertise 0x1800000001028 || true
|
||||
|
||||
Generic Receive Offload, aka GRO
|
||||
--------------------------------
|
||||
The driver supports the in-kernel software implementation of GRO. GRO has
|
||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -3066,7 +3066,7 @@ F: Documentation/devicetree/bindings/phy/phy-ath79-usb.txt
|
|||
F: drivers/phy/qualcomm/phy-ath79-usb.c
|
||||
|
||||
ATHEROS ATH GENERIC UTILITIES
|
||||
M: Kalle Valo <kvalo@codeaurora.org>
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/wireless/ath/*
|
||||
|
@ -3081,7 +3081,7 @@ W: https://wireless.wiki.kernel.org/en/users/Drivers/ath5k
|
|||
F: drivers/net/wireless/ath/ath5k/
|
||||
|
||||
ATHEROS ATH6KL WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@codeaurora.org>
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath6kl
|
||||
|
@ -13248,7 +13248,7 @@ F: include/uapi/linux/if_*
|
|||
F: include/uapi/linux/netdevice.h
|
||||
|
||||
NETWORKING DRIVERS (WIRELESS)
|
||||
M: Kalle Valo <kvalo@codeaurora.org>
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
Q: http://patchwork.kernel.org/project/linux-wireless/list/
|
||||
|
@ -15704,7 +15704,7 @@ T: git git://linuxtv.org/anttip/media_tree.git
|
|||
F: drivers/media/tuners/qt1010*
|
||||
|
||||
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@codeaurora.org>
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: ath10k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
|
||||
|
@ -15712,7 +15712,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
|||
F: drivers/net/wireless/ath/ath10k/
|
||||
|
||||
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@codeaurora.org>
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: ath11k@lists.infradead.org
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
||||
|
@ -15885,7 +15885,7 @@ F: Documentation/devicetree/bindings/media/*venus*
|
|||
F: drivers/media/platform/qcom/venus/
|
||||
|
||||
QUALCOMM WCN36XX WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@codeaurora.org>
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: wcn36xx@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/wcn36xx
|
||||
|
|
|
@ -1252,19 +1252,54 @@ st: if (is_imm8(insn->off))
|
|||
case BPF_LDX | BPF_MEM | BPF_DW:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
|
||||
if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
|
||||
/* test src_reg, src_reg */
|
||||
maybe_emit_mod(&prog, src_reg, src_reg, true); /* always 1 byte */
|
||||
EMIT2(0x85, add_2reg(0xC0, src_reg, src_reg));
|
||||
/* jne start_of_ldx */
|
||||
EMIT2(X86_JNE, 0);
|
||||
/* Though the verifier prevents negative insn->off in BPF_PROBE_MEM
|
||||
* add abs(insn->off) to the limit to make sure that negative
|
||||
* offset won't be an issue.
|
||||
* insn->off is s16, so it won't affect valid pointers.
|
||||
*/
|
||||
u64 limit = TASK_SIZE_MAX + PAGE_SIZE + abs(insn->off);
|
||||
u8 *end_of_jmp1, *end_of_jmp2;
|
||||
|
||||
/* Conservatively check that src_reg + insn->off is a kernel address:
|
||||
* 1. src_reg + insn->off >= limit
|
||||
* 2. src_reg + insn->off doesn't become small positive.
|
||||
* Cannot do src_reg + insn->off >= limit in one branch,
|
||||
* since it needs two spare registers, but JIT has only one.
|
||||
*/
|
||||
|
||||
/* movabsq r11, limit */
|
||||
EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG));
|
||||
EMIT((u32)limit, 4);
|
||||
EMIT(limit >> 32, 4);
|
||||
/* cmp src_reg, r11 */
|
||||
maybe_emit_mod(&prog, src_reg, AUX_REG, true);
|
||||
EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG));
|
||||
/* if unsigned '<' goto end_of_jmp2 */
|
||||
EMIT2(X86_JB, 0);
|
||||
end_of_jmp1 = prog;
|
||||
|
||||
/* mov r11, src_reg */
|
||||
emit_mov_reg(&prog, true, AUX_REG, src_reg);
|
||||
/* add r11, insn->off */
|
||||
maybe_emit_1mod(&prog, AUX_REG, true);
|
||||
EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off);
|
||||
/* jmp if not carry to start_of_ldx
|
||||
* Otherwise ERR_PTR(-EINVAL) + 128 will be the user addr
|
||||
* that has to be rejected.
|
||||
*/
|
||||
EMIT2(0x73 /* JNC */, 0);
|
||||
end_of_jmp2 = prog;
|
||||
|
||||
/* xor dst_reg, dst_reg */
|
||||
emit_mov_imm32(&prog, false, dst_reg, 0);
|
||||
/* jmp byte_after_ldx */
|
||||
EMIT2(0xEB, 0);
|
||||
|
||||
/* populate jmp_offset for JNE above */
|
||||
temp[4] = prog - temp - 5 /* sizeof(test + jne) */;
|
||||
/* populate jmp_offset for JB above to jump to xor dst_reg */
|
||||
end_of_jmp1[-1] = end_of_jmp2 - end_of_jmp1;
|
||||
/* populate jmp_offset for JNC above to jump to start_of_ldx */
|
||||
start_of_ldx = prog;
|
||||
end_of_jmp2[-1] = start_of_ldx - end_of_jmp2;
|
||||
}
|
||||
emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
|
||||
if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
|
||||
|
@ -1305,7 +1340,7 @@ st: if (is_imm8(insn->off))
|
|||
* End result: x86 insn "mov rbx, qword ptr [rax+0x14]"
|
||||
* of 4 bytes will be ignored and rbx will be zero inited.
|
||||
*/
|
||||
ex->fixup = (prog - temp) | (reg2pt_regs[dst_reg] << 8);
|
||||
ex->fixup = (prog - start_of_ldx) | (reg2pt_regs[dst_reg] << 8);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -768,6 +768,10 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
|||
if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) && ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, false);
|
||||
|
||||
if (!err && ops->port_set_speed_duplex)
|
||||
err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED,
|
||||
DUPLEX_UNFORCED);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
if (err)
|
||||
|
|
|
@ -283,7 +283,7 @@ static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (speed)
|
||||
if (speed != SPEED_UNFORCED)
|
||||
dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
|
||||
else
|
||||
dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
|
||||
|
@ -516,7 +516,7 @@ int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (speed)
|
||||
if (speed != SPEED_UNFORCED)
|
||||
dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
|
||||
else
|
||||
dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
|
||||
|
|
|
@ -1309,11 +1309,11 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
|
|||
struct bcm_sysport_priv *priv = netdev_priv(dev);
|
||||
struct device *kdev = &priv->pdev->dev;
|
||||
struct bcm_sysport_tx_ring *ring;
|
||||
unsigned long flags, desc_flags;
|
||||
struct bcm_sysport_cb *cb;
|
||||
struct netdev_queue *txq;
|
||||
u32 len_status, addr_lo;
|
||||
unsigned int skb_len;
|
||||
unsigned long flags;
|
||||
dma_addr_t mapping;
|
||||
u16 queue;
|
||||
int ret;
|
||||
|
@ -1373,8 +1373,10 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
|
|||
ring->desc_count--;
|
||||
|
||||
/* Ports are latched, so write upper address first */
|
||||
spin_lock_irqsave(&priv->desc_lock, desc_flags);
|
||||
tdma_writel(priv, len_status, TDMA_WRITE_PORT_HI(ring->index));
|
||||
tdma_writel(priv, addr_lo, TDMA_WRITE_PORT_LO(ring->index));
|
||||
spin_unlock_irqrestore(&priv->desc_lock, desc_flags);
|
||||
|
||||
/* Check ring space and update SW control flow */
|
||||
if (ring->desc_count == 0)
|
||||
|
@ -2013,6 +2015,7 @@ static int bcm_sysport_open(struct net_device *dev)
|
|||
}
|
||||
|
||||
/* Initialize both hardware and software ring */
|
||||
spin_lock_init(&priv->desc_lock);
|
||||
for (i = 0; i < dev->num_tx_queues; i++) {
|
||||
ret = bcm_sysport_init_tx_ring(priv, i);
|
||||
if (ret) {
|
||||
|
|
|
@ -711,6 +711,7 @@ struct bcm_sysport_priv {
|
|||
int wol_irq;
|
||||
|
||||
/* Transmit rings */
|
||||
spinlock_t desc_lock;
|
||||
struct bcm_sysport_tx_ring *tx_rings;
|
||||
|
||||
/* Receive queue */
|
||||
|
|
|
@ -589,9 +589,9 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
|
|||
* Internal or external PHY with MDIO access
|
||||
*/
|
||||
phydev = phy_attach(priv->dev, phy_name, pd->phy_interface);
|
||||
if (!phydev) {
|
||||
if (IS_ERR(phydev)) {
|
||||
dev_err(kdev, "failed to register PHY device\n");
|
||||
return -ENODEV;
|
||||
return PTR_ERR(phydev);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
|
|
@ -388,6 +388,8 @@ struct dpaa2_eth_ch_stats {
|
|||
__u64 bytes_per_cdan;
|
||||
};
|
||||
|
||||
#define DPAA2_ETH_CH_STATS 7
|
||||
|
||||
/* Maximum number of queues associated with a DPNI */
|
||||
#define DPAA2_ETH_MAX_TCS 8
|
||||
#define DPAA2_ETH_MAX_RX_QUEUES_PER_TC 16
|
||||
|
|
|
@ -278,7 +278,7 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
|
|||
/* Per-channel stats */
|
||||
for (k = 0; k < priv->num_channels; k++) {
|
||||
ch_stats = &priv->channel[k]->stats;
|
||||
for (j = 0; j < sizeof(*ch_stats) / sizeof(__u64) - 1; j++)
|
||||
for (j = 0; j < DPAA2_ETH_CH_STATS; j++)
|
||||
*((__u64 *)data + i + j) += *((__u64 *)ch_stats + j);
|
||||
}
|
||||
i += j;
|
||||
|
|
|
@ -839,6 +839,8 @@ struct hnae3_handle {
|
|||
|
||||
u8 netdev_flags;
|
||||
struct dentry *hnae3_dbgfs;
|
||||
/* protects concurrent contention between debugfs commands */
|
||||
struct mutex dbgfs_lock;
|
||||
|
||||
/* Network interface message level enabled bits */
|
||||
u32 msg_enable;
|
||||
|
|
|
@ -1226,6 +1226,7 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&handle->dbgfs_lock);
|
||||
save_buf = &hns3_dbg_cmd[index].buf;
|
||||
|
||||
if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
|
||||
|
@ -1238,15 +1239,15 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
|
|||
read_buf = *save_buf;
|
||||
} else {
|
||||
read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
|
||||
if (!read_buf)
|
||||
return -ENOMEM;
|
||||
if (!read_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* save the buffer addr until the last read operation */
|
||||
*save_buf = read_buf;
|
||||
}
|
||||
|
||||
/* get data ready for the first time to read */
|
||||
if (!*ppos) {
|
||||
/* get data ready for the first time to read */
|
||||
ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
|
||||
read_buf, hns3_dbg_cmd[index].buf_len);
|
||||
if (ret)
|
||||
|
@ -1255,8 +1256,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
|
|||
|
||||
size = simple_read_from_buffer(buffer, count, ppos, read_buf,
|
||||
strlen(read_buf));
|
||||
if (size > 0)
|
||||
if (size > 0) {
|
||||
mutex_unlock(&handle->dbgfs_lock);
|
||||
return size;
|
||||
}
|
||||
|
||||
out:
|
||||
/* free the buffer for the last read operation */
|
||||
|
@ -1265,6 +1268,7 @@ out:
|
|||
*save_buf = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&handle->dbgfs_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1337,6 +1341,8 @@ int hns3_dbg_init(struct hnae3_handle *handle)
|
|||
debugfs_create_dir(hns3_dbg_dentry[i].name,
|
||||
handle->hnae3_dbgfs);
|
||||
|
||||
mutex_init(&handle->dbgfs_lock);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
|
||||
if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
|
||||
ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
|
||||
|
@ -1363,6 +1369,7 @@ int hns3_dbg_init(struct hnae3_handle *handle)
|
|||
return 0;
|
||||
|
||||
out:
|
||||
mutex_destroy(&handle->dbgfs_lock);
|
||||
debugfs_remove_recursive(handle->hnae3_dbgfs);
|
||||
handle->hnae3_dbgfs = NULL;
|
||||
return ret;
|
||||
|
@ -1378,6 +1385,7 @@ void hns3_dbg_uninit(struct hnae3_handle *handle)
|
|||
hns3_dbg_cmd[i].buf = NULL;
|
||||
}
|
||||
|
||||
mutex_destroy(&handle->dbgfs_lock);
|
||||
debugfs_remove_recursive(handle->hnae3_dbgfs);
|
||||
handle->hnae3_dbgfs = NULL;
|
||||
}
|
||||
|
|
|
@ -114,7 +114,8 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev,
|
|||
|
||||
memcpy(&req->msg, send_msg, sizeof(struct hclge_vf_to_pf_msg));
|
||||
|
||||
trace_hclge_vf_mbx_send(hdev, req);
|
||||
if (test_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state))
|
||||
trace_hclge_vf_mbx_send(hdev, req);
|
||||
|
||||
/* synchronous send */
|
||||
if (need_resp) {
|
||||
|
|
|
@ -2046,6 +2046,7 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|||
}
|
||||
adapter->aq_required = 0;
|
||||
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
queue_delayed_work(iavf_wq,
|
||||
&adapter->watchdog_task,
|
||||
msecs_to_jiffies(10));
|
||||
|
@ -2076,16 +2077,14 @@ static void iavf_watchdog_task(struct work_struct *work)
|
|||
iavf_detect_recover_hung(&adapter->vsi);
|
||||
break;
|
||||
case __IAVF_REMOVE:
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
return;
|
||||
default:
|
||||
mutex_unlock(&adapter->crit_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for hw reset */
|
||||
reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK;
|
||||
if (!reg_val) {
|
||||
iavf_change_state(adapter, __IAVF_RESETTING);
|
||||
adapter->flags |= IAVF_FLAG_RESET_PENDING;
|
||||
adapter->aq_required = 0;
|
||||
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
|
||||
|
|
|
@ -705,7 +705,7 @@ static int ice_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
|
|||
scaled_ppm = -scaled_ppm;
|
||||
}
|
||||
|
||||
while ((u64)scaled_ppm > div_u64(U64_MAX, incval)) {
|
||||
while ((u64)scaled_ppm > div64_u64(U64_MAX, incval)) {
|
||||
/* handle overflow by scaling down the scaled_ppm and
|
||||
* the divisor, losing some precision
|
||||
*/
|
||||
|
@ -1540,19 +1540,16 @@ static void ice_ptp_tx_tstamp_work(struct kthread_work *work)
|
|||
if (err)
|
||||
continue;
|
||||
|
||||
/* Check if the timestamp is valid */
|
||||
if (!(raw_tstamp & ICE_PTP_TS_VALID))
|
||||
/* Check if the timestamp is invalid or stale */
|
||||
if (!(raw_tstamp & ICE_PTP_TS_VALID) ||
|
||||
raw_tstamp == tx->tstamps[idx].cached_tstamp)
|
||||
continue;
|
||||
|
||||
/* clear the timestamp register, so that it won't show valid
|
||||
* again when re-used.
|
||||
*/
|
||||
ice_clear_phy_tstamp(hw, tx->quad, phy_idx);
|
||||
|
||||
/* The timestamp is valid, so we'll go ahead and clear this
|
||||
* index and then send the timestamp up to the stack.
|
||||
*/
|
||||
spin_lock(&tx->lock);
|
||||
tx->tstamps[idx].cached_tstamp = raw_tstamp;
|
||||
clear_bit(idx, tx->in_use);
|
||||
skb = tx->tstamps[idx].skb;
|
||||
tx->tstamps[idx].skb = NULL;
|
||||
|
|
|
@ -55,15 +55,21 @@ struct ice_perout_channel {
|
|||
* struct ice_tx_tstamp - Tracking for a single Tx timestamp
|
||||
* @skb: pointer to the SKB for this timestamp request
|
||||
* @start: jiffies when the timestamp was first requested
|
||||
* @cached_tstamp: last read timestamp
|
||||
*
|
||||
* This structure tracks a single timestamp request. The SKB pointer is
|
||||
* provided when initiating a request. The start time is used to ensure that
|
||||
* we discard old requests that were not fulfilled within a 2 second time
|
||||
* window.
|
||||
* Timestamp values in the PHY are read only and do not get cleared except at
|
||||
* hardware reset or when a new timestamp value is captured. The cached_tstamp
|
||||
* field is used to detect the case where a new timestamp has not yet been
|
||||
* captured, ensuring that we avoid sending stale timestamp data to the stack.
|
||||
*/
|
||||
struct ice_tx_tstamp {
|
||||
struct sk_buff *skb;
|
||||
unsigned long start;
|
||||
u64 cached_tstamp;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -7648,6 +7648,20 @@ static int igb_set_vf_mac_filter(struct igb_adapter *adapter, const int vf,
|
|||
struct vf_mac_filter *entry = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) &&
|
||||
!vf_data->trusted) {
|
||||
dev_warn(&pdev->dev,
|
||||
"VF %d requested MAC filter but is administratively denied\n",
|
||||
vf);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!is_valid_ether_addr(addr)) {
|
||||
dev_warn(&pdev->dev,
|
||||
"VF %d attempted to set invalid MAC filter\n",
|
||||
vf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (info) {
|
||||
case E1000_VF_MAC_FILTER_CLR:
|
||||
/* remove all unicast MAC filters related to the current VF */
|
||||
|
@ -7661,20 +7675,6 @@ static int igb_set_vf_mac_filter(struct igb_adapter *adapter, const int vf,
|
|||
}
|
||||
break;
|
||||
case E1000_VF_MAC_FILTER_ADD:
|
||||
if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) &&
|
||||
!vf_data->trusted) {
|
||||
dev_warn(&pdev->dev,
|
||||
"VF %d requested MAC filter but is administratively denied\n",
|
||||
vf);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!is_valid_ether_addr(addr)) {
|
||||
dev_warn(&pdev->dev,
|
||||
"VF %d attempted to set invalid MAC filter\n",
|
||||
vf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* try to find empty slot in the list */
|
||||
list_for_each(pos, &adapter->vf_macs.l) {
|
||||
entry = list_entry(pos, struct vf_mac_filter, l);
|
||||
|
|
|
@ -2859,6 +2859,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
return 0;
|
||||
|
||||
err_hw_init:
|
||||
netif_napi_del(&adapter->rx_ring->napi);
|
||||
kfree(adapter->tx_ring);
|
||||
kfree(adapter->rx_ring);
|
||||
err_sw_init:
|
||||
|
|
|
@ -636,7 +636,7 @@ s32 igc_set_ltr_i225(struct igc_hw *hw, bool link)
|
|||
ltrv = rd32(IGC_LTRMAXV);
|
||||
if (ltr_max != (ltrv & IGC_LTRMAXV_LTRV_MASK)) {
|
||||
ltrv = IGC_LTRMAXV_LSNP_REQ | ltr_max |
|
||||
(scale_min << IGC_LTRMAXV_SCALE_SHIFT);
|
||||
(scale_max << IGC_LTRMAXV_SCALE_SHIFT);
|
||||
wr32(IGC_LTRMAXV, ltrv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5531,6 +5531,10 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
|
|||
if (!speed && hw->mac.ops.get_link_capabilities) {
|
||||
ret = hw->mac.ops.get_link_capabilities(hw, &speed,
|
||||
&autoneg);
|
||||
/* remove NBASE-T speeds from default autonegotiation
|
||||
* to accommodate broken network switches in the field
|
||||
* which cannot cope with advertised NBASE-T speeds
|
||||
*/
|
||||
speed &= ~(IXGBE_LINK_SPEED_5GB_FULL |
|
||||
IXGBE_LINK_SPEED_2_5GB_FULL);
|
||||
}
|
||||
|
|
|
@ -3405,6 +3405,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
|
|||
/* flush pending Tx transactions */
|
||||
ixgbe_clear_tx_pending(hw);
|
||||
|
||||
/* set MDIO speed before talking to the PHY in case it's the 1st time */
|
||||
ixgbe_set_mdio_speed(hw);
|
||||
|
||||
/* PHY ops must be identified and initialized prior to reset */
|
||||
status = hw->phy.ops.init(hw);
|
||||
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED ||
|
||||
|
|
|
@ -8494,7 +8494,8 @@ mlxsw_sp_rif_mac_profile_replace(struct mlxsw_sp *mlxsw_sp,
|
|||
u8 mac_profile;
|
||||
int err;
|
||||
|
||||
if (!mlxsw_sp_rif_mac_profile_is_shared(rif))
|
||||
if (!mlxsw_sp_rif_mac_profile_is_shared(rif) &&
|
||||
!mlxsw_sp_rif_mac_profile_find(mlxsw_sp, new_mac))
|
||||
return mlxsw_sp_rif_mac_profile_edit(rif, new_mac);
|
||||
|
||||
err = mlxsw_sp_rif_mac_profile_get(mlxsw_sp, new_mac,
|
||||
|
|
|
@ -609,6 +609,9 @@ static size_t ef100_update_stats(struct efx_nic *efx,
|
|||
ef100_common_stat_mask(mask);
|
||||
ef100_ethtool_stat_mask(mask);
|
||||
|
||||
if (!mc_stats)
|
||||
return 0;
|
||||
|
||||
efx_nic_copy_stats(efx, mc_stats);
|
||||
efx_nic_update_stats(ef100_stat_desc, EF100_STAT_COUNT, mask,
|
||||
stats, mc_stats, false);
|
||||
|
|
|
@ -33,6 +33,7 @@ struct rk_gmac_ops {
|
|||
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
|
||||
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
|
||||
void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
|
||||
bool regs_valid;
|
||||
u32 regs[];
|
||||
};
|
||||
|
||||
|
@ -1092,6 +1093,7 @@ static const struct rk_gmac_ops rk3568_ops = {
|
|||
.set_to_rmii = rk3568_set_to_rmii,
|
||||
.set_rgmii_speed = rk3568_set_gmac_speed,
|
||||
.set_rmii_speed = rk3568_set_gmac_speed,
|
||||
.regs_valid = true,
|
||||
.regs = {
|
||||
0xfe2a0000, /* gmac0 */
|
||||
0xfe010000, /* gmac1 */
|
||||
|
@ -1383,7 +1385,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
|
|||
* to be distinguished.
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res) {
|
||||
if (res && ops->regs_valid) {
|
||||
int i = 0;
|
||||
|
||||
while (ops->regs[i]) {
|
||||
|
|
|
@ -172,6 +172,19 @@ struct stmmac_flow_entry {
|
|||
int is_l4;
|
||||
};
|
||||
|
||||
/* Rx Frame Steering */
|
||||
enum stmmac_rfs_type {
|
||||
STMMAC_RFS_T_VLAN,
|
||||
STMMAC_RFS_T_MAX,
|
||||
};
|
||||
|
||||
struct stmmac_rfs_entry {
|
||||
unsigned long cookie;
|
||||
int in_use;
|
||||
int type;
|
||||
int tc;
|
||||
};
|
||||
|
||||
struct stmmac_priv {
|
||||
/* Frequently used values are kept adjacent for cache effect */
|
||||
u32 tx_coal_frames[MTL_MAX_TX_QUEUES];
|
||||
|
@ -289,6 +302,10 @@ struct stmmac_priv {
|
|||
struct stmmac_tc_entry *tc_entries;
|
||||
unsigned int flow_entries_max;
|
||||
struct stmmac_flow_entry *flow_entries;
|
||||
unsigned int rfs_entries_max[STMMAC_RFS_T_MAX];
|
||||
unsigned int rfs_entries_cnt[STMMAC_RFS_T_MAX];
|
||||
unsigned int rfs_entries_total;
|
||||
struct stmmac_rfs_entry *rfs_entries;
|
||||
|
||||
/* Pulse Per Second output */
|
||||
struct stmmac_pps_cfg pps[STMMAC_PPS_MAX];
|
||||
|
|
|
@ -1461,16 +1461,20 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
|
|||
{
|
||||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
|
||||
gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
|
||||
|
||||
if (priv->dma_cap.addr64 <= 32)
|
||||
gfp |= GFP_DMA32;
|
||||
|
||||
if (!buf->page) {
|
||||
buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->page = page_pool_alloc_pages(rx_q->page_pool, gfp);
|
||||
if (!buf->page)
|
||||
return -ENOMEM;
|
||||
buf->page_offset = stmmac_rx_offset(priv);
|
||||
}
|
||||
|
||||
if (priv->sph && !buf->sec_page) {
|
||||
buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->sec_page = page_pool_alloc_pages(rx_q->page_pool, gfp);
|
||||
if (!buf->sec_page)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -4482,6 +4486,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
|
|||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
int dirty = stmmac_rx_dirty(priv, queue);
|
||||
unsigned int entry = rx_q->dirty_rx;
|
||||
gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
|
||||
|
||||
if (priv->dma_cap.addr64 <= 32)
|
||||
gfp |= GFP_DMA32;
|
||||
|
||||
while (dirty-- > 0) {
|
||||
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[entry];
|
||||
|
@ -4494,13 +4502,13 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
|
|||
p = rx_q->dma_rx + entry;
|
||||
|
||||
if (!buf->page) {
|
||||
buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->page = page_pool_alloc_pages(rx_q->page_pool, gfp);
|
||||
if (!buf->page)
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->sph && !buf->sec_page) {
|
||||
buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->sec_page = page_pool_alloc_pages(rx_q->page_pool, gfp);
|
||||
if (!buf->sec_page)
|
||||
break;
|
||||
|
||||
|
|
|
@ -232,11 +232,33 @@ static int tc_setup_cls_u32(struct stmmac_priv *priv,
|
|||
}
|
||||
}
|
||||
|
||||
static int tc_rfs_init(struct stmmac_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
priv->rfs_entries_max[STMMAC_RFS_T_VLAN] = 8;
|
||||
|
||||
for (i = 0; i < STMMAC_RFS_T_MAX; i++)
|
||||
priv->rfs_entries_total += priv->rfs_entries_max[i];
|
||||
|
||||
priv->rfs_entries = devm_kcalloc(priv->device,
|
||||
priv->rfs_entries_total,
|
||||
sizeof(*priv->rfs_entries),
|
||||
GFP_KERNEL);
|
||||
if (!priv->rfs_entries)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_info(priv->device, "Enabled RFS Flow TC (entries=%d)\n",
|
||||
priv->rfs_entries_total);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tc_init(struct stmmac_priv *priv)
|
||||
{
|
||||
struct dma_features *dma_cap = &priv->dma_cap;
|
||||
unsigned int count;
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
if (dma_cap->l3l4fnum) {
|
||||
priv->flow_entries_max = dma_cap->l3l4fnum;
|
||||
|
@ -250,10 +272,14 @@ static int tc_init(struct stmmac_priv *priv)
|
|||
for (i = 0; i < priv->flow_entries_max; i++)
|
||||
priv->flow_entries[i].idx = i;
|
||||
|
||||
dev_info(priv->device, "Enabled Flow TC (entries=%d)\n",
|
||||
dev_info(priv->device, "Enabled L3L4 Flow TC (entries=%d)\n",
|
||||
priv->flow_entries_max);
|
||||
}
|
||||
|
||||
ret = tc_rfs_init(priv);
|
||||
if (ret)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!priv->plat->fpe_cfg) {
|
||||
priv->plat->fpe_cfg = devm_kzalloc(priv->device,
|
||||
sizeof(*priv->plat->fpe_cfg),
|
||||
|
@ -607,16 +633,45 @@ static int tc_del_flow(struct stmmac_priv *priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct stmmac_rfs_entry *tc_find_rfs(struct stmmac_priv *priv,
|
||||
struct flow_cls_offload *cls,
|
||||
bool get_free)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->rfs_entries_total; i++) {
|
||||
struct stmmac_rfs_entry *entry = &priv->rfs_entries[i];
|
||||
|
||||
if (entry->cookie == cls->cookie)
|
||||
return entry;
|
||||
if (get_free && entry->in_use == false)
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define VLAN_PRIO_FULL_MASK (0x07)
|
||||
|
||||
static int tc_add_vlan_flow(struct stmmac_priv *priv,
|
||||
struct flow_cls_offload *cls)
|
||||
{
|
||||
struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false);
|
||||
struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
|
||||
struct flow_dissector *dissector = rule->match.dissector;
|
||||
int tc = tc_classid_to_hwtc(priv->dev, cls->classid);
|
||||
struct flow_match_vlan match;
|
||||
|
||||
if (!entry) {
|
||||
entry = tc_find_rfs(priv, cls, true);
|
||||
if (!entry)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (priv->rfs_entries_cnt[STMMAC_RFS_T_VLAN] >=
|
||||
priv->rfs_entries_max[STMMAC_RFS_T_VLAN])
|
||||
return -ENOENT;
|
||||
|
||||
/* Nothing to do here */
|
||||
if (!dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_VLAN))
|
||||
return -EINVAL;
|
||||
|
@ -638,6 +693,12 @@ static int tc_add_vlan_flow(struct stmmac_priv *priv,
|
|||
|
||||
prio = BIT(match.key->vlan_priority);
|
||||
stmmac_rx_queue_prio(priv, priv->hw, prio, tc);
|
||||
|
||||
entry->in_use = true;
|
||||
entry->cookie = cls->cookie;
|
||||
entry->tc = tc;
|
||||
entry->type = STMMAC_RFS_T_VLAN;
|
||||
priv->rfs_entries_cnt[STMMAC_RFS_T_VLAN]++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -646,20 +707,19 @@ static int tc_add_vlan_flow(struct stmmac_priv *priv,
|
|||
static int tc_del_vlan_flow(struct stmmac_priv *priv,
|
||||
struct flow_cls_offload *cls)
|
||||
{
|
||||
struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
|
||||
struct flow_dissector *dissector = rule->match.dissector;
|
||||
int tc = tc_classid_to_hwtc(priv->dev, cls->classid);
|
||||
struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false);
|
||||
|
||||
/* Nothing to do here */
|
||||
if (!dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_VLAN))
|
||||
return -EINVAL;
|
||||
if (!entry || !entry->in_use || entry->type != STMMAC_RFS_T_VLAN)
|
||||
return -ENOENT;
|
||||
|
||||
if (tc < 0) {
|
||||
netdev_err(priv->dev, "Invalid traffic class\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
stmmac_rx_queue_prio(priv, priv->hw, 0, entry->tc);
|
||||
|
||||
stmmac_rx_queue_prio(priv, priv->hw, 0, tc);
|
||||
entry->in_use = false;
|
||||
entry->cookie = 0;
|
||||
entry->tc = 0;
|
||||
entry->type = 0;
|
||||
|
||||
priv->rfs_entries_cnt[STMMAC_RFS_T_VLAN]--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1844,13 +1844,14 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
|||
if (ret < 0) {
|
||||
dev_err(dev, "%pOF error reading port_id %d\n",
|
||||
port_np, ret);
|
||||
return ret;
|
||||
goto of_node_put;
|
||||
}
|
||||
|
||||
if (!port_id || port_id > common->port_num) {
|
||||
dev_err(dev, "%pOF has invalid port_id %u %s\n",
|
||||
port_np, port_id, port_np->name);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto of_node_put;
|
||||
}
|
||||
|
||||
port = am65_common_get_port(common, port_id);
|
||||
|
@ -1866,8 +1867,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
|||
(AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1));
|
||||
|
||||
port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base);
|
||||
if (IS_ERR(port->slave.mac_sl))
|
||||
return PTR_ERR(port->slave.mac_sl);
|
||||
if (IS_ERR(port->slave.mac_sl)) {
|
||||
ret = PTR_ERR(port->slave.mac_sl);
|
||||
goto of_node_put;
|
||||
}
|
||||
|
||||
port->disabled = !of_device_is_available(port_np);
|
||||
if (port->disabled) {
|
||||
|
@ -1880,7 +1883,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
|||
ret = PTR_ERR(port->slave.ifphy);
|
||||
dev_err(dev, "%pOF error retrieving port phy: %d\n",
|
||||
port_np, ret);
|
||||
return ret;
|
||||
goto of_node_put;
|
||||
}
|
||||
|
||||
port->slave.mac_only =
|
||||
|
@ -1889,10 +1892,12 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
|||
/* get phy/link info */
|
||||
if (of_phy_is_fixed_link(port_np)) {
|
||||
ret = of_phy_register_fixed_link(port_np);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
if (ret) {
|
||||
ret = dev_err_probe(dev, ret,
|
||||
"failed to register fixed-link phy %pOF\n",
|
||||
port_np);
|
||||
goto of_node_put;
|
||||
}
|
||||
port->slave.phy_node = of_node_get(port_np);
|
||||
} else {
|
||||
port->slave.phy_node =
|
||||
|
@ -1902,14 +1907,15 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
|||
if (!port->slave.phy_node) {
|
||||
dev_err(dev,
|
||||
"slave[%d] no phy found\n", port_id);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto of_node_put;
|
||||
}
|
||||
|
||||
ret = of_get_phy_mode(port_np, &port->slave.phy_if);
|
||||
if (ret) {
|
||||
dev_err(dev, "%pOF read phy-mode err %d\n",
|
||||
port_np, ret);
|
||||
return ret;
|
||||
goto of_node_put;
|
||||
}
|
||||
|
||||
ret = of_get_mac_address(port_np, port->slave.mac_addr);
|
||||
|
@ -1932,6 +1938,11 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
of_node_put:
|
||||
of_node_put(port_np);
|
||||
of_node_put(node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void am65_cpsw_pcpu_stats_free(void *data)
|
||||
|
|
|
@ -514,6 +514,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
|
|||
goto err_free;
|
||||
key = nmap->entry[i].key;
|
||||
*key = i;
|
||||
memset(nmap->entry[i].value, 0, offmap->map.value_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,10 @@ static int nsim_set_ringparam(struct net_device *dev,
|
|||
{
|
||||
struct netdevsim *ns = netdev_priv(dev);
|
||||
|
||||
memcpy(&ns->ethtool.ring, ring, sizeof(ns->ethtool.ring));
|
||||
ns->ethtool.ring.rx_pending = ring->rx_pending;
|
||||
ns->ethtool.ring.rx_jumbo_pending = ring->rx_jumbo_pending;
|
||||
ns->ethtool.ring.rx_mini_pending = ring->rx_mini_pending;
|
||||
ns->ethtool.ring.tx_pending = ring->tx_pending;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -460,6 +460,9 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
|
|||
|
||||
if (addr == mdiodev->addr) {
|
||||
device_set_node(dev, of_fwnode_handle(child));
|
||||
/* The refcount on "child" is passed to the mdio
|
||||
* device. Do _not_ use of_node_put(child) here.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
#define LAN7801_USB_PRODUCT_ID (0x7801)
|
||||
#define LAN78XX_EEPROM_MAGIC (0x78A5)
|
||||
#define LAN78XX_OTP_MAGIC (0x78F3)
|
||||
#define AT29M2AF_USB_VENDOR_ID (0x07C9)
|
||||
#define AT29M2AF_USB_PRODUCT_ID (0x0012)
|
||||
|
||||
#define MII_READ 1
|
||||
#define MII_WRITE 0
|
||||
|
@ -4734,6 +4736,10 @@ static const struct usb_device_id products[] = {
|
|||
/* LAN7801 USB Gigabit Ethernet Device */
|
||||
USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID),
|
||||
},
|
||||
{
|
||||
/* ATM2-AF USB Gigabit Ethernet Device */
|
||||
USB_DEVICE(AT29M2AF_USB_VENDOR_ID, AT29M2AF_USB_PRODUCT_ID),
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
|
|
|
@ -1358,6 +1358,7 @@ static const struct usb_device_id products[] = {
|
|||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
||||
|
|
|
@ -733,7 +733,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
|
|||
pr_debug("%s: rx error: len %u exceeds max size %d\n",
|
||||
dev->name, len, GOOD_PACKET_LEN);
|
||||
dev->stats.rx_length_errors++;
|
||||
goto err_len;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (likely(!vi->xdp_enabled)) {
|
||||
|
@ -825,10 +825,8 @@ static struct sk_buff *receive_small(struct net_device *dev,
|
|||
|
||||
skip_xdp:
|
||||
skb = build_skb(buf, buflen);
|
||||
if (!skb) {
|
||||
put_page(page);
|
||||
if (!skb)
|
||||
goto err;
|
||||
}
|
||||
skb_reserve(skb, headroom - delta);
|
||||
skb_put(skb, len);
|
||||
if (!xdp_prog) {
|
||||
|
@ -839,13 +837,12 @@ skip_xdp:
|
|||
if (metasize)
|
||||
skb_metadata_set(skb, metasize);
|
||||
|
||||
err:
|
||||
return skb;
|
||||
|
||||
err_xdp:
|
||||
rcu_read_unlock();
|
||||
stats->xdp_drops++;
|
||||
err_len:
|
||||
err:
|
||||
stats->drops++;
|
||||
put_page(page);
|
||||
xdp_xmit:
|
||||
|
|
|
@ -7,16 +7,20 @@ config BRCMSMAC
|
|||
depends on MAC80211
|
||||
depends on BCMA_POSSIBLE
|
||||
select BCMA
|
||||
select NEW_LEDS if BCMA_DRIVER_GPIO
|
||||
select LEDS_CLASS if BCMA_DRIVER_GPIO
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CORDIC
|
||||
help
|
||||
This module adds support for PCIe wireless adapters based on Broadcom
|
||||
IEEE802.11n SoftMAC chipsets. It also has WLAN led support, which will
|
||||
be available if you select BCMA_DRIVER_GPIO. If you choose to build a
|
||||
module, the driver will be called brcmsmac.ko.
|
||||
IEEE802.11n SoftMAC chipsets. If you choose to build a module, the
|
||||
driver will be called brcmsmac.ko.
|
||||
|
||||
config BRCMSMAC_LEDS
|
||||
def_bool BRCMSMAC && BCMA_DRIVER_GPIO && MAC80211_LEDS
|
||||
help
|
||||
The brcmsmac LED support depends on the presence of the
|
||||
BCMA_DRIVER_GPIO driver, and it only works if LED support
|
||||
is enabled and reachable from the driver module.
|
||||
|
||||
source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ brcmsmac-y := \
|
|||
brcms_trace_events.o \
|
||||
debug.o
|
||||
|
||||
brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
|
||||
brcmsmac-$(CONFIG_BRCMSMAC_LEDS) += led.o
|
||||
|
||||
obj-$(CONFIG_BRCMSMAC) += brcmsmac.o
|
||||
|
|
|
@ -24,7 +24,7 @@ struct brcms_led {
|
|||
struct gpio_desc *gpiod;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
#ifdef CONFIG_BRCMSMAC_LEDS
|
||||
void brcms_led_unregister(struct brcms_info *wl);
|
||||
int brcms_led_register(struct brcms_info *wl);
|
||||
#else
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
config IWLEGACY
|
||||
tristate
|
||||
select FW_LOADER
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
select LEDS_TRIGGERS
|
||||
select MAC80211_LEDS
|
||||
|
||||
config IWL4965
|
||||
tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
|
||||
depends on PCI && MAC80211
|
||||
depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
|
||||
select IWLEGACY
|
||||
help
|
||||
This option enables support for
|
||||
|
@ -38,6 +37,7 @@ config IWL4965
|
|||
config IWL3945
|
||||
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
|
||||
depends on PCI && MAC80211
|
||||
depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
|
||||
select IWLEGACY
|
||||
help
|
||||
Select to build the driver supporting the:
|
||||
|
|
|
@ -47,7 +47,7 @@ if IWLWIFI
|
|||
|
||||
config IWLWIFI_LEDS
|
||||
bool
|
||||
depends on LEDS_CLASS=y || LEDS_CLASS=IWLWIFI
|
||||
depends on LEDS_CLASS=y || LEDS_CLASS=MAC80211
|
||||
depends on IWLMVM || IWLDVM
|
||||
select LEDS_TRIGGERS
|
||||
select MAC80211_LEDS
|
||||
|
|
|
@ -269,17 +269,18 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
|
|||
u8 rate_plcp;
|
||||
u32 rate_flags = 0;
|
||||
bool is_cck;
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
/* info->control is only relevant for non HW rate control */
|
||||
if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
|
||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
/* HT rate doesn't make sense for a non data frame */
|
||||
WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS &&
|
||||
!ieee80211_is_data(fc),
|
||||
"Got a HT rate (flags:0x%x/mcs:%d/fc:0x%x/state:%d) for a non data frame\n",
|
||||
info->control.rates[0].flags,
|
||||
info->control.rates[0].idx,
|
||||
le16_to_cpu(fc), mvmsta->sta_state);
|
||||
le16_to_cpu(fc), sta ? mvmsta->sta_state : -1);
|
||||
|
||||
rate_idx = info->control.rates[0].idx;
|
||||
}
|
||||
|
|
|
@ -34,4 +34,4 @@ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
|
|||
obj-$(CONFIG_MT7603E) += mt7603/
|
||||
obj-$(CONFIG_MT7615_COMMON) += mt7615/
|
||||
obj-$(CONFIG_MT7915E) += mt7915/
|
||||
obj-$(CONFIG_MT7921E) += mt7921/
|
||||
obj-$(CONFIG_MT7921_COMMON) += mt7921/
|
||||
|
|
|
@ -136,19 +136,21 @@ struct mptcp_info {
|
|||
* MPTCP_EVENT_REMOVED: token, rem_id
|
||||
* An address has been lost by the peer.
|
||||
*
|
||||
* MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6,
|
||||
* daddr4 | daddr6, sport, dport, backup,
|
||||
* if_idx [, error]
|
||||
* MPTCP_EVENT_SUB_ESTABLISHED: token, family, loc_id, rem_id,
|
||||
* saddr4 | saddr6, daddr4 | daddr6, sport,
|
||||
* dport, backup, if_idx [, error]
|
||||
* A new subflow has been established. 'error' should not be set.
|
||||
*
|
||||
* MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6,
|
||||
* sport, dport, backup, if_idx [, error]
|
||||
* MPTCP_EVENT_SUB_CLOSED: token, family, loc_id, rem_id, saddr4 | saddr6,
|
||||
* daddr4 | daddr6, sport, dport, backup, if_idx
|
||||
* [, error]
|
||||
* A subflow has been closed. An error (copy of sk_err) could be set if an
|
||||
* error has been detected for this subflow.
|
||||
*
|
||||
* MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6,
|
||||
* sport, dport, backup, if_idx [, error]
|
||||
* The priority of a subflow has changed. 'error' should not be set.
|
||||
* MPTCP_EVENT_SUB_PRIORITY: token, family, loc_id, rem_id, saddr4 | saddr6,
|
||||
* daddr4 | daddr6, sport, dport, backup, if_idx
|
||||
* [, error]
|
||||
* The priority of a subflow has changed. 'error' should not be set.
|
||||
*/
|
||||
enum mptcp_event_type {
|
||||
MPTCP_EVENT_UNSPEC = 0,
|
||||
|
|
|
@ -1366,22 +1366,28 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
|
|||
reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
|
||||
}
|
||||
|
||||
static bool __reg32_bound_s64(s32 a)
|
||||
{
|
||||
return a >= 0 && a <= S32_MAX;
|
||||
}
|
||||
|
||||
static void __reg_assign_32_into_64(struct bpf_reg_state *reg)
|
||||
{
|
||||
reg->umin_value = reg->u32_min_value;
|
||||
reg->umax_value = reg->u32_max_value;
|
||||
/* Attempt to pull 32-bit signed bounds into 64-bit bounds
|
||||
* but must be positive otherwise set to worse case bounds
|
||||
* and refine later from tnum.
|
||||
|
||||
/* Attempt to pull 32-bit signed bounds into 64-bit bounds but must
|
||||
* be positive otherwise set to worse case bounds and refine later
|
||||
* from tnum.
|
||||
*/
|
||||
if (reg->s32_min_value >= 0 && reg->s32_max_value >= 0)
|
||||
reg->smax_value = reg->s32_max_value;
|
||||
else
|
||||
reg->smax_value = U32_MAX;
|
||||
if (reg->s32_min_value >= 0)
|
||||
if (__reg32_bound_s64(reg->s32_min_value) &&
|
||||
__reg32_bound_s64(reg->s32_max_value)) {
|
||||
reg->smin_value = reg->s32_min_value;
|
||||
else
|
||||
reg->smax_value = reg->s32_max_value;
|
||||
} else {
|
||||
reg->smin_value = 0;
|
||||
reg->smax_value = U32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static void __reg_combine_32_into_64(struct bpf_reg_state *reg)
|
||||
|
@ -2379,8 +2385,6 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
|
|||
*/
|
||||
if (insn->src_reg != BPF_REG_FP)
|
||||
return 0;
|
||||
if (BPF_SIZE(insn->code) != BPF_DW)
|
||||
return 0;
|
||||
|
||||
/* dreg = *(u64 *)[fp - off] was a fill from the stack.
|
||||
* that [fp - off] slot contains scalar that needs to be
|
||||
|
@ -2403,8 +2407,6 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
|
|||
/* scalars can only be spilled into stack */
|
||||
if (insn->dst_reg != BPF_REG_FP)
|
||||
return 0;
|
||||
if (BPF_SIZE(insn->code) != BPF_DW)
|
||||
return 0;
|
||||
spi = (-insn->off - 1) / BPF_REG_SIZE;
|
||||
if (spi >= 64) {
|
||||
verbose(env, "BUG spi %d\n", spi);
|
||||
|
@ -4551,9 +4553,16 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
|
|||
|
||||
if (insn->imm == BPF_CMPXCHG) {
|
||||
/* Check comparison of R0 with memory location */
|
||||
err = check_reg_arg(env, BPF_REG_0, SRC_OP);
|
||||
const u32 aux_reg = BPF_REG_0;
|
||||
|
||||
err = check_reg_arg(env, aux_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (is_pointer_value(env, aux_reg)) {
|
||||
verbose(env, "R%d leaks addr into mem\n", aux_reg);
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_pointer_value(env, insn->src_reg)) {
|
||||
|
@ -4588,13 +4597,19 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
|
|||
load_reg = -1;
|
||||
}
|
||||
|
||||
/* check whether we can read the memory */
|
||||
/* Check whether we can read the memory, with second call for fetch
|
||||
* case to simulate the register fill.
|
||||
*/
|
||||
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
||||
BPF_SIZE(insn->code), BPF_READ, load_reg, true);
|
||||
BPF_SIZE(insn->code), BPF_READ, -1, true);
|
||||
if (!err && load_reg >= 0)
|
||||
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
||||
BPF_SIZE(insn->code), BPF_READ, load_reg,
|
||||
true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* check whether we can write into the same memory */
|
||||
/* Check whether we can write into the same memory. */
|
||||
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
||||
BPF_SIZE(insn->code), BPF_WRITE, -1, true);
|
||||
if (err)
|
||||
|
@ -8308,6 +8323,10 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
|||
insn->dst_reg);
|
||||
}
|
||||
zext_32_to_64(dst_reg);
|
||||
|
||||
__update_reg_bounds(dst_reg);
|
||||
__reg_deduce_bounds(dst_reg);
|
||||
__reg_bound_offset(dst_reg);
|
||||
}
|
||||
} else {
|
||||
/* case: R = imm
|
||||
|
|
|
@ -832,7 +832,7 @@ void skb_dump(const char *level, const struct sk_buff *skb, bool full_pkt)
|
|||
ntohs(skb->protocol), skb->pkt_type, skb->skb_iif);
|
||||
|
||||
if (dev)
|
||||
printk("%sdev name=%s feat=0x%pNF\n",
|
||||
printk("%sdev name=%s feat=%pNF\n",
|
||||
level, dev->name, &dev->features);
|
||||
if (sk)
|
||||
printk("%ssk family=%hu type=%u proto=%u\n",
|
||||
|
|
|
@ -261,6 +261,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
|
|||
r->idiag_state = sk->sk_state;
|
||||
r->idiag_timer = 0;
|
||||
r->idiag_retrans = 0;
|
||||
r->idiag_expires = 0;
|
||||
|
||||
if (inet_diag_msg_attrs_fill(sk, skb, r, ext,
|
||||
sk_user_ns(NETLINK_CB(cb->skb).sk),
|
||||
|
@ -314,9 +315,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
|
|||
r->idiag_retrans = icsk->icsk_probes_out;
|
||||
r->idiag_expires =
|
||||
jiffies_delta_to_msecs(sk->sk_timer.expires - jiffies);
|
||||
} else {
|
||||
r->idiag_timer = 0;
|
||||
r->idiag_expires = 0;
|
||||
}
|
||||
|
||||
if ((ext & (1 << (INET_DIAG_INFO - 1))) && handler->idiag_info_size) {
|
||||
|
|
|
@ -1933,7 +1933,6 @@ static int __net_init sit_init_net(struct net *net)
|
|||
return 0;
|
||||
|
||||
err_reg_dev:
|
||||
ipip6_dev_free(sitn->fb_tunnel_dev);
|
||||
free_netdev(sitn->fb_tunnel_dev);
|
||||
err_alloc_dev:
|
||||
return err;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007-2010, Intel Corporation
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2020 Intel Corporation
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -191,7 +191,8 @@ static void ieee80211_add_addbaext(struct ieee80211_sub_if_data *sdata,
|
|||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return;
|
||||
he_cap = ieee80211_get_he_iftype_cap(sband, sdata->vif.type);
|
||||
he_cap = ieee80211_get_he_iftype_cap(sband,
|
||||
ieee80211_vif_type_p2p(&sdata->vif));
|
||||
if (!he_cap)
|
||||
return;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007-2010, Intel Corporation
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 - 2020 Intel Corporation
|
||||
* Copyright (C) 2018 - 2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
|
@ -106,7 +106,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
|
|||
mgmt->u.action.u.addba_req.start_seq_num =
|
||||
cpu_to_le16(start_seq_num << 4);
|
||||
|
||||
ieee80211_tx_skb(sdata, skb);
|
||||
ieee80211_tx_skb_tid(sdata, skb, tid);
|
||||
}
|
||||
|
||||
void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
|
||||
|
@ -213,6 +213,8 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
|
|||
struct ieee80211_txq *txq = sta->sta.txq[tid];
|
||||
struct txq_info *txqi;
|
||||
|
||||
lockdep_assert_held(&sta->ampdu_mlme.mtx);
|
||||
|
||||
if (!txq)
|
||||
return;
|
||||
|
||||
|
@ -290,7 +292,6 @@ static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid)
|
|||
ieee80211_assign_tid_tx(sta, tid, NULL);
|
||||
|
||||
ieee80211_agg_splice_finish(sta->sdata, tid);
|
||||
ieee80211_agg_start_txq(sta, tid, false);
|
||||
|
||||
kfree_rcu(tid_tx, rcu_head);
|
||||
}
|
||||
|
@ -480,8 +481,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
|
|||
|
||||
/* send AddBA request */
|
||||
ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
|
||||
tid_tx->dialog_token,
|
||||
sta->tid_seq[tid] >> 4,
|
||||
tid_tx->dialog_token, tid_tx->ssn,
|
||||
buf_size, tid_tx->timeout);
|
||||
|
||||
WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state));
|
||||
|
@ -523,6 +523,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
|
|||
|
||||
params.ssn = sta->tid_seq[tid] >> 4;
|
||||
ret = drv_ampdu_action(local, sdata, ¶ms);
|
||||
tid_tx->ssn = params.ssn;
|
||||
if (ret == IEEE80211_AMPDU_TX_START_DELAY_ADDBA) {
|
||||
return;
|
||||
} else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
|
||||
|
@ -889,6 +890,7 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
|
|||
{
|
||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||
bool send_delba = false;
|
||||
bool start_txq = false;
|
||||
|
||||
ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
|
||||
sta->sta.addr, tid);
|
||||
|
@ -906,10 +908,14 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
|
|||
send_delba = true;
|
||||
|
||||
ieee80211_remove_tid_tx(sta, tid);
|
||||
start_txq = true;
|
||||
|
||||
unlock_sta:
|
||||
spin_unlock_bh(&sta->lock);
|
||||
|
||||
if (start_txq)
|
||||
ieee80211_agg_start_txq(sta, tid, false);
|
||||
|
||||
if (send_delba)
|
||||
ieee80211_send_delba(sdata, sta->sta.addr, tid,
|
||||
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
|
||||
|
|
|
@ -1219,8 +1219,11 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local,
|
|||
{
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
|
||||
|
||||
if (local->in_reconfig)
|
||||
/* In reconfig don't transmit now, but mark for waking later */
|
||||
if (local->in_reconfig) {
|
||||
set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txq->flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_sdata_in_driver(sdata))
|
||||
return;
|
||||
|
|
|
@ -2452,11 +2452,18 @@ static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
|
|||
u16 tx_time)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
u16 tid = ieee80211_get_tid(hdr);
|
||||
int ac = ieee80211_ac_from_tid(tid);
|
||||
struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
|
||||
u16 tid;
|
||||
int ac;
|
||||
struct ieee80211_sta_tx_tspec *tx_tspec;
|
||||
unsigned long now = jiffies;
|
||||
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
return;
|
||||
|
||||
tid = ieee80211_get_tid(hdr);
|
||||
ac = ieee80211_ac_from_tid(tid);
|
||||
tx_tspec = &ifmgd->tx_tspec[ac];
|
||||
|
||||
if (likely(!tx_tspec->admitted_time))
|
||||
return;
|
||||
|
||||
|
|
|
@ -2944,6 +2944,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
|||
if (!fwd_skb)
|
||||
goto out;
|
||||
|
||||
fwd_skb->dev = sdata->dev;
|
||||
fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
|
||||
fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
|
||||
info = IEEE80211_SKB_CB(fwd_skb);
|
||||
|
|
|
@ -644,13 +644,13 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
|
|||
/* check if STA exists already */
|
||||
if (sta_info_get_bss(sdata, sta->sta.addr)) {
|
||||
err = -EEXIST;
|
||||
goto out_err;
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
|
||||
if (!sinfo) {
|
||||
err = -ENOMEM;
|
||||
goto out_err;
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
local->num_sta++;
|
||||
|
@ -667,6 +667,15 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
|
|||
|
||||
list_add_tail_rcu(&sta->list, &local->sta_list);
|
||||
|
||||
/* update channel context before notifying the driver about state
|
||||
* change, this enables driver using the updated channel context right away.
|
||||
*/
|
||||
if (sta->sta_state >= IEEE80211_STA_ASSOC) {
|
||||
ieee80211_recalc_min_chandef(sta->sdata);
|
||||
if (!sta->sta.support_p2p_ps)
|
||||
ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
|
||||
}
|
||||
|
||||
/* notify driver */
|
||||
err = sta_info_insert_drv_state(local, sdata, sta);
|
||||
if (err)
|
||||
|
@ -674,12 +683,6 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
|
|||
|
||||
set_sta_flag(sta, WLAN_STA_INSERTED);
|
||||
|
||||
if (sta->sta_state >= IEEE80211_STA_ASSOC) {
|
||||
ieee80211_recalc_min_chandef(sta->sdata);
|
||||
if (!sta->sta.support_p2p_ps)
|
||||
ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
|
||||
}
|
||||
|
||||
/* accept BA sessions now */
|
||||
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
|
||||
|
@ -706,8 +709,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
|
|||
out_drop_sta:
|
||||
local->num_sta--;
|
||||
synchronize_net();
|
||||
out_cleanup:
|
||||
cleanup_single_sta(sta);
|
||||
out_err:
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
kfree(sinfo);
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -176,6 +176,7 @@ struct sta_info;
|
|||
* @failed_bar_ssn: ssn of the last failed BAR tx attempt
|
||||
* @bar_pending: BAR needs to be re-sent
|
||||
* @amsdu: support A-MSDU withing A-MDPU
|
||||
* @ssn: starting sequence number of the session
|
||||
*
|
||||
* This structure's lifetime is managed by RCU, assignments to
|
||||
* the array holding it must hold the aggregation mutex.
|
||||
|
@ -199,6 +200,7 @@ struct tid_ampdu_tx {
|
|||
u8 stop_initiator;
|
||||
bool tx_stop;
|
||||
u16 buf_size;
|
||||
u16 ssn;
|
||||
|
||||
u16 failed_bar_ssn;
|
||||
bool bar_pending;
|
||||
|
|
|
@ -1822,15 +1822,15 @@ static int invoke_tx_handlers_late(struct ieee80211_tx_data *tx)
|
|||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
||||
ieee80211_tx_result res = TX_CONTINUE;
|
||||
|
||||
if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
|
||||
if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
|
||||
__skb_queue_tail(&tx->skbs, tx->skb);
|
||||
tx->skb = NULL;
|
||||
goto txh_done;
|
||||
}
|
||||
|
||||
if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
|
||||
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
||||
CALL_TXH(ieee80211_tx_h_sequence);
|
||||
CALL_TXH(ieee80211_tx_h_fragment);
|
||||
|
@ -4191,11 +4191,11 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
|||
|
||||
ieee80211_aggr_check(sdata, sta, skb);
|
||||
|
||||
sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
|
||||
|
||||
if (sta) {
|
||||
struct ieee80211_fast_tx *fast_tx;
|
||||
|
||||
sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
|
||||
|
||||
fast_tx = rcu_dereference(sta->fast_tx);
|
||||
|
||||
if (fast_tx &&
|
||||
|
|
|
@ -943,7 +943,12 @@ static void ieee80211_parse_extension_element(u32 *crc,
|
|||
struct ieee802_11_elems *elems)
|
||||
{
|
||||
const void *data = elem->data + 1;
|
||||
u8 len = elem->datalen - 1;
|
||||
u8 len;
|
||||
|
||||
if (!elem->datalen)
|
||||
return;
|
||||
|
||||
len = elem->datalen - 1;
|
||||
|
||||
switch (elem->data[0]) {
|
||||
case WLAN_EID_EXT_HE_MU_EDCA:
|
||||
|
@ -2063,7 +2068,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
|
|||
chandef.chan = chan;
|
||||
|
||||
skb = ieee80211_probereq_get(&local->hw, src, ssid, ssid_len,
|
||||
100 + ie_len);
|
||||
local->scan_ies_len + ie_len);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
|
@ -2646,6 +2651,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||
mutex_unlock(&local->sta_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is for hw restart things are still running.
|
||||
* We may want to change that later, however.
|
||||
*/
|
||||
if (local->open_count && (!suspended || reconfig_due_to_wowlan))
|
||||
drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
|
||||
|
||||
if (local->in_reconfig) {
|
||||
local->in_reconfig = false;
|
||||
barrier();
|
||||
|
@ -2664,13 +2676,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
|
||||
false);
|
||||
|
||||
/*
|
||||
* If this is for hw restart things are still running.
|
||||
* We may want to change that later, however.
|
||||
*/
|
||||
if (local->open_count && (!suspended || reconfig_due_to_wowlan))
|
||||
drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
|
||||
|
||||
if (!suspended)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -700,6 +700,9 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
|
|||
|
||||
msk_owned_by_me(msk);
|
||||
|
||||
if (sk->sk_state == TCP_LISTEN)
|
||||
return;
|
||||
|
||||
if (!rm_list->nr)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1524,7 +1524,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
|
|||
int ret = 0;
|
||||
|
||||
prev_ssk = ssk;
|
||||
mptcp_flush_join_list(msk);
|
||||
__mptcp_flush_join_list(msk);
|
||||
ssk = mptcp_subflow_get_send(msk);
|
||||
|
||||
/* First check. If the ssk has changed since
|
||||
|
@ -2879,7 +2879,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
|
|||
*/
|
||||
if (WARN_ON_ONCE(!new_mptcp_sock)) {
|
||||
tcp_sk(newsk)->is_mptcp = 0;
|
||||
return newsk;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* acquire the 2nd reference for the owning socket */
|
||||
|
@ -2891,6 +2891,8 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
|
|||
MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK);
|
||||
}
|
||||
|
||||
out:
|
||||
newsk->sk_kern_sock = kern;
|
||||
return newsk;
|
||||
}
|
||||
|
||||
|
|
|
@ -525,7 +525,6 @@ static bool mptcp_supported_sockopt(int level, int optname)
|
|||
case TCP_NODELAY:
|
||||
case TCP_THIN_LINEAR_TIMEOUTS:
|
||||
case TCP_CONGESTION:
|
||||
case TCP_ULP:
|
||||
case TCP_CORK:
|
||||
case TCP_KEEPIDLE:
|
||||
case TCP_KEEPINTVL:
|
||||
|
|
|
@ -4492,9 +4492,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
|
|||
}
|
||||
|
||||
out_free_pg_vec:
|
||||
bitmap_free(rx_owner_map);
|
||||
if (pg_vec)
|
||||
if (pg_vec) {
|
||||
bitmap_free(rx_owner_map);
|
||||
free_pg_vec(pg_vec, order, req->tp_block_nr);
|
||||
}
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -868,6 +868,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp,
|
|||
|
||||
err = pep_accept_conn(newsk, skb);
|
||||
if (err) {
|
||||
__sock_put(sk);
|
||||
sock_put(newsk);
|
||||
newsk = NULL;
|
||||
goto drop;
|
||||
|
|
|
@ -253,6 +253,7 @@ static struct rds_connection *__rds_conn_create(struct net *net,
|
|||
* should end up here, but if it
|
||||
* does, reset/destroy the connection.
|
||||
*/
|
||||
kfree(conn->c_path);
|
||||
kmem_cache_free(rds_conn_slab, conn);
|
||||
conn = ERR_PTR(-EOPNOTSUPP);
|
||||
goto out;
|
||||
|
|
|
@ -3687,6 +3687,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
|
|||
entry->mpls_mangle.ttl = tcf_mpls_ttl(act);
|
||||
break;
|
||||
default:
|
||||
err = -EOPNOTSUPP;
|
||||
goto err_out_locked;
|
||||
}
|
||||
} else if (is_tcf_skbedit_ptype(act)) {
|
||||
|
|
|
@ -2736,7 +2736,7 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
q->tins = kvcalloc(CAKE_MAX_TINS, sizeof(struct cake_tin_data),
|
||||
GFP_KERNEL);
|
||||
if (!q->tins)
|
||||
goto nomem;
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < CAKE_MAX_TINS; i++) {
|
||||
struct cake_tin_data *b = q->tins + i;
|
||||
|
@ -2766,10 +2766,6 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
q->min_netlen = ~0;
|
||||
q->min_adjlen = ~0;
|
||||
return 0;
|
||||
|
||||
nomem:
|
||||
cake_destroy(sch);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int cake_dump(struct Qdisc *sch, struct sk_buff *skb)
|
||||
|
|
|
@ -666,9 +666,9 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
}
|
||||
}
|
||||
for (i = q->nbands; i < oldbands; i++) {
|
||||
qdisc_tree_flush_backlog(q->classes[i].qdisc);
|
||||
if (i >= q->nstrict)
|
||||
if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
|
||||
list_del(&q->classes[i].alist);
|
||||
qdisc_tree_flush_backlog(q->classes[i].qdisc);
|
||||
}
|
||||
q->nstrict = nstrict;
|
||||
memcpy(q->prio2band, priomap, sizeof(priomap));
|
||||
|
|
|
@ -194,7 +194,9 @@ static int smc_release(struct socket *sock)
|
|||
/* cleanup for a dangling non-blocking connect */
|
||||
if (smc->connect_nonblock && sk->sk_state == SMC_INIT)
|
||||
tcp_abort(smc->clcsock->sk, ECONNABORTED);
|
||||
flush_work(&smc->connect_work);
|
||||
|
||||
if (cancel_work_sync(&smc->connect_work))
|
||||
sock_put(&smc->sk); /* sock_hold in smc_connect for passive closing */
|
||||
|
||||
if (sk->sk_state == SMC_LISTEN)
|
||||
/* smc_close_non_accepted() is called and acquires
|
||||
|
|
|
@ -133,6 +133,7 @@ static u32 reg_is_indoor_portid;
|
|||
|
||||
static void restore_regulatory_settings(bool reset_user, bool cached);
|
||||
static void print_regdomain(const struct ieee80211_regdomain *rd);
|
||||
static void reg_process_hint(struct regulatory_request *reg_request);
|
||||
|
||||
static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
|
||||
{
|
||||
|
@ -1098,6 +1099,8 @@ int reg_reload_regdb(void)
|
|||
const struct firmware *fw;
|
||||
void *db;
|
||||
int err;
|
||||
const struct ieee80211_regdomain *current_regdomain;
|
||||
struct regulatory_request *request;
|
||||
|
||||
err = request_firmware(&fw, "regulatory.db", ®_pdev->dev);
|
||||
if (err)
|
||||
|
@ -1118,8 +1121,26 @@ int reg_reload_regdb(void)
|
|||
if (!IS_ERR_OR_NULL(regdb))
|
||||
kfree(regdb);
|
||||
regdb = db;
|
||||
rtnl_unlock();
|
||||
|
||||
/* reset regulatory domain */
|
||||
current_regdomain = get_cfg80211_regdom();
|
||||
|
||||
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||
if (!request) {
|
||||
err = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
request->wiphy_idx = WIPHY_IDX_INVALID;
|
||||
request->alpha2[0] = current_regdomain->alpha2[0];
|
||||
request->alpha2[1] = current_regdomain->alpha2[1];
|
||||
request->initiator = NL80211_REGDOM_SET_BY_CORE;
|
||||
request->user_reg_hint_type = NL80211_USER_REG_HINT_USER;
|
||||
|
||||
reg_process_hint(request);
|
||||
|
||||
out_unlock:
|
||||
rtnl_unlock();
|
||||
out:
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
|
@ -2338,6 +2359,7 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
|
|||
struct cfg80211_chan_def chandef = {};
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
enum nl80211_iftype iftype;
|
||||
bool ret;
|
||||
|
||||
wdev_lock(wdev);
|
||||
iftype = wdev->iftype;
|
||||
|
@ -2387,7 +2409,11 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
|
|||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
return cfg80211_reg_can_beacon_relax(wiphy, &chandef, iftype);
|
||||
wiphy_lock(wiphy);
|
||||
ret = cfg80211_reg_can_beacon_relax(wiphy, &chandef, iftype);
|
||||
wiphy_unlock(wiphy);
|
||||
|
||||
return ret;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
return cfg80211_chandef_usable(wiphy, &chandef,
|
||||
|
|
|
@ -677,8 +677,6 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock,
|
|||
struct xdp_sock *xs = xdp_sk(sk);
|
||||
struct xsk_buff_pool *pool;
|
||||
|
||||
sock_poll_wait(file, sock, wait);
|
||||
|
||||
if (unlikely(!xsk_is_bound(xs)))
|
||||
return mask;
|
||||
|
||||
|
@ -690,6 +688,8 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock,
|
|||
else
|
||||
/* Poll needs to drive Tx also in copy mode */
|
||||
__xsk_sendmsg(sk);
|
||||
} else {
|
||||
sock_poll_wait(file, sock, wait);
|
||||
}
|
||||
|
||||
if (xs->rx && !xskq_prod_is_empty(xs->rx))
|
||||
|
|
|
@ -33,6 +33,22 @@ noinline int bpf_testmod_loop_test(int n)
|
|||
return sum;
|
||||
}
|
||||
|
||||
__weak noinline struct file *bpf_testmod_return_ptr(int arg)
|
||||
{
|
||||
static struct file f = {};
|
||||
|
||||
switch (arg) {
|
||||
case 1: return (void *)EINVAL; /* user addr */
|
||||
case 2: return (void *)0xcafe4a11; /* user addr */
|
||||
case 3: return (void *)-EINVAL; /* canonical, but invalid */
|
||||
case 4: return (void *)(1ull << 60); /* non-canonical and invalid */
|
||||
case 5: return (void *)~(1ull << 30); /* trigger extable */
|
||||
case 6: return &f; /* valid addr */
|
||||
case 7: return (void *)((long)&f | 1); /* kernel tricks */
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
noinline ssize_t
|
||||
bpf_testmod_test_read(struct file *file, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
|
@ -43,6 +59,10 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
|
|||
.off = off,
|
||||
.len = len,
|
||||
};
|
||||
int i = 1;
|
||||
|
||||
while (bpf_testmod_return_ptr(i))
|
||||
i++;
|
||||
|
||||
/* This is always true. Use the check to make sure the compiler
|
||||
* doesn't remove bpf_testmod_loop_test.
|
||||
|
|
|
@ -90,7 +90,7 @@ static void print_err_line(void)
|
|||
|
||||
static void test_conn(void)
|
||||
{
|
||||
int listen_fd = -1, cli_fd = -1, err;
|
||||
int listen_fd = -1, cli_fd = -1, srv_fd = -1, err;
|
||||
socklen_t addrlen = sizeof(srv_sa6);
|
||||
int srv_port;
|
||||
|
||||
|
@ -112,6 +112,10 @@ static void test_conn(void)
|
|||
if (CHECK_FAIL(cli_fd == -1))
|
||||
goto done;
|
||||
|
||||
srv_fd = accept(listen_fd, NULL, NULL);
|
||||
if (CHECK_FAIL(srv_fd == -1))
|
||||
goto done;
|
||||
|
||||
if (CHECK(skel->bss->listen_tp_sport != srv_port ||
|
||||
skel->bss->req_sk_sport != srv_port,
|
||||
"Unexpected sk src port",
|
||||
|
@ -134,11 +138,13 @@ done:
|
|||
close(listen_fd);
|
||||
if (cli_fd != -1)
|
||||
close(cli_fd);
|
||||
if (srv_fd != -1)
|
||||
close(srv_fd);
|
||||
}
|
||||
|
||||
static void test_syncookie(void)
|
||||
{
|
||||
int listen_fd = -1, cli_fd = -1, err;
|
||||
int listen_fd = -1, cli_fd = -1, srv_fd = -1, err;
|
||||
socklen_t addrlen = sizeof(srv_sa6);
|
||||
int srv_port;
|
||||
|
||||
|
@ -161,6 +167,10 @@ static void test_syncookie(void)
|
|||
if (CHECK_FAIL(cli_fd == -1))
|
||||
goto done;
|
||||
|
||||
srv_fd = accept(listen_fd, NULL, NULL);
|
||||
if (CHECK_FAIL(srv_fd == -1))
|
||||
goto done;
|
||||
|
||||
if (CHECK(skel->bss->listen_tp_sport != srv_port,
|
||||
"Unexpected tp src port",
|
||||
"listen_tp_sport:%u expected:%u\n",
|
||||
|
@ -188,6 +198,8 @@ done:
|
|||
close(listen_fd);
|
||||
if (cli_fd != -1)
|
||||
close(cli_fd);
|
||||
if (srv_fd != -1)
|
||||
close(srv_fd);
|
||||
}
|
||||
|
||||
struct test {
|
||||
|
|
|
@ -87,6 +87,18 @@ int BPF_PROG(handle_fexit,
|
|||
return 0;
|
||||
}
|
||||
|
||||
SEC("fexit/bpf_testmod_return_ptr")
|
||||
int BPF_PROG(handle_fexit_ret, int arg, struct file *ret)
|
||||
{
|
||||
long buf = 0;
|
||||
|
||||
bpf_probe_read_kernel(&buf, 8, ret);
|
||||
bpf_probe_read_kernel(&buf, 8, (char *)ret + 256);
|
||||
*(volatile long long *)ret;
|
||||
*(volatile int *)&ret->f_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u32 fmod_ret_read_sz = 0;
|
||||
|
||||
SEC("fmod_ret/bpf_testmod_test_read")
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#define MAX_INSNS BPF_MAXINSNS
|
||||
#define MAX_TEST_INSNS 1000000
|
||||
#define MAX_FIXUPS 8
|
||||
#define MAX_NR_MAPS 21
|
||||
#define MAX_NR_MAPS 22
|
||||
#define MAX_TEST_RUNS 8
|
||||
#define POINTER_VALUE 0xcafe4all
|
||||
#define TEST_DATA_LEN 64
|
||||
|
|
|
@ -138,6 +138,8 @@
|
|||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.result_unpriv = REJECT,
|
||||
.errstr_unpriv = "R0 leaks addr into mem",
|
||||
},
|
||||
{
|
||||
"Dest pointer in r0 - succeed",
|
||||
|
@ -156,4 +158,88 @@
|
|||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.result_unpriv = REJECT,
|
||||
.errstr_unpriv = "R0 leaks addr into mem",
|
||||
},
|
||||
{
|
||||
"Dest pointer in r0 - succeed, check 2",
|
||||
.insns = {
|
||||
/* r0 = &val */
|
||||
BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
|
||||
/* val = r0; */
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
|
||||
/* r5 = &val */
|
||||
BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
|
||||
/* r0 = atomic_cmpxchg(&val, r0, r5); */
|
||||
BPF_ATOMIC_OP(BPF_DW, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
|
||||
/* r1 = *r0 */
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
|
||||
/* exit(0); */
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.result_unpriv = REJECT,
|
||||
.errstr_unpriv = "R0 leaks addr into mem",
|
||||
},
|
||||
{
|
||||
"Dest pointer in r0 - succeed, check 3",
|
||||
.insns = {
|
||||
/* r0 = &val */
|
||||
BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
|
||||
/* val = r0; */
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
|
||||
/* r5 = &val */
|
||||
BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
|
||||
/* r0 = atomic_cmpxchg(&val, r0, r5); */
|
||||
BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
|
||||
/* exit(0); */
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = REJECT,
|
||||
.errstr = "invalid size of register fill",
|
||||
.errstr_unpriv = "R0 leaks addr into mem",
|
||||
},
|
||||
{
|
||||
"Dest pointer in r0 - succeed, check 4",
|
||||
.insns = {
|
||||
/* r0 = &val */
|
||||
BPF_MOV32_REG(BPF_REG_0, BPF_REG_10),
|
||||
/* val = r0; */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
|
||||
/* r5 = &val */
|
||||
BPF_MOV32_REG(BPF_REG_5, BPF_REG_10),
|
||||
/* r0 = atomic_cmpxchg(&val, r0, r5); */
|
||||
BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
|
||||
/* r1 = *r10 */
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, -8),
|
||||
/* exit(0); */
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.result_unpriv = REJECT,
|
||||
.errstr_unpriv = "R10 partial copy of pointer",
|
||||
},
|
||||
{
|
||||
"Dest pointer in r0 - succeed, check 5",
|
||||
.insns = {
|
||||
/* r0 = &val */
|
||||
BPF_MOV32_REG(BPF_REG_0, BPF_REG_10),
|
||||
/* val = r0; */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -8),
|
||||
/* r5 = &val */
|
||||
BPF_MOV32_REG(BPF_REG_5, BPF_REG_10),
|
||||
/* r0 = atomic_cmpxchg(&val, r0, r5); */
|
||||
BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_10, BPF_REG_5, -8),
|
||||
/* r1 = *r0 */
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -8),
|
||||
/* exit(0); */
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = REJECT,
|
||||
.errstr = "R0 invalid mem access",
|
||||
.errstr_unpriv = "R10 partial copy of pointer",
|
||||
},
|
||||
|
|
|
@ -1,3 +1,97 @@
|
|||
{
|
||||
"atomic dw/fetch and address leakage of (map ptr & -1) via stack slot",
|
||||
.insns = {
|
||||
BPF_LD_IMM64(BPF_REG_1, -1),
|
||||
BPF_LD_MAP_FD(BPF_REG_8, 0),
|
||||
BPF_LD_MAP_FD(BPF_REG_9, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
|
||||
BPF_ATOMIC_OP(BPF_DW, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_2, 0),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
|
||||
BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_array_48b = { 2, 4 },
|
||||
.result = ACCEPT,
|
||||
.result_unpriv = REJECT,
|
||||
.errstr_unpriv = "leaking pointer from stack off -8",
|
||||
},
|
||||
{
|
||||
"atomic dw/fetch and address leakage of (map ptr & -1) via returned value",
|
||||
.insns = {
|
||||
BPF_LD_IMM64(BPF_REG_1, -1),
|
||||
BPF_LD_MAP_FD(BPF_REG_8, 0),
|
||||
BPF_LD_MAP_FD(BPF_REG_9, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
|
||||
BPF_ATOMIC_OP(BPF_DW, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
|
||||
BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
|
||||
BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_array_48b = { 2, 4 },
|
||||
.result = ACCEPT,
|
||||
.result_unpriv = REJECT,
|
||||
.errstr_unpriv = "leaking pointer from stack off -8",
|
||||
},
|
||||
{
|
||||
"atomic w/fetch and address leakage of (map ptr & -1) via stack slot",
|
||||
.insns = {
|
||||
BPF_LD_IMM64(BPF_REG_1, -1),
|
||||
BPF_LD_MAP_FD(BPF_REG_8, 0),
|
||||
BPF_LD_MAP_FD(BPF_REG_9, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
|
||||
BPF_ATOMIC_OP(BPF_W, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_2, 0),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
|
||||
BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_array_48b = { 2, 4 },
|
||||
.result = REJECT,
|
||||
.errstr = "invalid size of register fill",
|
||||
},
|
||||
{
|
||||
"atomic w/fetch and address leakage of (map ptr & -1) via returned value",
|
||||
.insns = {
|
||||
BPF_LD_IMM64(BPF_REG_1, -1),
|
||||
BPF_LD_MAP_FD(BPF_REG_8, 0),
|
||||
BPF_LD_MAP_FD(BPF_REG_9, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_9, 0),
|
||||
BPF_ATOMIC_OP(BPF_W, BPF_AND | BPF_FETCH, BPF_REG_2, BPF_REG_1, 0),
|
||||
BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
|
||||
BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_array_48b = { 2, 4 },
|
||||
.result = REJECT,
|
||||
.errstr = "invalid size of register fill",
|
||||
},
|
||||
#define __ATOMIC_FETCH_OP_TEST(src_reg, dst_reg, operand1, op, operand2, expect) \
|
||||
{ \
|
||||
"atomic fetch " #op ", src=" #dst_reg " dst=" #dst_reg, \
|
||||
|
|
|
@ -132,6 +132,77 @@
|
|||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
|
||||
},
|
||||
{
|
||||
"precision tracking for u32 spill/fill",
|
||||
.insns = {
|
||||
BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
|
||||
BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
|
||||
BPF_MOV32_IMM(BPF_REG_6, 32),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_MOV32_IMM(BPF_REG_6, 4),
|
||||
/* Additional insns to introduce a pruning point. */
|
||||
BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 0),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 0),
|
||||
/* u32 spill/fill */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -8),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_10, -8),
|
||||
/* out-of-bound map value access for r6=32 */
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
|
||||
BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_hash_8b = { 15 },
|
||||
.result = REJECT,
|
||||
.errstr = "R0 min value is outside of the allowed memory range",
|
||||
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
|
||||
},
|
||||
{
|
||||
"precision tracking for u32 spills, u64 fill",
|
||||
.insns = {
|
||||
BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
|
||||
BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
|
||||
BPF_MOV32_IMM(BPF_REG_7, 0xffffffff),
|
||||
/* Additional insns to introduce a pruning point. */
|
||||
BPF_MOV64_IMM(BPF_REG_3, 1),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 1),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 1),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 1),
|
||||
BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 1),
|
||||
BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
|
||||
/* u32 spills, u64 fill */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, -8),
|
||||
/* if r8 != X goto pc+1 r8 known in fallthrough branch */
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_8, 0xffffffff, 1),
|
||||
BPF_MOV64_IMM(BPF_REG_3, 1),
|
||||
/* if r8 == X goto pc+1 condition always true on first
|
||||
* traversal, so starts backtracking to mark r8 as requiring
|
||||
* precision. r7 marked as needing precision. r6 not marked
|
||||
* since it's not tracked.
|
||||
*/
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 0xffffffff, 1),
|
||||
/* fails if r8 correctly marked unknown after fill. */
|
||||
BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = REJECT,
|
||||
.errstr = "div by zero",
|
||||
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
|
||||
},
|
||||
{
|
||||
"allocated_stack",
|
||||
.insns = {
|
||||
|
|
|
@ -175,6 +175,38 @@
|
|||
.errstr = "invalid access to packet",
|
||||
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
||||
},
|
||||
{
|
||||
"Spill u32 const scalars. Refill as u64. Offset to skb->data",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct __sk_buff, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct __sk_buff, data_end)),
|
||||
/* r6 = 0 */
|
||||
BPF_MOV32_IMM(BPF_REG_6, 0),
|
||||
/* r7 = 20 */
|
||||
BPF_MOV32_IMM(BPF_REG_7, 20),
|
||||
/* *(u32 *)(r10 -4) = r6 */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
|
||||
/* *(u32 *)(r10 -8) = r7 */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
|
||||
/* r4 = *(u64 *)(r10 -8) */
|
||||
BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -8),
|
||||
/* r0 = r2 */
|
||||
BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
|
||||
/* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv,umax=65535 */
|
||||
BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
|
||||
/* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv,umax=65535 */
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
|
||||
/* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv20 */
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = REJECT,
|
||||
.errstr = "invalid access to packet",
|
||||
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
||||
},
|
||||
{
|
||||
"Spill a u32 const scalar. Refill as u16 from fp-6. Offset to skb->data",
|
||||
.insns = {
|
||||
|
|
|
@ -1077,6 +1077,29 @@
|
|||
.errstr = "R0 invalid mem access 'inv'",
|
||||
.errstr_unpriv = "R0 pointer -= pointer prohibited",
|
||||
},
|
||||
{
|
||||
"map access: trying to leak tained dst reg",
|
||||
.insns = {
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
|
||||
BPF_MOV32_IMM(BPF_REG_1, 0xFFFFFFFF),
|
||||
BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
|
||||
BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_1),
|
||||
BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_array_48b = { 4 },
|
||||
.result = REJECT,
|
||||
.errstr = "math between map_value pointer and 4294967295 is not allowed",
|
||||
},
|
||||
{
|
||||
"32bit pkt_ptr -= scalar",
|
||||
.insns = {
|
||||
|
|
|
@ -72,6 +72,35 @@ rif_mac_profile_replacement_test()
|
|||
ip link set $h1.10 address $h1_10_mac
|
||||
}
|
||||
|
||||
rif_mac_profile_consolidation_test()
|
||||
{
|
||||
local count=$1; shift
|
||||
local h1_20_mac
|
||||
|
||||
RET=0
|
||||
|
||||
if [[ $count -eq 1 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
h1_20_mac=$(mac_get $h1.20)
|
||||
|
||||
# Set the MAC of $h1.20 to that of $h1.10 and confirm that they are
|
||||
# using the same MAC profile.
|
||||
ip link set $h1.20 address 00:11:11:11:11:11
|
||||
check_err $?
|
||||
|
||||
occ=$(devlink -j resource show $DEVLINK_DEV \
|
||||
| jq '.[][][] | select(.name=="rif_mac_profiles") |.["occ"]')
|
||||
|
||||
[[ $occ -eq $((count - 1)) ]]
|
||||
check_err $? "MAC profile occupancy did not decrease"
|
||||
|
||||
log_test "RIF MAC profile consolidation"
|
||||
|
||||
ip link set $h1.20 address $h1_20_mac
|
||||
}
|
||||
|
||||
rif_mac_profile_shared_replacement_test()
|
||||
{
|
||||
local count=$1; shift
|
||||
|
@ -104,6 +133,7 @@ rif_mac_profile_edit_test()
|
|||
create_max_rif_mac_profiles $count
|
||||
|
||||
rif_mac_profile_replacement_test
|
||||
rif_mac_profile_consolidation_test $count
|
||||
rif_mac_profile_shared_replacement_test $count
|
||||
}
|
||||
|
||||
|
|
|
@ -455,6 +455,22 @@ cleanup()
|
|||
ip netns del ${NSC} >/dev/null 2>&1
|
||||
}
|
||||
|
||||
cleanup_vrf_dup()
|
||||
{
|
||||
ip link del ${NSA_DEV2} >/dev/null 2>&1
|
||||
ip netns pids ${NSC} | xargs kill 2>/dev/null
|
||||
ip netns del ${NSC} >/dev/null 2>&1
|
||||
}
|
||||
|
||||
setup_vrf_dup()
|
||||
{
|
||||
# some VRF tests use ns-C which has the same config as
|
||||
# ns-B but for a device NOT in the VRF
|
||||
create_ns ${NSC} "-" "-"
|
||||
connect_ns ${NSA} ${NSA_DEV2} ${NSA_IP}/24 ${NSA_IP6}/64 \
|
||||
${NSC} ${NSC_DEV} ${NSB_IP}/24 ${NSB_IP6}/64
|
||||
}
|
||||
|
||||
setup()
|
||||
{
|
||||
local with_vrf=${1}
|
||||
|
@ -484,12 +500,6 @@ setup()
|
|||
|
||||
ip -netns ${NSB} ro add ${VRF_IP}/32 via ${NSA_IP} dev ${NSB_DEV}
|
||||
ip -netns ${NSB} -6 ro add ${VRF_IP6}/128 via ${NSA_IP6} dev ${NSB_DEV}
|
||||
|
||||
# some VRF tests use ns-C which has the same config as
|
||||
# ns-B but for a device NOT in the VRF
|
||||
create_ns ${NSC} "-" "-"
|
||||
connect_ns ${NSA} ${NSA_DEV2} ${NSA_IP}/24 ${NSA_IP6}/64 \
|
||||
${NSC} ${NSC_DEV} ${NSB_IP}/24 ${NSB_IP6}/64
|
||||
else
|
||||
ip -netns ${NSA} ro add ${NSB_LO_IP}/32 via ${NSB_IP} dev ${NSA_DEV}
|
||||
ip -netns ${NSA} ro add ${NSB_LO_IP6}/128 via ${NSB_IP6} dev ${NSA_DEV}
|
||||
|
@ -1240,7 +1250,9 @@ ipv4_tcp_vrf()
|
|||
log_test_addr ${a} $? 1 "Global server, local connection"
|
||||
|
||||
# run MD5 tests
|
||||
setup_vrf_dup
|
||||
ipv4_tcp_md5
|
||||
cleanup_vrf_dup
|
||||
|
||||
#
|
||||
# enable VRF global server
|
||||
|
@ -1798,8 +1810,9 @@ ipv4_addr_bind_vrf()
|
|||
for a in ${NSA_IP} ${VRF_IP}
|
||||
do
|
||||
log_start
|
||||
show_hint "Socket not bound to VRF, but address is in VRF"
|
||||
run_cmd nettest -s -R -P icmp -l ${a} -b
|
||||
log_test_addr ${a} $? 0 "Raw socket bind to local address"
|
||||
log_test_addr ${a} $? 1 "Raw socket bind to local address"
|
||||
|
||||
log_start
|
||||
run_cmd nettest -s -R -P icmp -l ${a} -I ${NSA_DEV} -b
|
||||
|
@ -2191,7 +2204,7 @@ ipv6_ping_vrf()
|
|||
log_start
|
||||
show_hint "Fails since VRF device does not support linklocal or multicast"
|
||||
run_cmd ${ping6} -c1 -w1 ${a}
|
||||
log_test_addr ${a} $? 2 "ping out, VRF bind"
|
||||
log_test_addr ${a} $? 1 "ping out, VRF bind"
|
||||
done
|
||||
|
||||
for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
|
||||
|
@ -2719,7 +2732,9 @@ ipv6_tcp_vrf()
|
|||
log_test_addr ${a} $? 1 "Global server, local connection"
|
||||
|
||||
# run MD5 tests
|
||||
setup_vrf_dup
|
||||
ipv6_tcp_md5
|
||||
cleanup_vrf_dup
|
||||
|
||||
#
|
||||
# enable VRF global server
|
||||
|
@ -3414,11 +3429,14 @@ ipv6_addr_bind_novrf()
|
|||
run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
|
||||
log_test_addr ${a} $? 0 "TCP socket bind to local address after device bind"
|
||||
|
||||
# Sadly, the kernel allows binding a socket to a device and then
|
||||
# binding to an address not on the device. So this test passes
|
||||
# when it really should not
|
||||
a=${NSA_LO_IP6}
|
||||
log_start
|
||||
show_hint "Should fail with 'Cannot assign requested address'"
|
||||
show_hint "Tecnically should fail since address is not on device but kernel allows"
|
||||
run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
|
||||
log_test_addr ${a} $? 1 "TCP socket bind to out of scope local address"
|
||||
log_test_addr ${a} $? 0 "TCP socket bind to out of scope local address"
|
||||
}
|
||||
|
||||
ipv6_addr_bind_vrf()
|
||||
|
@ -3459,10 +3477,15 @@ ipv6_addr_bind_vrf()
|
|||
run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
|
||||
log_test_addr ${a} $? 0 "TCP socket bind to local address with device bind"
|
||||
|
||||
# Sadly, the kernel allows binding a socket to a device and then
|
||||
# binding to an address not on the device. The only restriction
|
||||
# is that the address is valid in the L3 domain. So this test
|
||||
# passes when it really should not
|
||||
a=${VRF_IP6}
|
||||
log_start
|
||||
show_hint "Tecnically should fail since address is not on device but kernel allows"
|
||||
run_cmd nettest -6 -s -l ${a} -I ${NSA_DEV} -t1 -b
|
||||
log_test_addr ${a} $? 1 "TCP socket bind to VRF address with device bind"
|
||||
log_test_addr ${a} $? 0 "TCP socket bind to VRF address with device bind"
|
||||
|
||||
a=${NSA_LO_IP6}
|
||||
log_start
|
||||
|
|
|
@ -13,6 +13,8 @@ NETIFS[p5]=veth4
|
|||
NETIFS[p6]=veth5
|
||||
NETIFS[p7]=veth6
|
||||
NETIFS[p8]=veth7
|
||||
NETIFS[p9]=veth8
|
||||
NETIFS[p10]=veth9
|
||||
|
||||
# Port that does not have a cable connected.
|
||||
NETIF_NO_CABLE=eth8
|
||||
|
|
|
@ -311,7 +311,7 @@ check_exception()
|
|||
ip -netns h1 ro get ${H1_VRF_ARG} ${H2_N2_IP} | \
|
||||
grep -E -v 'mtu|redirected' | grep -q "cache"
|
||||
fi
|
||||
log_test $? 0 "IPv4: ${desc}"
|
||||
log_test $? 0 "IPv4: ${desc}" 0
|
||||
|
||||
# No PMTU info for test "redirect" and "mtu exception plus redirect"
|
||||
if [ "$with_redirect" = "yes" ] && [ "$desc" != "redirect exception plus mtu" ]; then
|
||||
|
|
|
@ -498,7 +498,7 @@ static void parse_opts(int argc, char **argv)
|
|||
bool have_toeplitz = false;
|
||||
int index, c;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "46C:d:i:k:r:stT:u:v", long_options, &index)) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "46C:d:i:k:r:stT:uv", long_options, &index)) != -1) {
|
||||
switch (c) {
|
||||
case '4':
|
||||
cfg_family = AF_INET;
|
||||
|
|
Loading…
Reference in New Issue