1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-11 09:00:12 +00:00

Including fixes from Bluetooth and WiFi. Notably this includes the fix

for the iwlwifi issue you reported.
 
 Current release - regressions:
 
   - core: avoid prefetching NULL pointers
 
   - wifi:
     - iwlwifi: implement settime64 as stub for MVM/MLD PTP
     - mac80211: fix list iteration in ieee80211_add_virtual_monitor()
 
   - handshake: fix null-ptr-deref in handshake_complete()
 
   - eth: mana: fix use-after-free in reset service rescan path
 
 Previous releases - regressions:
 
   - openvswitch: avoid needlessly taking the RTNL on vport destroy
 
   - dsa: properly keep track of conduit reference
 
   - ipv4:
     - fix reference count leak when using error routes with nexthop objects
     - fib: restore ECMP balance from loopback
 
   - mptcp: ensure context reset on disconnect()
 
   - bluetooth: fix potential UaF in btusb
 
   - nfc: fix deadlock between nfc_unregister_device and rfkill_fop_write
 
   - eth: gve: defer interrupt enabling until NAPI registration
 
   - eth: i40e: fix scheduling in set_rx_mode
 
   - eth: macb: relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()
 
   - eth: rtl8150: fix memory leak on usb_submit_urb() failure
 
   - wifi: 8192cu: fix tid out of range in rtl92cu_tx_fill_desc()
 
 Previous releases - always broken:
 
   - ip6_gre: make ip6gre_header() robust
 
   - ipv6: fix a BUG in rt6_get_pcpu_route() under PREEMPT_RT
 
   - af_unix: don't post cmsg for SO_INQ unless explicitly asked for
 
   - phy: mediatek: fix nvmem cell reference leak in mt798x_phy_calibration
 
   - wifi: mac80211: discard beacon frames to non-broadcast address
 
   - eth: iavf: fix off-by-one issues in iavf_config_rss_reg()
 
   - eth: stmmac: fix the crash issue for zero copy XDP_TX action
 
   - eth: team: fix check for port enabled in team_queue_override_port_prio_changed()
 
 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCgAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmlT43wSHHBhYmVuaUBy
 ZWRoYXQuY29tAAoJECkkeY3MjxOkHhMP/jF3B8c3djMgpYpEwPRgqJlzdpBGQvcO
 UsN/8fYI/XowIcU6T/yC/KM5cABCWyfnj6yZe743wPrlj8DnWK7+Fezrfwx7l8e0
 0LH9kVwOIaQXg/QthtXaDHNB/9OanDtgcpitI209gENRjF81bYWCehImil6jbVnn
 DUnVmfZIQ6k3dFsAPC4W7uJdA2FORtQzEZ1dZ13Ivx9jmbazK81ptUbIMAAnyfIZ
 rUhv+UqaDIlflYwuay58ZPdu8no4nQlJMPiPybXiizfTVStEne9SQKOacP8j7XL0
 GSjEyDO8lJXCPVSVnGEyybBH50M0myGUSH73+56o2QRRLtrHLDfieOL/N8AarNDh
 7U2g9pq0+IFPuJsm9SFR14dIpUAvpKohc57ZvsmworC8NuENzl6H3b6/U4n/1oNE
 JCbcitl91GkyF0Bvyac5a9wfk8SsYEJEGLPrtNX8UwH0UJh8spkfoQq5oHkC3juQ
 77n//eOFSz8oPDlV7ayNv+W3CEzOW09mSYFu8bdjBKC5HeyBJsm3HnJdaAhSqNEH
 6duRvcMlUJQ0JPILJoS1Zoy166uIu8hs2mZtygcAzyacia8yckL+Oq2UCYMi2oKP
 psOIzfd6G/+f203w37jdSY0OVlQSHvmCFSeaY6FHs2LEApDrNWK1cMLYO+lMU8EE
 q0j2SmDNMHhM
 =P1hX
 -----END PGP SIGNATURE-----

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

Pull networking fixes from Paolo Abeni:
 "Including fixes from Bluetooth and WiFi. Notably this includes the fix
  for the iwlwifi issue you reported.

  Current release - regressions:

   - core: avoid prefetching NULL pointers

   - wifi:
      - iwlwifi: implement settime64 as stub for MVM/MLD PTP
      - mac80211: fix list iteration in ieee80211_add_virtual_monitor()

   - handshake: fix null-ptr-deref in handshake_complete()

   - eth: mana: fix use-after-free in reset service rescan path

  Previous releases - regressions:

   - openvswitch: avoid needlessly taking the RTNL on vport destroy

   - dsa: properly keep track of conduit reference

   - ipv4:
      - fix error route reference count leak with nexthop objects
      - fib: restore ECMP balance from loopback

   - mptcp: ensure context reset on disconnect()

   - bluetooth: fix potential UaF in btusb

   - nfc: fix deadlock between nfc_unregister_device and
     rfkill_fop_write

   - eth:
      - gve: defer interrupt enabling until NAPI registration
      - i40e: fix scheduling in set_rx_mode
      - macb: relocate mog_init_rings() callback from macb_mac_link_up()
        to macb_open()
      - rtl8150: fix memory leak on usb_submit_urb() failure

   - wifi: 8192cu: fix tid out of range in rtl92cu_tx_fill_desc()

  Previous releases - always broken:

   - ip6_gre: make ip6gre_header() robust

   - ipv6: fix a BUG in rt6_get_pcpu_route() under PREEMPT_RT

   - af_unix: don't post cmsg for SO_INQ unless explicitly asked for

   - phy: mediatek: fix nvmem cell reference leak in
     mt798x_phy_calibration

   - wifi: mac80211: discard beacon frames to non-broadcast address

   - eth:
      - iavf: fix off-by-one issues in iavf_config_rss_reg()
      - stmmac: fix the crash issue for zero copy XDP_TX action
      - team: fix check for port enabled when priority changes"

* tag 'net-6.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (64 commits)
  ipv6: fix a BUG in rt6_get_pcpu_route() under PREEMPT_RT
  net: rose: fix invalid array index in rose_kill_by_device()
  net: enetc: do not print error log if addr is 0
  net: macb: Relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()
  selftests: fib_test: Add test case for ipv4 multi nexthops
  net: fib: restore ECMP balance from loopback
  selftests: fib_nexthops: Add test cases for error routes deletion
  ipv4: Fix reference count leak when using error routes with nexthop objects
  net: usb: sr9700: fix incorrect command used to write single register
  ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr()
  usbnet: avoid a possible crash in dql_completed()
  gve: defer interrupt enabling until NAPI registration
  net: stmmac: fix the crash issue for zero copy XDP_TX action
  octeontx2-pf: fix "UBSAN: shift-out-of-bounds error"
  af_unix: don't post cmsg for SO_INQ unless explicitly asked for
  net: mana: Fix use-after-free in reset service rescan path
  net: avoid prefetching NULL pointers
  net: bridge: Describe @tunnel_hash member in net_bridge_vlan_group struct
  net: nfc: fix deadlock between nfc_unregister_device and rfkill_fop_write
  net: usb: asix: validate PHY address before use
  ...
This commit is contained in:
Linus Torvalds 2025-12-30 08:45:58 -08:00
commit dbf8fe85a1
71 changed files with 428 additions and 194 deletions

View File

@ -4052,7 +4052,7 @@ static int btusb_probe(struct usb_interface *intf,
return -ENODEV;
}
data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@ -4075,8 +4075,10 @@ static int btusb_probe(struct usb_interface *intf,
}
}
if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
kfree(data);
return -ENODEV;
}
if (id->driver_info & BTUSB_AMP) {
data->cmdreq_type = USB_TYPE_CLASS | 0x01;
@ -4131,8 +4133,10 @@ static int btusb_probe(struct usb_interface *intf,
data->recv_acl = hci_recv_frame;
hdev = hci_alloc_dev_priv(priv_size);
if (!hdev)
if (!hdev) {
kfree(data);
return -ENOMEM;
}
hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data);
@ -4406,6 +4410,7 @@ out_free_dev:
if (data->reset_gpio)
gpiod_put(data->reset_gpio);
hci_free_dev(hdev);
kfree(data);
return err;
}
@ -4454,6 +4459,7 @@ static void btusb_disconnect(struct usb_interface *intf)
}
hci_free_dev(hdev);
kfree(data);
}
#ifdef CONFIG_PM

View File

@ -2169,6 +2169,9 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
if (!ent->is_valid)
return 0;
if (is_multicast_ether_addr(ent->mac))
return 0;
if (port != ent->port)
return 0;

View File

@ -2924,19 +2924,26 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
port->id = id;
eth->ports[p] = port;
err = airoha_metadata_dst_alloc(port);
if (err)
return err;
return airoha_metadata_dst_alloc(port);
}
err = register_netdev(dev);
if (err)
goto free_metadata_dst;
static int airoha_register_gdm_devices(struct airoha_eth *eth)
{
int i;
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
int err;
if (!port)
continue;
err = register_netdev(port->dev);
if (err)
return err;
}
return 0;
free_metadata_dst:
airoha_metadata_dst_free(port);
return err;
}
static int airoha_probe(struct platform_device *pdev)
@ -3027,6 +3034,10 @@ static int airoha_probe(struct platform_device *pdev)
}
}
err = airoha_register_gdm_devices(eth);
if (err)
goto error_napi_stop;
return 0;
error_napi_stop:
@ -3040,10 +3051,12 @@ error_hw_cleanup:
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
if (port && port->dev->reg_state == NETREG_REGISTERED) {
if (!port)
continue;
if (port->dev->reg_state == NETREG_REGISTERED)
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
}
airoha_metadata_dst_free(port);
}
free_netdev(eth->napi_dev);
platform_set_drvdata(pdev, NULL);

View File

@ -1928,6 +1928,7 @@ static void xgbe_set_rx_adap_mode(struct xgbe_prv_data *pdata,
{
if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
pdata->rx_adapt_retries = 0;
pdata->mode_set = false;
return;
}
@ -1974,6 +1975,7 @@ static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata)
*/
netif_dbg(pdata, link, pdata->netdev, "Block_lock done");
pdata->rx_adapt_done = true;
pdata->rx_adapt_retries = 0;
pdata->mode_set = false;
return;
}

View File

@ -255,14 +255,14 @@ config BNXT_HWMON
devices, via the hwmon sysfs interface.
config BNGE
tristate "Broadcom Ethernet device support"
tristate "Broadcom ThorUltra Ethernet device support"
depends on PCI
select NET_DEVLINK
select PAGE_POOL
help
This driver supports Broadcom 50/100/200/400/800 gigabit Ethernet cards.
The module will be called bng_en. To compile this driver as a module,
choose M here.
This driver supports Broadcom ThorUltra 50/100/200/400/800 gigabit
Ethernet cards. The module will be called bng_en. To compile this
driver as a module, choose M here.
config BCMASP
tristate "Broadcom ASP 2.0 Ethernet support"

View File

@ -5,7 +5,7 @@
#define _BNGE_H_
#define DRV_NAME "bng_en"
#define DRV_SUMMARY "Broadcom 800G Ethernet Linux Driver"
#define DRV_SUMMARY "Broadcom ThorUltra NIC Ethernet Driver"
#include <linux/etherdevice.h>
#include <linux/bnxt/hsi.h>

View File

@ -19,7 +19,7 @@ char bnge_driver_name[] = DRV_NAME;
static const struct {
char *name;
} board_info[] = {
[BCM57708] = { "Broadcom BCM57708 50Gb/100Gb/200Gb/400Gb/800Gb Ethernet" },
[BCM57708] = { "Broadcom BCM57708 ThorUltra 50Gb/100Gb/200Gb/400Gb/800Gb Ethernet" },
};
static const struct pci_device_id bnge_pci_tbl[] = {

View File

@ -708,7 +708,6 @@ static void macb_mac_link_up(struct phylink_config *config,
/* Initialize rings & buffers as clearing MACB_BIT(TE) in link down
* cleared the pipeline and control registers.
*/
bp->macbgem_ops.mog_init_rings(bp);
macb_init_buffers(bp);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
@ -2954,6 +2953,8 @@ static int macb_open(struct net_device *dev)
goto pm_exit;
}
bp->macbgem_ops.mog_init_rings(bp);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
napi_enable(&queue->napi_rx);
napi_enable(&queue->napi_tx);

View File

@ -577,11 +577,17 @@ static int imx94_enetc_mdio_phyaddr_config(struct netc_blk_ctrl *priv,
}
addr = netc_get_phy_addr(np);
if (addr <= 0) {
if (addr < 0) {
dev_err(dev, "Failed to get PHY address\n");
return addr;
}
/* The default value of LaBCR[MDIO_PHYAD_PRTAD] is 0,
* so no need to set the register.
*/
if (!addr)
return 0;
if (phy_mask & BIT(addr)) {
dev_err(dev,
"Find same PHY address in EMDIO and ENETC node\n");

View File

@ -558,7 +558,7 @@ static int gve_alloc_notify_blocks(struct gve_priv *priv)
block->priv = priv;
err = request_irq(priv->msix_vectors[msix_idx].vector,
gve_is_gqi(priv) ? gve_intr : gve_intr_dqo,
0, block->name, block);
IRQF_NO_AUTOEN, block->name, block);
if (err) {
dev_err(&priv->pdev->dev,
"Failed to receive msix vector %d\n", i);

View File

@ -112,11 +112,13 @@ void gve_add_napi(struct gve_priv *priv, int ntfy_idx,
netif_napi_add_locked(priv->dev, &block->napi, gve_poll);
netif_napi_set_irq_locked(&block->napi, block->irq);
enable_irq(block->irq);
}
void gve_remove_napi(struct gve_priv *priv, int ntfy_idx)
{
struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
disable_irq(block->irq);
netif_napi_del_locked(&block->napi);
}

View File

@ -4094,7 +4094,15 @@ static bool e1000_tbi_should_accept(struct e1000_adapter *adapter,
u32 length, const u8 *data)
{
struct e1000_hw *hw = &adapter->hw;
u8 last_byte = *(data + length - 1);
u8 last_byte;
/* Guard against OOB on data[length - 1] */
if (unlikely(!length))
return false;
/* Upper bound: length must not exceed rx_buffer_len */
if (unlikely(length > adapter->rx_buffer_len))
return false;
last_byte = *(data + length - 1);
if (TBI_ACCEPT(hw, status, errors, length, last_byte)) {
unsigned long irq_flags;

View File

@ -1422,4 +1422,15 @@ static inline struct i40e_veb *i40e_pf_get_main_veb(struct i40e_pf *pf)
return (pf->lan_veb != I40E_NO_VEB) ? pf->veb[pf->lan_veb] : NULL;
}
static inline u32 i40e_get_max_num_descriptors(const struct i40e_pf *pf)
{
const struct i40e_hw *hw = &pf->hw;
switch (hw->mac.type) {
case I40E_MAC_XL710:
return I40E_MAX_NUM_DESCRIPTORS_XL710;
default:
return I40E_MAX_NUM_DESCRIPTORS;
}
}
#endif /* _I40E_H_ */

View File

@ -2013,18 +2013,6 @@ static void i40e_get_drvinfo(struct net_device *netdev,
drvinfo->n_priv_flags += I40E_GL_PRIV_FLAGS_STR_LEN;
}
static u32 i40e_get_max_num_descriptors(struct i40e_pf *pf)
{
struct i40e_hw *hw = &pf->hw;
switch (hw->mac.type) {
case I40E_MAC_XL710:
return I40E_MAX_NUM_DESCRIPTORS_XL710;
default:
return I40E_MAX_NUM_DESCRIPTORS;
}
}
static void i40e_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,

View File

@ -2234,6 +2234,7 @@ static void i40e_set_rx_mode(struct net_device *netdev)
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state);
}
i40e_service_event_schedule(vsi->back);
}
/**

View File

@ -656,7 +656,7 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_id,
/* ring_len has to be multiple of 8 */
if (!IS_ALIGNED(info->ring_len, 8) ||
info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
info->ring_len > i40e_get_max_num_descriptors(pf)) {
ret = -EINVAL;
goto error_context;
}
@ -726,7 +726,7 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id,
/* ring_len has to be multiple of 32 */
if (!IS_ALIGNED(info->ring_len, 32) ||
info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
info->ring_len > i40e_get_max_num_descriptors(pf)) {
ret = -EINVAL;
goto error_param;
}

View File

@ -1726,11 +1726,11 @@ static int iavf_config_rss_reg(struct iavf_adapter *adapter)
u16 i;
dw = (u32 *)adapter->rss_key;
for (i = 0; i <= adapter->rss_key_size / 4; i++)
for (i = 0; i < adapter->rss_key_size / 4; i++)
wr32(hw, IAVF_VFQF_HKEY(i), dw[i]);
dw = (u32 *)adapter->rss_lut;
for (i = 0; i <= adapter->rss_lut_size / 4; i++)
for (i = 0; i < adapter->rss_lut_size / 4; i++)
wr32(hw, IAVF_VFQF_HLUT(i), dw[i]);
iavf_flush(hw);

View File

@ -1271,7 +1271,7 @@ void idpf_mbx_task(struct work_struct *work)
idpf_mb_irq_enable(adapter);
else
queue_delayed_work(adapter->mbx_wq, &adapter->mbx_task,
msecs_to_jiffies(300));
usecs_to_jiffies(300));
idpf_recv_mb_msg(adapter);
}

View File

@ -1016,6 +1016,9 @@ static int idpf_send_get_lan_memory_regions(struct idpf_adapter *adapter)
struct idpf_vc_xn_params xn_params = {
.vc_op = VIRTCHNL2_OP_GET_LAN_MEMORY_REGIONS,
.recv_buf.iov_len = IDPF_CTLQ_MAX_BUF_LEN,
.send_buf.iov_len =
sizeof(struct virtchnl2_get_lan_memory_regions) +
sizeof(struct virtchnl2_mem_region),
.timeout_ms = IDPF_VC_XN_DEFAULT_TIMEOUT_MSEC,
};
int num_regions, size;
@ -1028,6 +1031,8 @@ static int idpf_send_get_lan_memory_regions(struct idpf_adapter *adapter)
return -ENOMEM;
xn_params.recv_buf.iov_base = rcvd_regions;
rcvd_regions->num_memory_regions = cpu_to_le16(1);
xn_params.send_buf.iov_base = rcvd_regions;
reply_sz = idpf_vc_xn_exec(adapter, &xn_params);
if (reply_sz < 0)
return reply_sz;

View File

@ -418,6 +418,14 @@ static int otx2_set_ringparam(struct net_device *netdev,
*/
if (rx_count < pfvf->hw.rq_skid)
rx_count = pfvf->hw.rq_skid;
if (ring->rx_pending < 16) {
netdev_err(netdev,
"rx ring size %u invalid, min is 16\n",
ring->rx_pending);
return -EINVAL;
}
rx_count = Q_COUNT(Q_SIZE(rx_count, 3));
/* Due pipelining impact minimum 2000 unused SQ CQE's

View File

@ -481,7 +481,7 @@ static void mana_serv_reset(struct pci_dev *pdev)
/* Perform PCI rescan on device if we failed on HWC */
dev_err(&pdev->dev, "MANA service: resume failed, rescanning\n");
mana_serv_rescan(pdev);
goto out;
return;
}
if (ret)

View File

@ -516,15 +516,7 @@ static inline void smc_rcv(struct net_device *dev)
* any other concurrent access and C would always interrupt B. But life
* isn't that easy in a SMP world...
*/
#define smc_special_trylock(lock, flags) \
({ \
int __ret; \
local_irq_save(flags); \
__ret = spin_trylock(lock); \
if (!__ret) \
local_irq_restore(flags); \
__ret; \
})
#define smc_special_trylock(lock, flags) spin_trylock_irqsave(lock, flags)
#define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags)
#define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags)
#else

View File

@ -89,6 +89,7 @@ MODULE_PARM_DESC(phyaddr, "Physical device address");
#define STMMAC_XDP_CONSUMED BIT(0)
#define STMMAC_XDP_TX BIT(1)
#define STMMAC_XDP_REDIRECT BIT(2)
#define STMMAC_XSK_CONSUMED BIT(3)
static int flow_ctrl = 0xdead;
module_param(flow_ctrl, int, 0644);
@ -5126,6 +5127,7 @@ static int stmmac_xdp_get_tx_queue(struct stmmac_priv *priv,
static int stmmac_xdp_xmit_back(struct stmmac_priv *priv,
struct xdp_buff *xdp)
{
bool zc = !!(xdp->rxq->mem.type == MEM_TYPE_XSK_BUFF_POOL);
struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
int cpu = smp_processor_id();
struct netdev_queue *nq;
@ -5142,9 +5144,18 @@ static int stmmac_xdp_xmit_back(struct stmmac_priv *priv,
/* Avoids TX time-out as we are sharing with slow path */
txq_trans_cond_update(nq);
res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, false);
if (res == STMMAC_XDP_TX)
/* For zero copy XDP_TX action, dma_map is true */
res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, zc);
if (res == STMMAC_XDP_TX) {
stmmac_flush_tx_descriptors(priv, queue);
} else if (res == STMMAC_XDP_CONSUMED && zc) {
/* xdp has been freed by xdp_convert_buff_to_frame(),
* no need to call xsk_buff_free() again, so return
* STMMAC_XSK_CONSUMED.
*/
res = STMMAC_XSK_CONSUMED;
xdp_return_frame(xdpf);
}
__netif_tx_unlock(nq);
@ -5494,6 +5505,8 @@ read_again:
break;
case STMMAC_XDP_CONSUMED:
xsk_buff_free(buf->xdp);
fallthrough;
case STMMAC_XSK_CONSUMED:
rx_dropped++;
break;
case STMMAC_XDP_TX:

View File

@ -21,6 +21,7 @@ config LIBWX
depends on PTP_1588_CLOCK_OPTIONAL
select PAGE_POOL
select DIMLIB
select PHYLINK
help
Common library for Wangxun(R) Ethernet drivers.
@ -29,7 +30,6 @@ config NGBE
depends on PCI
depends on PTP_1588_CLOCK_OPTIONAL
select LIBWX
select PHYLINK
help
This driver supports Wangxun(R) GbE PCI Express family of
adapters.
@ -48,7 +48,6 @@ config TXGBE
depends on PTP_1588_CLOCK_OPTIONAL
select MARVELL_10G_PHY
select REGMAP
select PHYLINK
select HWMON if TXGBE=y
select SFP
select GPIOLIB
@ -71,7 +70,6 @@ config TXGBEVF
depends on PCI_MSI
depends on PTP_1588_CLOCK_OPTIONAL
select LIBWX
select PHYLINK
help
This driver supports virtual functions for SP1000A, WX1820AL,
WX5XXX, WX5XXXAL.

View File

@ -334,7 +334,7 @@ int fjes_hw_init(struct fjes_hw *hw)
ret = fjes_hw_reset(hw);
if (ret)
return ret;
goto err_iounmap;
fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
@ -347,8 +347,10 @@ int fjes_hw_init(struct fjes_hw *hw)
hw->max_epid = fjes_hw_get_max_epid(hw);
hw->my_epid = fjes_hw_get_my_epid(hw);
if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid))
return -ENXIO;
if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid)) {
ret = -ENXIO;
goto err_iounmap;
}
ret = fjes_hw_setup(hw);
@ -356,6 +358,10 @@ int fjes_hw_init(struct fjes_hw *hw)
hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE;
return ret;
err_iounmap:
fjes_hw_iounmap(hw);
return ret;
}
void fjes_hw_exit(struct fjes_hw *hw)

View File

@ -63,6 +63,13 @@ static int aspeed_mdio_op(struct mii_bus *bus, u8 st, u8 op, u8 phyad, u8 regad,
iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL);
/* Workaround for read-after-write issue.
* The controller may return stale data if a read follows immediately
* after a write. A dummy read forces the hardware to update its
* internal state, ensuring that the next real read returns correct data.
*/
ioread32(ctx->base + ASPEED_MDIO_CTRL);
return readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl,
!(ctrl & ASPEED_MDIO_CTRL_FIRE),
ASPEED_MDIO_INTERVAL_US,

View File

@ -354,7 +354,6 @@ static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_pri
struct fwnode_handle *node)
{
struct rtl9300_mdio_chan *chan;
struct fwnode_handle *child;
struct mii_bus *bus;
u32 mdio_bus;
int err;
@ -371,7 +370,7 @@ static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_pri
* compatible = "ethernet-phy-ieee802.3-c45". This does mean we can't
* support both c45 and c22 on the same MDIO bus.
*/
fwnode_for_each_child_node(node, child)
fwnode_for_each_child_node_scoped(node, child)
if (fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"))
priv->smi_bus_is_c45[mdio_bus] = true;
@ -409,7 +408,6 @@ static int rtl9300_mdiobus_map_ports(struct device *dev)
{
struct rtl9300_mdio_priv *priv = dev_get_drvdata(dev);
struct device *parent = dev->parent;
struct fwnode_handle *port;
int err;
struct fwnode_handle *ports __free(fwnode_handle) =
@ -418,7 +416,7 @@ static int rtl9300_mdiobus_map_ports(struct device *dev)
return dev_err_probe(dev, -EINVAL, "%pfwP missing ethernet-ports\n",
dev_fwnode(parent));
fwnode_for_each_child_node(ports, port) {
fwnode_for_each_child_node_scoped(ports, port) {
struct device_node *mdio_dn;
u32 addr;
u32 bus;

View File

@ -1167,9 +1167,9 @@ static int mt798x_phy_calibration(struct phy_device *phydev)
}
buf = (u32 *)nvmem_cell_read(cell, &len);
nvmem_cell_put(cell);
if (IS_ERR(buf))
return PTR_ERR(buf);
nvmem_cell_put(cell);
if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
phydev_err(phydev, "invalid efuse data\n");

View File

@ -878,7 +878,7 @@ static void __team_queue_override_enabled_check(struct team *team)
static void team_queue_override_port_prio_changed(struct team *team,
struct team_port *port)
{
if (!port->queue_id || team_port_enabled(port))
if (!port->queue_id || !team_port_enabled(port))
return;
__team_queue_override_port_del(team, port);
__team_queue_override_port_add(team, port);

View File

@ -335,6 +335,11 @@ int asix_read_phy_addr(struct usbnet *dev, bool internal)
offset = (internal ? 1 : 0);
ret = buf[offset];
if (ret >= PHY_MAX_ADDR) {
netdev_err(dev->net, "invalid PHY address: %d\n", ret);
return -ENODEV;
}
netdev_dbg(dev->net, "%s PHY address 0x%x\n",
internal ? "internal" : "external", ret);

View File

@ -210,11 +210,7 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
ret = asix_read_phy_addr(dev, priv->use_embdphy);
if (ret < 0)
goto free;
if (ret >= PHY_MAX_ADDR) {
netdev_err(dev->net, "Invalid PHY address %#x\n", ret);
ret = -ENODEV;
goto free;
}
priv->phy_addr = ret;
ax88172a_reset_phy(dev, priv->use_embdphy);

View File

@ -211,6 +211,8 @@ static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg)
if (res == -ENODEV)
netif_device_detach(dev->netdev);
dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res);
kfree(req);
usb_free_urb(async_urb);
}
return res;
}

View File

@ -52,7 +52,7 @@ static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value)
static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
{
return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG,
return usbnet_write_cmd(dev, SR_WR_REG, SR_REQ_WR_REG,
value, reg, NULL, 0);
}
@ -65,7 +65,7 @@ static void sr_write_async(struct usbnet *dev, u8 reg, u16 length,
static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
{
usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
usbnet_write_cmd_async(dev, SR_WR_REG, SR_REQ_WR_REG,
value, reg, NULL, 0);
}
@ -539,6 +539,11 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */
.driver_info = (unsigned long)&sr9700_driver_info,
},
{
/* SR9700 with virtual driver CD-ROM - interface 0 is the CD-ROM device */
USB_DEVICE_INTERFACE_NUMBER(0x0fe6, 0x9702, 1),
.driver_info = (unsigned long)&sr9700_driver_info,
},
{}, /* END */
};

View File

@ -831,7 +831,6 @@ int usbnet_stop(struct net_device *net)
clear_bit(EVENT_DEV_OPEN, &dev->flags);
netif_stop_queue(net);
netdev_reset_queue(net);
netif_info(dev, ifdown, dev->net,
"stop stats: rx/tx %lu/%lu, errs %lu/%lu\n",
@ -875,6 +874,8 @@ int usbnet_stop(struct net_device *net)
timer_delete_sync(&dev->delay);
cancel_work_sync(&dev->kevent);
netdev_reset_queue(net);
if (!pm)
usb_autopm_put_interface(dev->intf);

View File

@ -1597,7 +1597,7 @@ static void _iwl_op_mode_stop(struct iwl_drv *drv)
*/
static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
{
unsigned int min_core, max_core, loaded_core;
int min_core, max_core, loaded_core;
struct iwl_drv *drv = context;
struct iwl_fw *fw = &drv->fw;
const struct iwl_ucode_header *ucode;
@ -1676,7 +1676,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
if (loaded_core < min_core || loaded_core > max_core) {
IWL_ERR(drv,
"Driver unable to support your firmware API. "
"Driver supports FW core %u..%u, firmware is %u.\n",
"Driver supports FW core %d..%d, firmware is %d.\n",
min_core, max_core, loaded_core);
goto try_again;
}

View File

@ -121,6 +121,12 @@ static int iwl_mld_ptp_gettime(struct ptp_clock_info *ptp,
return 0;
}
static int iwl_mld_ptp_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts)
{
return -EOPNOTSUPP;
}
static int iwl_mld_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct iwl_mld *mld = container_of(ptp, struct iwl_mld,
@ -279,6 +285,7 @@ void iwl_mld_ptp_init(struct iwl_mld *mld)
mld->ptp_data.ptp_clock_info.owner = THIS_MODULE;
mld->ptp_data.ptp_clock_info.gettime64 = iwl_mld_ptp_gettime;
mld->ptp_data.ptp_clock_info.settime64 = iwl_mld_ptp_settime;
mld->ptp_data.ptp_clock_info.max_adj = 0x7fffffff;
mld->ptp_data.ptp_clock_info.adjtime = iwl_mld_ptp_adjtime;
mld->ptp_data.ptp_clock_info.adjfine = iwl_mld_ptp_adjfine;

View File

@ -220,6 +220,12 @@ static int iwl_mvm_ptp_gettime(struct ptp_clock_info *ptp,
return 0;
}
static int iwl_mvm_ptp_settime(struct ptp_clock_info *ptp,
const struct timespec64 *ts)
{
return -EOPNOTSUPP;
}
static int iwl_mvm_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct iwl_mvm *mvm = container_of(ptp, struct iwl_mvm,
@ -281,6 +287,7 @@ void iwl_mvm_ptp_init(struct iwl_mvm *mvm)
mvm->ptp_data.ptp_clock_info.adjfine = iwl_mvm_ptp_adjfine;
mvm->ptp_data.ptp_clock_info.adjtime = iwl_mvm_ptp_adjtime;
mvm->ptp_data.ptp_clock_info.gettime64 = iwl_mvm_ptp_gettime;
mvm->ptp_data.ptp_clock_info.settime64 = iwl_mvm_ptp_settime;
mvm->ptp_data.scaled_freq = SCALE_FACTOR;
/* Give a short 'friendly name' to identify the PHC clock */

View File

@ -511,7 +511,8 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
if (sta) {
sta_entry = (struct rtl_sta_info *)sta->drv_priv;
tid = ieee80211_get_tid(hdr);
agg_state = sta_entry->tids[tid].agg.agg_state;
if (tid < MAX_TID_COUNT)
agg_state = sta_entry->tids[tid].agg.agg_state;
ampdu_density = sta->deflink.ht_cap.ampdu_density;
}

View File

@ -144,8 +144,10 @@ static u32 rtw_sdio_to_io_address(struct rtw_dev *rtwdev, u32 addr,
static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr)
{
bool might_indirect_under_power_off = rtwdev->chip->id == RTW_CHIP_TYPE_8822C;
if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags) &&
!rtw_sdio_is_bus_addr(addr))
!rtw_sdio_is_bus_addr(addr) && might_indirect_under_power_off)
return false;
return !rtw_sdio_is_sdio30_supported(rtwdev) ||

View File

@ -965,8 +965,7 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
struct sk_buff *rx_skb;
int i;
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_UNBOUND,
0);
rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0);
if (!rtwusb->rxwq) {
rtw_err(rtwdev, "failed to create RX work queue\n");
return -ENOMEM;

View File

@ -207,6 +207,11 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
if (total_blocks <= wl->tx_blocks_available) {
if (skb_headroom(skb) < (total_len - skb->len) &&
pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) {
wl1271_free_tx_id(wl, id);
return -EAGAIN;
}
desc = skb_push(skb, total_len - skb->len);
wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,

View File

@ -302,6 +302,7 @@ struct dsa_port {
struct devlink_port devlink_port;
struct phylink *pl;
struct phylink_config pl_config;
netdevice_tracker conduit_tracker;
struct dsa_lag *lag;
struct net_device *hsr_dev;

View File

@ -849,6 +849,12 @@ static u32 get_supported_settings(struct hci_dev *hdev)
if (cis_peripheral_capable(hdev))
settings |= MGMT_SETTING_CIS_PERIPHERAL;
if (bis_capable(hdev))
settings |= MGMT_SETTING_ISO_BROADCASTER;
if (sync_recv_capable(hdev))
settings |= MGMT_SETTING_ISO_SYNC_RECEIVER;
if (ll_privacy_capable(hdev))
settings |= MGMT_SETTING_LL_PRIVACY;

View File

@ -247,6 +247,7 @@ struct net_bridge_vlan {
* struct net_bridge_vlan_group
*
* @vlan_hash: VLAN entry rhashtable
* @tunnel_hash: Hash table to map from tunnel key ID (e.g. VXLAN VNI) to VLAN
* @vlan_list: sorted VLAN entry list
* @num_vlans: number of total VLAN entries
* @pvid: PVID VLAN id

View File

@ -4241,9 +4241,11 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
int count = 0;
llist_for_each_entry_safe(skb, next, ll_list, ll_node) {
prefetch(next);
prefetch(&next->priority);
skb_mark_not_on_list(skb);
if (next) {
prefetch(next);
prefetch(&next->priority);
skb_mark_not_on_list(skb);
}
rc = dev_qdisc_enqueue(skb, q, &to_free, txq);
count++;
}

View File

@ -367,16 +367,10 @@ static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
struct net_device *dsa_tree_find_first_conduit(struct dsa_switch_tree *dst)
{
struct device_node *ethernet;
struct net_device *conduit;
struct dsa_port *cpu_dp;
cpu_dp = dsa_tree_find_first_cpu(dst);
ethernet = of_parse_phandle(cpu_dp->dn, "ethernet", 0);
conduit = of_find_net_device_by_node(ethernet);
of_node_put(ethernet);
return conduit;
return cpu_dp->conduit;
}
/* Assign the default CPU port (the first one in the tree) to all ports of the
@ -1253,14 +1247,25 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
if (ethernet) {
struct net_device *conduit;
const char *user_protocol;
int err;
rtnl_lock();
conduit = of_find_net_device_by_node(ethernet);
of_node_put(ethernet);
if (!conduit)
if (!conduit) {
rtnl_unlock();
return -EPROBE_DEFER;
}
netdev_hold(conduit, &dp->conduit_tracker, GFP_KERNEL);
put_device(&conduit->dev);
rtnl_unlock();
user_protocol = of_get_property(dn, "dsa-tag-protocol", NULL);
return dsa_port_parse_cpu(dp, conduit, user_protocol);
err = dsa_port_parse_cpu(dp, conduit, user_protocol);
if (err)
netdev_put(conduit, &dp->conduit_tracker);
return err;
}
if (link)
@ -1393,37 +1398,30 @@ static struct device *dev_find_class(struct device *parent, char *class)
return device_find_child(parent, class, dev_is_class);
}
static struct net_device *dsa_dev_to_net_device(struct device *dev)
{
struct device *d;
d = dev_find_class(dev, "net");
if (d != NULL) {
struct net_device *nd;
nd = to_net_dev(d);
dev_hold(nd);
put_device(d);
return nd;
}
return NULL;
}
static int dsa_port_parse(struct dsa_port *dp, const char *name,
struct device *dev)
{
if (!strcmp(name, "cpu")) {
struct net_device *conduit;
struct device *d;
int err;
conduit = dsa_dev_to_net_device(dev);
if (!conduit)
rtnl_lock();
d = dev_find_class(dev, "net");
if (!d) {
rtnl_unlock();
return -EPROBE_DEFER;
}
dev_put(conduit);
conduit = to_net_dev(d);
netdev_hold(conduit, &dp->conduit_tracker, GFP_KERNEL);
put_device(d);
rtnl_unlock();
return dsa_port_parse_cpu(dp, conduit, NULL);
err = dsa_port_parse_cpu(dp, conduit, NULL);
if (err)
netdev_put(conduit, &dp->conduit_tracker);
return err;
}
if (!strcmp(name, "dsa"))
@ -1491,6 +1489,9 @@ static void dsa_switch_release_ports(struct dsa_switch *ds)
struct dsa_vlan *v, *n;
dsa_switch_for_each_port_safe(dp, next, ds) {
if (dsa_port_is_cpu(dp) && dp->conduit)
netdev_put(dp->conduit, &dp->conduit_tracker);
/* These are either entries that upper layers lost track of
* (probably due to bugs), or installed through interfaces
* where one does not necessarily have to remove them, like
@ -1635,8 +1636,10 @@ void dsa_switch_shutdown(struct dsa_switch *ds)
/* Disconnect from further netdevice notifiers on the conduit,
* since netdev_uses_dsa() will now return false.
*/
dsa_switch_for_each_cpu_port(dp, ds)
dsa_switch_for_each_cpu_port(dp, ds) {
dp->conduit->dsa_ptr = NULL;
netdev_put(dp->conduit, &dp->conduit_tracker);
}
rtnl_unlock();
out:

View File

@ -126,7 +126,8 @@ int handshake_nl_accept_doit(struct sk_buff *skb, struct genl_info *info)
}
out_complete:
handshake_complete(req, -EIO, NULL);
if (req)
handshake_complete(req, -EIO, NULL);
out_status:
trace_handshake_cmd_accept_err(net, req, NULL, err);
return err;

View File

@ -2167,8 +2167,8 @@ void fib_select_multipath(struct fib_result *res, int hash,
{
struct fib_info *fi = res->fi;
struct net *net = fi->fib_net;
bool found = false;
bool use_neigh;
int score = -1;
__be32 saddr;
if (unlikely(res->fi->nh)) {
@ -2180,7 +2180,7 @@ void fib_select_multipath(struct fib_result *res, int hash,
saddr = fl4 ? fl4->saddr : 0;
change_nexthops(fi) {
int nh_upper_bound;
int nh_upper_bound, nh_score = 0;
/* Nexthops without a carrier are assigned an upper bound of
* minus one when "ignore_routes_with_linkdown" is set.
@ -2190,24 +2190,18 @@ void fib_select_multipath(struct fib_result *res, int hash,
(use_neigh && !fib_good_nh(nexthop_nh)))
continue;
if (!found) {
if (saddr && nexthop_nh->nh_saddr == saddr)
nh_score += 2;
if (hash <= nh_upper_bound)
nh_score++;
if (score < nh_score) {
res->nh_sel = nhsel;
res->nhc = &nexthop_nh->nh_common;
found = !saddr || nexthop_nh->nh_saddr == saddr;
if (nh_score == 3 || (!saddr && nh_score == 1))
return;
score = nh_score;
}
if (hash > nh_upper_bound)
continue;
if (!saddr || nexthop_nh->nh_saddr == saddr) {
res->nh_sel = nhsel;
res->nhc = &nexthop_nh->nh_common;
return;
}
if (found)
return;
} endfor_nexthops(fi);
}
#endif

View File

@ -2053,10 +2053,11 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all)
continue;
}
/* Do not flush error routes if network namespace is
* not being dismantled
/* When not flushing the entire table, skip error
* routes that are not marked for deletion.
*/
if (!flush_all && fib_props[fa->fa_type].error) {
if (!flush_all && fib_props[fa->fa_type].error &&
!(fi->fib_flags & RTNH_F_DEAD)) {
slen = fa->fa_slen;
continue;
}

View File

@ -330,6 +330,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
if (!tun_dst)
return PACKET_REJECT;
/* MUST set options_len before referencing options */
info = &tun_dst->u.tun_info;
info->options_len = sizeof(*md);
/* skb can be uncloned in __iptunnel_pull_header, so
* old pkt_md is no longer valid and we need to reset
* it
@ -344,10 +348,8 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
ERSPAN_V2_MDSIZE);
info = &tun_dst->u.tun_info;
__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
info->key.tun_flags);
info->options_len = sizeof(*md);
}
skb_reset_mac_header(skb);

View File

@ -1342,7 +1342,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
pad = ((new_end & 4) + (end & 7)) & 7;
len_delta = new_end - (int)end + pad;
ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
ret_val = skb_cow(skb,
skb_headroom(skb) + (len_delta > 0 ? len_delta : 0));
if (ret_val < 0)
return ret_val;

View File

@ -535,6 +535,10 @@ static int ip6erspan_rcv(struct sk_buff *skb,
if (!tun_dst)
return PACKET_REJECT;
/* MUST set options_len before referencing options */
info = &tun_dst->u.tun_info;
info->options_len = sizeof(*md);
/* skb can be uncloned in __iptunnel_pull_header, so
* old pkt_md is no longer valid and we need to reset
* it
@ -543,7 +547,6 @@ static int ip6erspan_rcv(struct sk_buff *skb,
skb_network_header_len(skb);
pkt_md = (struct erspan_metadata *)(gh + gre_hdr_len +
sizeof(*ershdr));
info = &tun_dst->u.tun_info;
md = ip_tunnel_info_opts(info);
md->version = ver;
md2 = &md->u.md2;
@ -551,7 +554,6 @@ static int ip6erspan_rcv(struct sk_buff *skb,
ERSPAN_V2_MDSIZE);
__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT,
info->key.tun_flags);
info->options_len = sizeof(*md);
ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
@ -1366,9 +1368,16 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
{
struct ip6_tnl *t = netdev_priv(dev);
struct ipv6hdr *ipv6h;
int needed;
__be16 *p;
ipv6h = skb_push(skb, t->hlen + sizeof(*ipv6h));
needed = t->hlen + sizeof(*ipv6h);
if (skb_headroom(skb) < needed &&
pskb_expand_head(skb, HH_DATA_ALIGN(needed - skb_headroom(skb)),
0, GFP_ATOMIC))
return -needed;
ipv6h = skb_push(skb, needed);
ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb,
t->fl.u.ip6.flowlabel,
true, &t->fl.u.ip6));

View File

@ -1470,7 +1470,18 @@ static struct rt6_info *rt6_make_pcpu_route(struct net *net,
p = this_cpu_ptr(res->nh->rt6i_pcpu);
prev = cmpxchg(p, NULL, pcpu_rt);
BUG_ON(prev);
if (unlikely(prev)) {
/*
* Another task on this CPU already installed a pcpu_rt.
* This can happen on PREEMPT_RT where preemption is possible.
* Free our allocation and return the existing one.
*/
WARN_ON_ONCE(!IS_ENABLED(CONFIG_PREEMPT_RT));
dst_dev_put(&pcpu_rt->dst);
dst_release(&pcpu_rt->dst);
return prev;
}
if (res->f6i->fib6_destroying) {
struct fib6_info *from;

View File

@ -1345,7 +1345,6 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
size = sizeof(*new) + new_head_len + new_tail_len;
/* new or old multiple BSSID elements? */
if (params->mbssid_ies) {
mbssid = params->mbssid_ies;
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
@ -1355,15 +1354,6 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
}
size += ieee80211_get_mbssid_beacon_len(mbssid, rnr,
mbssid->cnt);
} else if (old && old->mbssid_ies) {
mbssid = old->mbssid_ies;
size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
if (old && old->rnr_ies) {
rnr = old->rnr_ies;
size += struct_size(new->rnr_ies, elem, rnr->cnt);
}
size += ieee80211_get_mbssid_beacon_len(mbssid, rnr,
mbssid->cnt);
}
new = kzalloc(size, GFP_KERNEL);

View File

@ -1251,7 +1251,7 @@ configure_monitor:
if (!creator_sdata) {
struct ieee80211_sub_if_data *other;
list_for_each_entry(other, &local->mon_list, list) {
list_for_each_entry_rcu(other, &local->mon_list, u.mntr.list) {
if (!other->vif.bss_conf.mu_mimo_owner)
continue;

View File

@ -1126,7 +1126,10 @@ again:
while (!ieee80211_chandef_usable(sdata, &chanreq->oper,
IEEE80211_CHAN_DISABLED)) {
if (WARN_ON(chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT)) {
if (chanreq->oper.width == NL80211_CHAN_WIDTH_20_NOHT) {
link_id_info(sdata, link_id,
"unusable channel (%d MHz) for connection\n",
chanreq->oper.chan->center_freq);
ret = -EINVAL;
goto free;
}

View File

@ -47,6 +47,9 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
int band;
if (!ifocb->joined)
return;
/* XXX: Consider removing the least recently used entry and
* allow new one to be added.
*/

View File

@ -3511,6 +3511,11 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
return RX_DROP_U_RUNT_ACTION;
/* Drop non-broadcast Beacon frames */
if (ieee80211_is_beacon(mgmt->frame_control) &&
!is_broadcast_ether_addr(mgmt->da))
return RX_DROP;
if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
ieee80211_is_beacon(mgmt->frame_control) &&
!(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {

View File

@ -408,6 +408,16 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb,
*/
subflow->snd_isn = TCP_SKB_CB(skb)->end_seq;
if (subflow->request_mptcp) {
if (unlikely(subflow_simultaneous_connect(sk))) {
WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK));
/* Ensure mptcp_finish_connect() will not process the
* MPC handshake.
*/
subflow->request_mptcp = 0;
return false;
}
opts->suboptions = OPTION_MPTCP_MPC_SYN;
opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk));
opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk));

View File

@ -2467,10 +2467,10 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
*/
static void __mptcp_subflow_disconnect(struct sock *ssk,
struct mptcp_subflow_context *subflow,
unsigned int flags)
bool fastclosing)
{
if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
subflow->send_fastclose) {
fastclosing) {
/* The MPTCP code never wait on the subflow sockets, TCP-level
* disconnect should never fail
*/
@ -2538,7 +2538,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
if (!dispose_it) {
__mptcp_subflow_disconnect(ssk, subflow, flags);
__mptcp_subflow_disconnect(ssk, subflow, msk->fastclosing);
release_sock(ssk);
goto out;
@ -2884,6 +2884,7 @@ static void mptcp_do_fastclose(struct sock *sk)
mptcp_set_state(sk, TCP_CLOSE);
mptcp_backlog_purge(sk);
msk->fastclosing = 1;
/* Explicitly send the fastclose reset as need */
if (__mptcp_check_fallback(msk))
@ -3418,6 +3419,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
msk->bytes_sent = 0;
msk->bytes_retrans = 0;
msk->rcvspace_init = 0;
msk->fastclosing = 0;
/* for fallback's sake */
WRITE_ONCE(msk->ack_seq, 0);

View File

@ -320,7 +320,8 @@ struct mptcp_sock {
fastopening:1,
in_accept_queue:1,
free_first:1,
rcvspace_init:1;
rcvspace_init:1,
fastclosing:1;
u32 notsent_lowat;
int keepalive_cnt;
int keepalive_idle;
@ -1337,10 +1338,8 @@ static inline bool subflow_simultaneous_connect(struct sock *sk)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
return (1 << sk->sk_state) &
(TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING) &&
is_active_ssk(subflow) &&
!subflow->conn_finished;
/* Note that the sk state implies !subflow->conn_finished. */
return sk->sk_state == TCP_SYN_RECV && is_active_ssk(subflow);
}
#ifdef CONFIG_SYN_COOKIES

View File

@ -1878,12 +1878,6 @@ static void subflow_state_change(struct sock *sk)
__subflow_state_change(sk);
if (subflow_simultaneous_connect(sk)) {
WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK));
subflow->conn_finished = 1;
mptcp_propagate_state(parent, sk, subflow, NULL);
}
/* as recvmsg() does not acquire the subflow socket for ssk selection
* a fin packet carrying a DSS can be unnoticed if we don't trigger
* the data available machinery here.

View File

@ -1154,6 +1154,7 @@ EXPORT_SYMBOL(nfc_register_device);
void nfc_unregister_device(struct nfc_dev *dev)
{
int rc;
struct rfkill *rfk = NULL;
pr_debug("dev_name=%s\n", dev_name(&dev->dev));
@ -1164,13 +1165,17 @@ void nfc_unregister_device(struct nfc_dev *dev)
device_lock(&dev->dev);
if (dev->rfkill) {
rfkill_unregister(dev->rfkill);
rfkill_destroy(dev->rfkill);
rfk = dev->rfkill;
dev->rfkill = NULL;
}
dev->shutting_down = true;
device_unlock(&dev->dev);
if (rfk) {
rfkill_unregister(rfk);
rfkill_destroy(rfk);
}
if (dev->ops->check_presence) {
timer_delete_sync(&dev->check_pres_timer);
cancel_work_sync(&dev->check_pres_work);

View File

@ -160,10 +160,19 @@ void ovs_netdev_detach_dev(struct vport *vport)
static void netdev_destroy(struct vport *vport)
{
rtnl_lock();
if (netif_is_ovs_port(vport->dev))
ovs_netdev_detach_dev(vport);
rtnl_unlock();
/* When called from ovs_db_notify_wq() after a dp_device_event(), the
* port has already been detached, so we can avoid taking the RTNL by
* checking this first.
*/
if (netif_is_ovs_port(vport->dev)) {
rtnl_lock();
/* Check again while holding the lock to ensure we don't race
* with the netdev notifier and detach twice.
*/
if (netif_is_ovs_port(vport->dev))
ovs_netdev_detach_dev(vport);
rtnl_unlock();
}
call_rcu(&vport->rcu, vport_netdev_free);
}

View File

@ -205,7 +205,7 @@ start:
spin_unlock_bh(&rose_list_lock);
for (i = 0; i < cnt; i++) {
sk = array[cnt];
sk = array[i];
rose = rose_sk(sk);
lock_sock(sk);
spin_lock_bh(&rose_list_lock);

View File

@ -2904,6 +2904,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
unsigned int last_len;
struct unix_sock *u;
int copied = 0;
bool do_cmsg;
int err = 0;
long timeo;
int target;
@ -2929,6 +2930,9 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
u = unix_sk(sk);
do_cmsg = READ_ONCE(u->recvmsg_inq);
if (do_cmsg)
msg->msg_get_inq = 1;
redo:
/* Lock the socket to prevent queue disordering
* while sleeps in memcpy_tomsg
@ -3088,10 +3092,11 @@ unlock:
if (msg) {
scm_recv_unix(sock, msg, &scm, flags);
if (READ_ONCE(u->recvmsg_inq) || msg->msg_get_inq) {
if (msg->msg_get_inq && (copied ?: err) >= 0) {
msg->msg_inq = READ_ONCE(u->inq_len);
put_cmsg(msg, SOL_SOCKET, SCM_INQ,
sizeof(msg->msg_inq), &msg->msg_inq);
if (do_cmsg)
put_cmsg(msg, SOL_SOCKET, SCM_INQ,
sizeof(msg->msg_inq), &msg->msg_inq);
}
} else {
scm_destroy(&scm);

View File

@ -910,7 +910,7 @@ void __cfg80211_connect_result(struct net_device *dev,
ssid_len = min(ssid->datalen, IEEE80211_MAX_SSID_LEN);
memcpy(wdev->u.client.ssid, ssid->data, ssid_len);
wdev->u.client.ssid_len = ssid->datalen;
wdev->u.client.ssid_len = ssid_len;
break;
}
rcu_read_unlock();

View File

@ -573,8 +573,9 @@ def psp_ip_ver_test_builder(name, test_func, psp_ver, ipver):
"""Build test cases for each combo of PSP version and IP version"""
def test_case(cfg):
cfg.require_ipver(ipver)
test_case.__name__ = f"{name}_v{psp_ver}_ip{ipver}"
test_func(cfg, psp_ver, ipver)
test_case.__name__ = f"{name}_v{psp_ver}_ip{ipver}"
return test_case
@ -582,8 +583,9 @@ def ipver_test_builder(name, test_func, ipver):
"""Build test cases for each IP version"""
def test_case(cfg):
cfg.require_ipver(ipver)
test_case.__name__ = f"{name}_ip{ipver}"
test_func(cfg, ipver)
test_case.__name__ = f"{name}_ip{ipver}"
return test_case

View File

@ -800,6 +800,14 @@ ipv6_fcnal()
set +e
check_nexthop "dev veth1" ""
log_test $? 0 "Nexthops removed on admin down"
# error routes should be deleted when their nexthop is deleted
run_cmd "$IP li set dev veth1 up"
run_cmd "$IP -6 nexthop add id 58 dev veth1"
run_cmd "$IP ro add blackhole 2001:db8:101::1/128 nhid 58"
run_cmd "$IP nexthop del id 58"
check_route6 "2001:db8:101::1" ""
log_test $? 0 "Error route removed on nexthop deletion"
}
ipv6_grp_refs()
@ -1459,6 +1467,13 @@ ipv4_fcnal()
run_cmd "$IP ro del 172.16.102.0/24"
log_test $? 0 "Delete route when not specifying nexthop attributes"
# error routes should be deleted when their nexthop is deleted
run_cmd "$IP nexthop add id 23 dev veth1"
run_cmd "$IP ro add blackhole 172.16.102.100/32 nhid 23"
run_cmd "$IP nexthop del id 23"
check_route "172.16.102.100" ""
log_test $? 0 "Error route removed on nexthop deletion"
}
ipv4_grp_fcnal()

View File

@ -12,7 +12,7 @@ TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
fib6_ra_to_static"
ipv4_mpath_balance_preferred fib6_ra_to_static"
VERBOSE=0
PAUSE_ON_FAIL=no
@ -2751,6 +2751,73 @@ ipv4_mpath_balance_test()
forwarding_cleanup
}
get_route_dev_src()
{
local pfx="$1"
local src="$2"
local out
if out=$($IP -j route get "$pfx" from "$src" | jq -re ".[0].dev"); then
echo "$out"
fi
}
ipv4_mpath_preferred()
{
local src_ip=$1
local pref_dev=$2
local dev routes
local route0=0
local route1=0
local pref_route=0
num_routes=254
for i in $(seq 1 $num_routes) ; do
dev=$(get_route_dev_src 172.16.105.$i $src_ip)
if [ "$dev" = "$pref_dev" ]; then
pref_route=$((pref_route+1))
elif [ "$dev" = "veth1" ]; then
route0=$((route0+1))
elif [ "$dev" = "veth3" ]; then
route1=$((route1+1))
fi
done
routes=$((route0+route1))
[ "$VERBOSE" = "1" ] && echo "multipath: routes seen: ($route0,$route1,$pref_route)"
if [ x"$pref_dev" = x"" ]; then
[[ $routes -ge $num_routes ]] && [[ $route0 -gt 0 ]] && [[ $route1 -gt 0 ]]
else
[[ $pref_route -ge $num_routes ]]
fi
}
ipv4_mpath_balance_preferred_test()
{
echo
echo "IPv4 multipath load balance preferred route"
forwarding_setup
$IP route add 172.16.105.0/24 \
nexthop via 172.16.101.2 \
nexthop via 172.16.103.2
ipv4_mpath_preferred 172.16.101.1 veth1
log_test $? 0 "IPv4 multipath loadbalance from veth1"
ipv4_mpath_preferred 172.16.103.1 veth3
log_test $? 0 "IPv4 multipath loadbalance from veth3"
ipv4_mpath_preferred 198.51.100.1
log_test $? 0 "IPv4 multipath loadbalance from dummy"
forwarding_cleanup
}
ipv6_mpath_balance_test()
{
echo
@ -2861,6 +2928,7 @@ do
ipv6_mpath_list) ipv6_mpath_list_test;;
ipv4_mpath_balance) ipv4_mpath_balance_test;;
ipv6_mpath_balance) ipv6_mpath_balance_test;;
ipv4_mpath_balance_preferred) ipv4_mpath_balance_preferred_test;;
fib6_ra_to_static) fib6_ra_to_static;;
help) echo "Test names: $TESTS"; exit 0;;

View File

@ -56,18 +56,12 @@ static void rtattr_end(struct nlmsghdr *nh, struct rtattr *attr)
static struct rtattr *rtattr_add_str(struct nlmsghdr *nh, unsigned short type,
const char *s)
{
struct rtattr *rta = rtattr_add(nh, type, strlen(s));
unsigned int strsz = strlen(s) + 1;
struct rtattr *rta;
memcpy(RTA_DATA(rta), s, strlen(s));
return rta;
}
rta = rtattr_add(nh, type, strsz);
static struct rtattr *rtattr_add_strsz(struct nlmsghdr *nh, unsigned short type,
const char *s)
{
struct rtattr *rta = rtattr_add(nh, type, strlen(s) + 1);
strcpy(RTA_DATA(rta), s);
memcpy(RTA_DATA(rta), s, strsz);
return rta;
}
@ -119,7 +113,7 @@ static int dev_create(const char *dev, const char *link_type,
link_info = rtattr_begin(&req.nh, IFLA_LINKINFO);
rtattr_add_strsz(&req.nh, IFLA_INFO_KIND, link_type);
rtattr_add_str(&req.nh, IFLA_INFO_KIND, link_type);
if (fill_info_data) {
info_data = rtattr_begin(&req.nh, IFLA_INFO_DATA);