Skip to content

Commit

Permalink
Merge tag 'net-6.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/netdev/net

Pull networking fixes from Paolo Abeni:
 "Including fixes from netfilter.

  Current release - regressions:

    - core: hold instance lock during NETDEV_CHANGE

    - rtnetlink: fix bad unlock balance in do_setlink()

    - ipv6:
       - fix null-ptr-deref in addrconf_add_ifaddr()
       - align behavior across nexthops during path selection

  Previous releases - regressions:

    - sctp: prevent transport UaF in sendmsg

    - mptcp: only inc MPJoinAckHMacFailure for HMAC failures

  Previous releases - always broken:

    - sched:
       - make ->qlen_notify() idempotent
       - ensure sufficient space when sending filter netlink notifications
       - sch_sfq: really don't allow 1 packet limit

    - netfilter: fix incorrect avx2 match of 5th field octet

    - tls: explicitly disallow disconnect

    - eth: octeontx2-pf: fix VF root node parent queue priority"

* tag 'net-6.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (38 commits)
  ethtool: cmis_cdb: Fix incorrect read / write length extension
  selftests: netfilter: add test case for recent mismatch bug
  nft_set_pipapo: fix incorrect avx2 match of 5th field octet
  net: ppp: Add bound checking for skb data on ppp_sync_txmung
  net: Fix null-ptr-deref by sock_lock_init_class_and_name() and rmmod.
  ipv6: Align behavior across nexthops during path selection
  net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY
  net: phy: move phy_link_change() prior to mdio_bus_phy_may_suspend()
  selftests/tc-testing: sfq: check that a derived limit of 1 is rejected
  net_sched: sch_sfq: move the limit validation
  net_sched: sch_sfq: use a temporary work area for validating configuration
  net: libwx: handle page_pool_dev_alloc_pages error
  selftests: mptcp: validate MPJoin HMacFailure counters
  mptcp: only inc MPJoinAckHMacFailure for HMAC failures
  rtnetlink: Fix bad unlock balance in do_setlink().
  net: ethtool: Don't call .cleanup_data when prepare_data fails
  tc: Ensure we have enough buffer space when sending filter netlink notifications
  net: libwx: Fix the wrong Rx descriptor field
  octeontx2-pf: qos: fix VF root node parent queue index
  selftests: tls: check that disconnect does nothing
  ...
  • Loading branch information
Linus Torvalds committed Apr 10, 2025
2 parents 2eb959e + eaa517b commit ab59a86
Show file tree
Hide file tree
Showing 45 changed files with 649 additions and 150 deletions.
10 changes: 6 additions & 4 deletions Documentation/networking/netdevices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,11 @@ operations directly under the netdev instance lock.
Devices drivers are encouraged to rely on the instance lock where possible.

For the (mostly software) drivers that need to interact with the core stack,
there are two sets of interfaces: ``dev_xxx`` and ``netif_xxx`` (e.g.,
``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx`` functions handle
acquiring the instance lock themselves, while the ``netif_xxx`` functions
assume that the driver has already acquired the instance lock.
there are two sets of interfaces: ``dev_xxx``/``netdev_xxx`` and ``netif_xxx``
(e.g., ``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx``/``netdev_xxx``
functions handle acquiring the instance lock themselves, while the
``netif_xxx`` functions assume that the driver has already acquired
the instance lock.

Notifiers and netdev instance lock
==================================
Expand All @@ -354,6 +355,7 @@ For devices with locked ops, currently only the following notifiers are
running under the lock:
* ``NETDEV_REGISTER``
* ``NETDEV_UP``
* ``NETDEV_CHANGE``

The following notifiers are running without the lock:
* ``NETDEV_UNREGISTER``
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/qos.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ static void __otx2_qos_txschq_cfg(struct otx2_nic *pfvf,

otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
} else if (level == NIX_TXSCH_LVL_TL2) {
/* configure parent txschq */
cfg->reg[num_regs] = NIX_AF_TL2X_PARENT(node->schq);
cfg->regval[num_regs] = (u64)hw->tx_link << 16;
num_regs++;

/* configure link cfg */
if (level == pfvf->qos.link_cfg_lvl) {
cfg->reg[num_regs] = NIX_AF_TL3_TL2X_LINKX_CFG(node->schq, hw->tx_link);
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ethernet/wangxun/libwx/wx_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ static bool wx_alloc_mapped_page(struct wx_ring *rx_ring,
return true;

page = page_pool_dev_alloc_pages(rx_ring->page_pool);
WARN_ON(!page);
if (unlikely(!page))
return false;
dma = page_pool_get_dma_addr(page);

bi->page_dma = dma;
Expand Down Expand Up @@ -546,7 +547,8 @@ static void wx_rx_checksum(struct wx_ring *ring,
return;

/* Hardware can't guarantee csum if IPv6 Dest Header found */
if (dptype.prot != WX_DEC_PTYPE_PROT_SCTP && WX_RXD_IPV6EX(rx_desc))
if (dptype.prot != WX_DEC_PTYPE_PROT_SCTP &&
wx_test_staterr(rx_desc, WX_RXD_STAT_IPV6EX))
return;

/* if L4 checksum error */
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/wangxun/libwx/wx_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ enum WX_MSCA_CMD_value {
#define WX_RXD_STAT_L4CS BIT(7) /* L4 xsum calculated */
#define WX_RXD_STAT_IPCS BIT(8) /* IP xsum calculated */
#define WX_RXD_STAT_OUTERIPCS BIT(10) /* Cloud IP xsum calculated*/
#define WX_RXD_STAT_IPV6EX BIT(12) /* IPv6 Dest Header */
#define WX_RXD_STAT_TS BIT(14) /* IEEE1588 Time Stamp */

#define WX_RXD_ERR_OUTERIPER BIT(26) /* CRC IP Header error */
Expand Down Expand Up @@ -589,8 +590,6 @@ enum wx_l2_ptypes {

#define WX_RXD_PKTTYPE(_rxd) \
((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 9) & 0xFF)
#define WX_RXD_IPV6EX(_rxd) \
((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 6) & 0x1)
/*********************** Transmit Descriptor Config Masks ****************/
#define WX_TXD_STAT_DD BIT(0) /* Descriptor Done */
#define WX_TXD_DTYP_DATA 0 /* Adv Data Descriptor */
Expand Down
57 changes: 42 additions & 15 deletions drivers/net/phy/phy_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,46 @@ static bool phy_drv_wol_enabled(struct phy_device *phydev)
return wol.wolopts != 0;
}

static void phy_link_change(struct phy_device *phydev, bool up)
{
struct net_device *netdev = phydev->attached_dev;

if (up)
netif_carrier_on(netdev);
else
netif_carrier_off(netdev);
phydev->adjust_link(netdev);
if (phydev->mii_ts && phydev->mii_ts->link_state)
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
}

/**
* phy_uses_state_machine - test whether consumer driver uses PAL state machine
* @phydev: the target PHY device structure
*
* Ultimately, this aims to indirectly determine whether the PHY is attached
* to a consumer which uses the state machine by calling phy_start() and
* phy_stop().
*
* When the PHY driver consumer uses phylib, it must have previously called
* phy_connect_direct() or one of its derivatives, so that phy_prepare_link()
* has set up a hook for monitoring state changes.
*
* When the PHY driver is used by the MAC driver consumer through phylink (the
* only other provider of a phy_link_change() method), using the PHY state
* machine is not optional.
*
* Return: true if consumer calls phy_start() and phy_stop(), false otherwise.
*/
static bool phy_uses_state_machine(struct phy_device *phydev)
{
if (phydev->phy_link_change == phy_link_change)
return phydev->attached_dev && phydev->adjust_link;

/* phydev->phy_link_change is implicitly phylink_phy_change() */
return true;
}

static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
{
struct device_driver *drv = phydev->mdio.dev.driver;
Expand Down Expand Up @@ -310,7 +350,7 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
* may call phy routines that try to grab the same lock, and that may
* lead to a deadlock.
*/
if (phydev->attached_dev && phydev->adjust_link)
if (phy_uses_state_machine(phydev))
phy_stop_machine(phydev);

if (!mdio_bus_phy_may_suspend(phydev))
Expand Down Expand Up @@ -364,7 +404,7 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
}
}

if (phydev->attached_dev && phydev->adjust_link)
if (phy_uses_state_machine(phydev))
phy_start_machine(phydev);

return 0;
Expand Down Expand Up @@ -1055,19 +1095,6 @@ struct phy_device *phy_find_first(struct mii_bus *bus)
}
EXPORT_SYMBOL(phy_find_first);

static void phy_link_change(struct phy_device *phydev, bool up)
{
struct net_device *netdev = phydev->attached_dev;

if (up)
netif_carrier_on(netdev);
else
netif_carrier_off(netdev);
phydev->adjust_link(netdev);
if (phydev->mii_ts && phydev->mii_ts->link_state)
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
}

/**
* phy_prepare_link - prepares the PHY layer to monitor link status
* @phydev: target phy_device struct
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ppp/ppp_synctty.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)
unsigned char *data;
int islcp;

/* Ensure we can safely access protocol field and LCP code */
if (!pskb_may_pull(skb, 3)) {
kfree_skb(skb);
return NULL;
}
data = skb->data;
proto = get_unaligned_be16(data);

Expand Down
2 changes: 2 additions & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -4429,6 +4429,7 @@ void linkwatch_fire_event(struct net_device *dev);
* pending work list (if queued).
*/
void linkwatch_sync_dev(struct net_device *dev);
void __linkwatch_sync_dev(struct net_device *dev);

/**
* netif_carrier_ok - test if carrier present
Expand Down Expand Up @@ -4974,6 +4975,7 @@ void dev_set_rx_mode(struct net_device *dev);
int dev_set_promiscuity(struct net_device *dev, int inc);
int netif_set_allmulti(struct net_device *dev, int inc, bool notify);
int dev_set_allmulti(struct net_device *dev, int inc);
void netif_state_change(struct net_device *dev);
void netdev_state_change(struct net_device *dev);
void __netdev_notify_peers(struct net_device *dev);
void netdev_notify_peers(struct net_device *dev);
Expand Down
2 changes: 1 addition & 1 deletion include/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,6 @@ rtnl_notify_needed(const struct net *net, u16 nlflags, u32 group)
return (nlflags & NLM_F_ECHO) || rtnl_has_listeners(net, group);
}

void netdev_set_operstate(struct net_device *dev, int newstate);
void netif_set_operstate(struct net_device *dev, int newstate);

#endif /* __LINUX_RTNETLINK_H */
3 changes: 2 additions & 1 deletion include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ struct sctp_transport {

/* Reference counting. */
refcount_t refcnt;
__u32 dead:1,
/* RTO-Pending : A flag used to track if one of the DATA
* chunks sent to this address is currently being
* used to compute a RTT. If this flag is 0,
Expand All @@ -784,7 +785,7 @@ struct sctp_transport {
* calculation completes (i.e. the DATA chunk
* is SACK'd) clear this flag.
*/
__u32 rto_pending:1,
rto_pending:1,

/*
* hb_sent : a flag that signals that we have a pending
Expand Down
40 changes: 38 additions & 2 deletions include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ struct sk_filter;
* @sk_txtime_unused: unused txtime flags
* @ns_tracker: tracker for netns reference
* @sk_user_frags: xarray of pages the user is holding a reference on.
* @sk_owner: reference to the real owner of the socket that calls
* sock_lock_init_class_and_name().
*/
struct sock {
/*
Expand Down Expand Up @@ -547,6 +549,10 @@ struct sock {
struct rcu_head sk_rcu;
netns_tracker ns_tracker;
struct xarray sk_user_frags;

#if IS_ENABLED(CONFIG_PROVE_LOCKING) && IS_ENABLED(CONFIG_MODULES)
struct module *sk_owner;
#endif
};

struct sock_bh_locked {
Expand Down Expand Up @@ -1583,6 +1589,35 @@ static inline void sk_mem_uncharge(struct sock *sk, int size)
sk_mem_reclaim(sk);
}

#if IS_ENABLED(CONFIG_PROVE_LOCKING) && IS_ENABLED(CONFIG_MODULES)
static inline void sk_owner_set(struct sock *sk, struct module *owner)
{
__module_get(owner);
sk->sk_owner = owner;
}

static inline void sk_owner_clear(struct sock *sk)
{
sk->sk_owner = NULL;
}

static inline void sk_owner_put(struct sock *sk)
{
module_put(sk->sk_owner);
}
#else
static inline void sk_owner_set(struct sock *sk, struct module *owner)
{
}

static inline void sk_owner_clear(struct sock *sk)
{
}

static inline void sk_owner_put(struct sock *sk)
{
}
#endif
/*
* Macro so as to not evaluate some arguments when
* lockdep is not enabled.
Expand All @@ -1592,13 +1627,14 @@ static inline void sk_mem_uncharge(struct sock *sk, int size)
*/
#define sock_lock_init_class_and_name(sk, sname, skey, name, key) \
do { \
sk_owner_set(sk, THIS_MODULE); \
sk->sk_lock.owned = 0; \
init_waitqueue_head(&sk->sk_lock.wq); \
spin_lock_init(&(sk)->sk_lock.slock); \
debug_check_no_locks_freed((void *)&(sk)->sk_lock, \
sizeof((sk)->sk_lock)); \
sizeof((sk)->sk_lock)); \
lockdep_set_class_and_name(&(sk)->sk_lock.slock, \
(skey), (sname)); \
(skey), (sname)); \
lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0); \
} while (0)

Expand Down
11 changes: 1 addition & 10 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1518,15 +1518,7 @@ void netdev_features_change(struct net_device *dev)
}
EXPORT_SYMBOL(netdev_features_change);

/**
* netdev_state_change - device changes state
* @dev: device to cause notification
*
* Called to indicate a device has changed state. This function calls
* the notifier chains for netdev_chain and sends a NEWLINK message
* to the routing socket.
*/
void netdev_state_change(struct net_device *dev)
void netif_state_change(struct net_device *dev)
{
if (dev->flags & IFF_UP) {
struct netdev_notifier_change_info change_info = {
Expand All @@ -1538,7 +1530,6 @@ void netdev_state_change(struct net_device *dev)
rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL, 0, NULL);
}
}
EXPORT_SYMBOL(netdev_state_change);

/**
* __netdev_notify_peers - notify network peers about existence of @dev,
Expand Down
16 changes: 16 additions & 0 deletions net/core/dev_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,19 @@ int dev_xdp_propagate(struct net_device *dev, struct netdev_bpf *bpf)
return ret;
}
EXPORT_SYMBOL_GPL(dev_xdp_propagate);

/**
* netdev_state_change() - device changes state
* @dev: device to cause notification
*
* Called to indicate a device has changed state. This function calls
* the notifier chains for netdev_chain and sends a NEWLINK message
* to the routing socket.
*/
void netdev_state_change(struct net_device *dev)
{
netdev_lock_ops(dev);
netif_state_change(dev);
netdev_unlock_ops(dev);
}
EXPORT_SYMBOL(netdev_state_change);
28 changes: 23 additions & 5 deletions net/core/link_watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ static void linkwatch_do_dev(struct net_device *dev)
else
dev_deactivate(dev);

netdev_state_change(dev);
netif_state_change(dev);
}
/* Note: our callers are responsible for calling netdev_tracker_free().
* This is the reason we use __dev_put() instead of dev_put().
Expand Down Expand Up @@ -240,7 +240,9 @@ static void __linkwatch_run_queue(int urgent_only)
*/
netdev_tracker_free(dev, &dev->linkwatch_dev_tracker);
spin_unlock_irq(&lweventlist_lock);
netdev_lock_ops(dev);
linkwatch_do_dev(dev);
netdev_unlock_ops(dev);
do_dev--;
spin_lock_irq(&lweventlist_lock);
}
Expand All @@ -253,25 +255,41 @@ static void __linkwatch_run_queue(int urgent_only)
spin_unlock_irq(&lweventlist_lock);
}

void linkwatch_sync_dev(struct net_device *dev)
static bool linkwatch_clean_dev(struct net_device *dev)
{
unsigned long flags;
int clean = 0;
bool clean = false;

spin_lock_irqsave(&lweventlist_lock, flags);
if (!list_empty(&dev->link_watch_list)) {
list_del_init(&dev->link_watch_list);
clean = 1;
clean = true;
/* We must release netdev tracker under
* the spinlock protection.
*/
netdev_tracker_free(dev, &dev->linkwatch_dev_tracker);
}
spin_unlock_irqrestore(&lweventlist_lock, flags);
if (clean)

return clean;
}

void __linkwatch_sync_dev(struct net_device *dev)
{
netdev_ops_assert_locked(dev);

if (linkwatch_clean_dev(dev))
linkwatch_do_dev(dev);
}

void linkwatch_sync_dev(struct net_device *dev)
{
if (linkwatch_clean_dev(dev)) {
netdev_lock_ops(dev);
linkwatch_do_dev(dev);
netdev_unlock_ops(dev);
}
}

/* Must be called with the rtnl semaphore held */
void linkwatch_run_queue(void)
Expand Down
Loading

0 comments on commit ab59a86

Please sign in to comment.