mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
Including fixes from Bluetooth.
Current release - regressions: - tcp: refine sk_rcvbuf increase for ooo packets - bluetooth: fix attempting to send HCI_Disconnect to BIS handle - rxrpc: fix over large frame size warning - eth: bcmgenet: initialize u64 stats seq counter Previous releases - regressions: - tcp: correct signedness in skb remaining space calculation - sched: abort __tc_modify_qdisc if parent class does not exist - vsock: fix transport_{g2h,h2g} TOCTOU - rxrpc: fix bug due to prealloc collision - tipc: fix use-after-free in tipc_conn_close(). - bluetooth: fix not marking Broadcast Sink BIS as connected - phy: qca808x: fix WoL issue by utilizing at8031_set_wol() - eth: am65-cpsw-nuss: fix skb size by accounting for skb_shared_info Previous releases - always broken: - netlink: fix wraparounds of sk->sk_rmem_alloc. - atm: fix infinite recursive call of clip_push(). - eth: stmmac: fix interrupt handling for level-triggered mode in DWC_XGMAC2 - eth: rtsn: fix a null pointer dereference in rtsn_probe() Signed-off-by: Paolo Abeni <pabeni@redhat.com> -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmhvtRwSHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOke6wP/iqvFgmSTHwmp+KvgV2RooqPcspstVM4 hiQ4UkdtShGzfnf+YulpNgXTefVvzPpJ+yqMr+Kh5+I5rxCdE7rmm7jnwa7w3rK1 3LpvwWPRbZB4FNBY3RusipbWaWmH+OW1kmXNSZ2GQJVydWlk4ebW0EES1ryQWTvh XdA6/w+qrlpBPxk7gP8ySrxOPm817o5O1FYZfRi1HaOKKmRVcxAupaiS3dkIMRIu 6zKlrg83mnD0AkO5c4fILZxo3rrmYM94uTxxIezxfsDfL4PHiWbZjuIe53qJaraO FBC1GZ+dsqRXwIxdBvLixeWJxVpJs9ZpWTj+aIOkOU+voYRMDP41/NhDZv8Xy1BT p5u0kjwOLIF+ELw63+klGYku9LWQpxYNnRNqRTBSbIu4rQTPgNkpi38NOgwt2sPE u3p68nK78WMEj6eAHws6bkS/udaQD9TqR1Kgt27vHz/LakdyTTanELtsN6rK6wdp dwX09rEQJk1QsWCd3vW5OHQMep7qhMBtCtqkuMNZlzt6PjzNpDNjKnued5qNn95i nw/mdZI2WtvbkTDLioNOb9UuaqMUT2G1MCl2ywUNcPTNK8nPNOjIS9KVCkkMrLfk +NvdXO94iz7l5Wlxd6/c9LA+8kHgWaZFD5PEE0ApvfEi/FyRLSMxnmWOHE6vRCEk 1+AwFSWWM3/X =GD9v -----END PGP SIGNATURE----- Merge tag 'net-6.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from Bluetooth. Current release - regressions: - tcp: refine sk_rcvbuf increase for ooo packets - bluetooth: fix attempting to send HCI_Disconnect to BIS handle - rxrpc: fix over large frame size warning - eth: bcmgenet: initialize u64 stats seq counter Previous releases - regressions: - tcp: correct signedness in skb remaining space calculation - sched: abort __tc_modify_qdisc if parent class does not exist - vsock: fix transport_{g2h,h2g} TOCTOU - rxrpc: fix bug due to prealloc collision - tipc: fix use-after-free in tipc_conn_close(). - bluetooth: fix not marking Broadcast Sink BIS as connected - phy: qca808x: fix WoL issue by utilizing at8031_set_wol() - eth: am65-cpsw-nuss: fix skb size by accounting for skb_shared_info Previous releases - always broken: - netlink: fix wraparounds of sk->sk_rmem_alloc. - atm: fix infinite recursive call of clip_push(). - eth: - stmmac: fix interrupt handling for level-triggered mode in DWC_XGMAC2 - rtsn: fix a null pointer dereference in rtsn_probe()" * tag 'net-6.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (37 commits) net/sched: sch_qfq: Fix null-deref in agg_dequeue rxrpc: Fix oops due to non-existence of prealloc backlog struct rxrpc: Fix bug due to prealloc collision MAINTAINERS: remove myself as netronome maintainer selftests/net: packetdrill: add tcp_ooo-before-and-after-accept.pkt tcp: refine sk_rcvbuf increase for ooo packets net/sched: Abort __tc_modify_qdisc if parent class does not exist net: ethernet: ti: am65-cpsw-nuss: Fix skb size by accounting for skb_shared_info net: thunderx: avoid direct MTU assignment after WRITE_ONCE() selftests/tc-testing: Create test case for UAF scenario with DRR/NETEM/BLACKHOLE chain atm: clip: Fix NULL pointer dereference in vcc_sendmsg() atm: clip: Fix infinite recursive call of clip_push(). atm: clip: Fix memory leak of struct clip_vcc. atm: clip: Fix potential null-ptr-deref in to_atmarpd(). net: phy: smsc: Fix link failure in forced mode with Auto-MDIX net: phy: smsc: Force predictable MDI-X state on LAN87xx net: phy: smsc: Fix Auto-MDIX configuration when disabled by strap net: stmmac: Fix interrupt handling for level-triggered mode in DWC_XGMAC2 rxrpc: Fix over large frame size warning net: airoha: Fix an error handling path in airoha_probe() ...
This commit is contained in:
commit
bc9ff192a6
|
@ -23,7 +23,7 @@ properties:
|
|||
- allwinner,sun20i-d1-emac
|
||||
- allwinner,sun50i-h6-emac
|
||||
- allwinner,sun50i-h616-emac0
|
||||
- allwinner,sun55i-a523-emac0
|
||||
- allwinner,sun55i-a523-gmac0
|
||||
- const: allwinner,sun50i-a64-emac
|
||||
|
||||
reg:
|
||||
|
|
|
@ -17224,10 +17224,10 @@ F: drivers/rtc/rtc-ntxec.c
|
|||
F: include/linux/mfd/ntxec.h
|
||||
|
||||
NETRONOME ETHERNET DRIVERS
|
||||
M: Louis Peens <louis.peens@corigine.com>
|
||||
R: Jakub Kicinski <kuba@kernel.org>
|
||||
R: Simon Horman <horms@kernel.org>
|
||||
L: oss-drivers@corigine.com
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: drivers/net/ethernet/netronome/
|
||||
|
||||
NETWORK BLOCK DEVICE (NBD)
|
||||
|
|
|
@ -2984,6 +2984,7 @@ static int airoha_probe(struct platform_device *pdev)
|
|||
error_napi_stop:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_stop_napi(ð->qdma[i]);
|
||||
airoha_ppe_deinit(eth);
|
||||
error_hw_cleanup:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_hw_cleanup(ð->qdma[i]);
|
||||
|
|
|
@ -11607,11 +11607,9 @@ static void bnxt_free_irq(struct bnxt *bp)
|
|||
|
||||
static int bnxt_request_irq(struct bnxt *bp)
|
||||
{
|
||||
struct cpu_rmap *rmap = NULL;
|
||||
int i, j, rc = 0;
|
||||
unsigned long flags = 0;
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
struct cpu_rmap *rmap;
|
||||
#endif
|
||||
|
||||
rc = bnxt_setup_int_mode(bp);
|
||||
if (rc) {
|
||||
|
@ -11632,15 +11630,15 @@ static int bnxt_request_irq(struct bnxt *bp)
|
|||
int map_idx = bnxt_cp_num_to_irq_num(bp, i);
|
||||
struct bnxt_irq *irq = &bp->irq_tbl[map_idx];
|
||||
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
if (rmap && bp->bnapi[i]->rx_ring) {
|
||||
if (IS_ENABLED(CONFIG_RFS_ACCEL) &&
|
||||
rmap && bp->bnapi[i]->rx_ring) {
|
||||
rc = irq_cpu_rmap_add(rmap, irq->vector);
|
||||
if (rc)
|
||||
netdev_warn(bp->dev, "failed adding irq rmap for ring %d\n",
|
||||
j);
|
||||
j++;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = request_irq(irq->vector, irq->handler, flags, irq->name,
|
||||
bp->bnapi[i]);
|
||||
if (rc)
|
||||
|
|
|
@ -4092,6 +4092,12 @@ static int bcmgenet_probe(struct platform_device *pdev)
|
|||
for (i = 0; i <= priv->hw_params->rx_queues; i++)
|
||||
priv->rx_rings[i].rx_max_coalesced_frames = 1;
|
||||
|
||||
/* Initialize u64 stats seq counter for 32bit machines */
|
||||
for (i = 0; i <= priv->hw_params->rx_queues; i++)
|
||||
u64_stats_init(&priv->rx_rings[i].stats64.syncp);
|
||||
for (i = 0; i <= priv->hw_params->tx_queues; i++)
|
||||
u64_stats_init(&priv->tx_rings[i].stats64.syncp);
|
||||
|
||||
/* libphy will determine the link state */
|
||||
netif_carrier_off(dev);
|
||||
|
||||
|
|
|
@ -1578,7 +1578,6 @@ napi_del:
|
|||
static int nicvf_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
{
|
||||
struct nicvf *nic = netdev_priv(netdev);
|
||||
int orig_mtu = netdev->mtu;
|
||||
|
||||
/* For now just support only the usual MTU sized frames,
|
||||
* plus some headroom for VLAN, QinQ.
|
||||
|
@ -1589,15 +1588,10 @@ static int nicvf_change_mtu(struct net_device *netdev, int new_mtu)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
WRITE_ONCE(netdev->mtu, new_mtu);
|
||||
|
||||
if (!netif_running(netdev))
|
||||
return 0;
|
||||
|
||||
if (nicvf_update_hw_max_frs(nic, new_mtu)) {
|
||||
netdev->mtu = orig_mtu;
|
||||
if (netif_running(netdev) && nicvf_update_hw_max_frs(nic, new_mtu))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WRITE_ONCE(netdev->mtu, new_mtu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1259,7 +1259,12 @@ static int rtsn_probe(struct platform_device *pdev)
|
|||
priv = netdev_priv(ndev);
|
||||
priv->pdev = pdev;
|
||||
priv->ndev = ndev;
|
||||
|
||||
priv->ptp_priv = rcar_gen4_ptp_alloc(pdev);
|
||||
if (!priv->ptp_priv) {
|
||||
ret = -ENOMEM;
|
||||
goto error_free;
|
||||
}
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
|
|
@ -364,19 +364,17 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
|
|||
}
|
||||
|
||||
/* TX/RX NORMAL interrupts */
|
||||
if (likely(intr_status & XGMAC_NIS)) {
|
||||
if (likely(intr_status & XGMAC_RI)) {
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
u64_stats_inc(&stats->rx_normal_irq_n[chan]);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
ret |= handle_rx;
|
||||
}
|
||||
if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
u64_stats_inc(&stats->tx_normal_irq_n[chan]);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
ret |= handle_tx;
|
||||
}
|
||||
if (likely(intr_status & XGMAC_RI)) {
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
u64_stats_inc(&stats->rx_normal_irq_n[chan]);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
ret |= handle_rx;
|
||||
}
|
||||
if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
u64_stats_inc(&stats->tx_normal_irq_n[chan]);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
ret |= handle_tx;
|
||||
}
|
||||
|
||||
/* Clear interrupts */
|
||||
|
|
|
@ -856,8 +856,6 @@ static struct sk_buff *am65_cpsw_build_skb(void *page_addr,
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
len += AM65_CPSW_HEADROOM;
|
||||
|
||||
skb = build_skb(page_addr, len);
|
||||
if (unlikely(!skb))
|
||||
return NULL;
|
||||
|
@ -1344,7 +1342,7 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow,
|
|||
}
|
||||
|
||||
skb = am65_cpsw_build_skb(page_addr, ndev,
|
||||
AM65_CPSW_MAX_PACKET_SIZE, headroom);
|
||||
PAGE_SIZE, headroom);
|
||||
if (unlikely(!skb)) {
|
||||
new_page = page;
|
||||
goto requeue;
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
|
||||
#define AT803X_LED_CONTROL 0x18
|
||||
|
||||
#define AT803X_PHY_MMD3_WOL_CTRL 0x8012
|
||||
#define AT803X_WOL_EN BIT(5)
|
||||
|
||||
#define AT803X_REG_CHIP_CONFIG 0x1f
|
||||
#define AT803X_BT_BX_REG_SEL 0x8000
|
||||
|
||||
|
@ -866,30 +863,6 @@ static int at8031_config_init(struct phy_device *phydev)
|
|||
return at803x_config_init(phydev);
|
||||
}
|
||||
|
||||
static int at8031_set_wol(struct phy_device *phydev,
|
||||
struct ethtool_wolinfo *wol)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* First setup MAC address and enable WOL interrupt */
|
||||
ret = at803x_set_wol(phydev, wol);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (wol->wolopts & WAKE_MAGIC)
|
||||
/* Enable WOL function for 1588 */
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
AT803X_PHY_MMD3_WOL_CTRL,
|
||||
0, AT803X_WOL_EN);
|
||||
else
|
||||
/* Disable WoL function for 1588 */
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
AT803X_PHY_MMD3_WOL_CTRL,
|
||||
AT803X_WOL_EN, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int at8031_config_intr(struct phy_device *phydev)
|
||||
{
|
||||
struct at803x_priv *priv = phydev->priv;
|
||||
|
|
|
@ -633,7 +633,7 @@ static struct phy_driver qca808x_driver[] = {
|
|||
.handle_interrupt = at803x_handle_interrupt,
|
||||
.get_tunable = at803x_get_tunable,
|
||||
.set_tunable = at803x_set_tunable,
|
||||
.set_wol = at803x_set_wol,
|
||||
.set_wol = at8031_set_wol,
|
||||
.get_wol = at803x_get_wol,
|
||||
.get_features = qca808x_get_features,
|
||||
.config_aneg = qca808x_config_aneg,
|
||||
|
|
|
@ -115,6 +115,31 @@ int at803x_set_wol(struct phy_device *phydev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(at803x_set_wol);
|
||||
|
||||
int at8031_set_wol(struct phy_device *phydev,
|
||||
struct ethtool_wolinfo *wol)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* First setup MAC address and enable WOL interrupt */
|
||||
ret = at803x_set_wol(phydev, wol);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (wol->wolopts & WAKE_MAGIC)
|
||||
/* Enable WOL function for 1588 */
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
AT803X_PHY_MMD3_WOL_CTRL,
|
||||
0, AT803X_WOL_EN);
|
||||
else
|
||||
/* Disable WoL function for 1588 */
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
AT803X_PHY_MMD3_WOL_CTRL,
|
||||
AT803X_WOL_EN, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(at8031_set_wol);
|
||||
|
||||
void at803x_get_wol(struct phy_device *phydev,
|
||||
struct ethtool_wolinfo *wol)
|
||||
{
|
||||
|
|
|
@ -172,6 +172,9 @@
|
|||
#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
|
||||
#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A
|
||||
|
||||
#define AT803X_PHY_MMD3_WOL_CTRL 0x8012
|
||||
#define AT803X_WOL_EN BIT(5)
|
||||
|
||||
#define AT803X_DEBUG_ADDR 0x1D
|
||||
#define AT803X_DEBUG_DATA 0x1E
|
||||
|
||||
|
@ -215,6 +218,8 @@ int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
|
|||
int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data);
|
||||
int at803x_set_wol(struct phy_device *phydev,
|
||||
struct ethtool_wolinfo *wol);
|
||||
int at8031_set_wol(struct phy_device *phydev,
|
||||
struct ethtool_wolinfo *wol);
|
||||
void at803x_get_wol(struct phy_device *phydev,
|
||||
struct ethtool_wolinfo *wol);
|
||||
int at803x_ack_interrupt(struct phy_device *phydev);
|
||||
|
|
|
@ -155,10 +155,29 @@ static int smsc_phy_reset(struct phy_device *phydev)
|
|||
|
||||
static int lan87xx_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
u8 mdix_ctrl;
|
||||
int val;
|
||||
int rc;
|
||||
|
||||
switch (phydev->mdix_ctrl) {
|
||||
/* When auto-negotiation is disabled (forced mode), the PHY's
|
||||
* Auto-MDIX will continue toggling the TX/RX pairs.
|
||||
*
|
||||
* To establish a stable link, we must select a fixed MDI mode.
|
||||
* If the user has not specified a fixed MDI mode (i.e., mdix_ctrl is
|
||||
* 'auto'), we default to ETH_TP_MDI. This choice of a ETH_TP_MDI mode
|
||||
* mirrors the behavior the hardware would exhibit if the AUTOMDIX_EN
|
||||
* strap were configured for a fixed MDI connection.
|
||||
*/
|
||||
if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
if (phydev->mdix_ctrl == ETH_TP_MDI_AUTO)
|
||||
mdix_ctrl = ETH_TP_MDI;
|
||||
else
|
||||
mdix_ctrl = phydev->mdix_ctrl;
|
||||
} else {
|
||||
mdix_ctrl = phydev->mdix_ctrl;
|
||||
}
|
||||
|
||||
switch (mdix_ctrl) {
|
||||
case ETH_TP_MDI:
|
||||
val = SPECIAL_CTRL_STS_OVRRD_AMDIX_;
|
||||
break;
|
||||
|
@ -167,7 +186,8 @@ static int lan87xx_config_aneg(struct phy_device *phydev)
|
|||
SPECIAL_CTRL_STS_AMDIX_STATE_;
|
||||
break;
|
||||
case ETH_TP_MDI_AUTO:
|
||||
val = SPECIAL_CTRL_STS_AMDIX_ENABLE_;
|
||||
val = SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
|
||||
SPECIAL_CTRL_STS_AMDIX_ENABLE_;
|
||||
break;
|
||||
default:
|
||||
return genphy_config_aneg(phydev);
|
||||
|
@ -183,7 +203,7 @@ static int lan87xx_config_aneg(struct phy_device *phydev)
|
|||
rc |= val;
|
||||
phy_write(phydev, SPECIAL_CTRL_STS, rc);
|
||||
|
||||
phydev->mdix = phydev->mdix_ctrl;
|
||||
phydev->mdix = mdix_ctrl;
|
||||
return genphy_config_aneg(phydev);
|
||||
}
|
||||
|
||||
|
@ -261,6 +281,33 @@ int lan87xx_read_status(struct phy_device *phydev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(lan87xx_read_status);
|
||||
|
||||
static int lan87xx_phy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* The LAN87xx PHY's initial MDI-X mode is determined by the AUTOMDIX_EN
|
||||
* hardware strap, but the driver cannot read the strap's status. This
|
||||
* creates an unpredictable initial state.
|
||||
*
|
||||
* To ensure consistent and reliable behavior across all boards,
|
||||
* override the strap configuration on initialization and force the PHY
|
||||
* into a known state with Auto-MDIX enabled, which is the expected
|
||||
* default for modern hardware.
|
||||
*/
|
||||
rc = phy_modify(phydev, SPECIAL_CTRL_STS,
|
||||
SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
|
||||
SPECIAL_CTRL_STS_AMDIX_ENABLE_ |
|
||||
SPECIAL_CTRL_STS_AMDIX_STATE_,
|
||||
SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
|
||||
SPECIAL_CTRL_STS_AMDIX_ENABLE_);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
|
||||
|
||||
return smsc_phy_config_init(phydev);
|
||||
}
|
||||
|
||||
static int lan874x_phy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
u16 val;
|
||||
|
@ -695,7 +742,7 @@ static struct phy_driver smsc_phy_driver[] = {
|
|||
|
||||
/* basic functions */
|
||||
.read_status = lan87xx_read_status,
|
||||
.config_init = smsc_phy_config_init,
|
||||
.config_init = lan87xx_phy_config_init,
|
||||
.soft_reset = smsc_phy_reset,
|
||||
.config_aneg = lan87xx_config_aneg,
|
||||
|
||||
|
|
|
@ -243,8 +243,8 @@ int __vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||
int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
size_t len, int flags);
|
||||
|
||||
#ifdef CONFIG_BPF_SYSCALL
|
||||
extern struct proto vsock_proto;
|
||||
#ifdef CONFIG_BPF_SYSCALL
|
||||
int vsock_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore);
|
||||
void __init vsock_bpf_build_proto(void);
|
||||
#else
|
||||
|
|
|
@ -1350,8 +1350,7 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state)
|
|||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(c, &h->list, list) {
|
||||
if (c->type != BIS_LINK || bacmp(&c->dst, BDADDR_ANY) ||
|
||||
c->state != state)
|
||||
if (c->type != BIS_LINK || c->state != state)
|
||||
continue;
|
||||
|
||||
if (handle == c->iso_qos.bcast.big) {
|
||||
|
|
|
@ -114,7 +114,6 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
|
|||
struct netlink_ext_ack *extack);
|
||||
void qdisc_put_rtab(struct qdisc_rate_table *tab);
|
||||
void qdisc_put_stab(struct qdisc_size_table *tab);
|
||||
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
|
||||
bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
|
||||
struct net_device *dev, struct netdev_queue *txq,
|
||||
spinlock_t *root_lock, bool validate);
|
||||
|
@ -290,4 +289,28 @@ static inline bool tc_qdisc_stats_dump(struct Qdisc *sch,
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
|
||||
{
|
||||
if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
|
||||
pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
|
||||
txt, qdisc->ops->id, qdisc->handle >> 16);
|
||||
qdisc->flags |= TCQ_F_WARN_NONWC;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int qdisc_peek_len(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
skb = sch->ops->peek(sch);
|
||||
if (unlikely(skb == NULL)) {
|
||||
qdisc_warn_nonwc("qdisc_peek_len", sch);
|
||||
return 0;
|
||||
}
|
||||
len = qdisc_pkt_len(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
#include <net/atmclip.h>
|
||||
|
||||
static struct net_device *clip_devs;
|
||||
static struct atm_vcc *atmarpd;
|
||||
static struct atm_vcc __rcu *atmarpd;
|
||||
static DEFINE_MUTEX(atmarpd_lock);
|
||||
static struct timer_list idle_timer;
|
||||
static const struct neigh_ops clip_neigh_ops;
|
||||
|
||||
|
@ -53,24 +54,35 @@ static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
|
|||
{
|
||||
struct sock *sk;
|
||||
struct atmarp_ctrl *ctrl;
|
||||
struct atm_vcc *vcc;
|
||||
struct sk_buff *skb;
|
||||
int err = 0;
|
||||
|
||||
pr_debug("(%d)\n", type);
|
||||
if (!atmarpd)
|
||||
return -EUNATCH;
|
||||
|
||||
rcu_read_lock();
|
||||
vcc = rcu_dereference(atmarpd);
|
||||
if (!vcc) {
|
||||
err = -EUNATCH;
|
||||
goto unlock;
|
||||
}
|
||||
skb = alloc_skb(sizeof(struct atmarp_ctrl), GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
if (!skb) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
ctrl = skb_put(skb, sizeof(struct atmarp_ctrl));
|
||||
ctrl->type = type;
|
||||
ctrl->itf_num = itf;
|
||||
ctrl->ip = ip;
|
||||
atm_force_charge(atmarpd, skb->truesize);
|
||||
atm_force_charge(vcc, skb->truesize);
|
||||
|
||||
sk = sk_atm(atmarpd);
|
||||
sk = sk_atm(vcc);
|
||||
skb_queue_tail(&sk->sk_receive_queue, skb);
|
||||
sk->sk_data_ready(sk);
|
||||
return 0;
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
|
||||
|
@ -417,6 +429,8 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
|
|||
|
||||
if (!vcc->push)
|
||||
return -EBADFD;
|
||||
if (vcc->user_back)
|
||||
return -EINVAL;
|
||||
clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL);
|
||||
if (!clip_vcc)
|
||||
return -ENOMEM;
|
||||
|
@ -607,17 +621,27 @@ static void atmarpd_close(struct atm_vcc *vcc)
|
|||
{
|
||||
pr_debug("\n");
|
||||
|
||||
rtnl_lock();
|
||||
atmarpd = NULL;
|
||||
mutex_lock(&atmarpd_lock);
|
||||
RCU_INIT_POINTER(atmarpd, NULL);
|
||||
mutex_unlock(&atmarpd_lock);
|
||||
|
||||
synchronize_rcu();
|
||||
skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
|
||||
rtnl_unlock();
|
||||
|
||||
pr_debug("(done)\n");
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
static int atmarpd_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
atm_return_tx(vcc, skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct atmdev_ops atmarpd_dev_ops = {
|
||||
.close = atmarpd_close
|
||||
.close = atmarpd_close,
|
||||
.send = atmarpd_send
|
||||
};
|
||||
|
||||
|
||||
|
@ -631,15 +655,18 @@ static struct atm_dev atmarpd_dev = {
|
|||
|
||||
static int atm_init_atmarp(struct atm_vcc *vcc)
|
||||
{
|
||||
rtnl_lock();
|
||||
if (vcc->push == clip_push)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&atmarpd_lock);
|
||||
if (atmarpd) {
|
||||
rtnl_unlock();
|
||||
mutex_unlock(&atmarpd_lock);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
|
||||
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
|
||||
|
||||
atmarpd = vcc;
|
||||
rcu_assign_pointer(atmarpd, vcc);
|
||||
set_bit(ATM_VF_META, &vcc->flags);
|
||||
set_bit(ATM_VF_READY, &vcc->flags);
|
||||
/* allow replies and avoid getting closed if signaling dies */
|
||||
|
@ -648,13 +675,14 @@ static int atm_init_atmarp(struct atm_vcc *vcc)
|
|||
vcc->push = NULL;
|
||||
vcc->pop = NULL; /* crash */
|
||||
vcc->push_oam = NULL; /* crash */
|
||||
rtnl_unlock();
|
||||
mutex_unlock(&atmarpd_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct atm_vcc *vcc = ATM_SD(sock);
|
||||
struct sock *sk = sock->sk;
|
||||
int err = 0;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -675,14 +703,18 @@ static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||
err = clip_create(arg);
|
||||
break;
|
||||
case ATMARPD_CTRL:
|
||||
lock_sock(sk);
|
||||
err = atm_init_atmarp(vcc);
|
||||
if (!err) {
|
||||
sock->state = SS_CONNECTED;
|
||||
__module_get(THIS_MODULE);
|
||||
}
|
||||
release_sock(sk);
|
||||
break;
|
||||
case ATMARP_MKIP:
|
||||
lock_sock(sk);
|
||||
err = clip_mkip(vcc, arg);
|
||||
release_sock(sk);
|
||||
break;
|
||||
case ATMARP_SETENTRY:
|
||||
err = clip_setentry(vcc, (__force __be32)arg);
|
||||
|
|
|
@ -6966,7 +6966,10 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
|
|||
bis->iso_qos.bcast.in.sdu = le16_to_cpu(ev->max_pdu);
|
||||
|
||||
if (!ev->status) {
|
||||
bis->state = BT_CONNECTED;
|
||||
set_bit(HCI_CONN_BIG_SYNC, &bis->flags);
|
||||
hci_debugfs_create_conn(bis);
|
||||
hci_conn_add_sysfs(bis);
|
||||
hci_iso_setup_path(bis);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1345,7 +1345,7 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
|
|||
* Command Disallowed error, so we must first disable the
|
||||
* instance if it is active.
|
||||
*/
|
||||
if (adv && !adv->pending) {
|
||||
if (adv) {
|
||||
err = hci_disable_ext_adv_instance_sync(hdev, instance);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -5493,7 +5493,7 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
|
|||
{
|
||||
struct hci_cp_disconnect cp;
|
||||
|
||||
if (test_bit(HCI_CONN_BIG_CREATED, &conn->flags)) {
|
||||
if (conn->type == BIS_LINK) {
|
||||
/* This is a BIS connection, hci_conn_del will
|
||||
* do the necessary cleanup.
|
||||
*/
|
||||
|
|
|
@ -1176,7 +1176,7 @@ restart:
|
|||
goto do_error;
|
||||
|
||||
while (msg_data_left(msg)) {
|
||||
ssize_t copy = 0;
|
||||
int copy = 0;
|
||||
|
||||
skb = tcp_write_queue_tail(sk);
|
||||
if (skb)
|
||||
|
|
|
@ -5181,7 +5181,9 @@ end:
|
|||
skb_condense(skb);
|
||||
skb_set_owner_r(skb, sk);
|
||||
}
|
||||
tcp_rcvbuf_grow(sk);
|
||||
/* do not grow rcvbuf for not-yet-accepted or orphaned sockets. */
|
||||
if (sk->sk_socket)
|
||||
tcp_rcvbuf_grow(sk);
|
||||
}
|
||||
|
||||
static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb,
|
||||
|
|
|
@ -387,7 +387,6 @@ static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
|
|||
WARN_ON(skb->sk != NULL);
|
||||
skb->sk = sk;
|
||||
skb->destructor = netlink_skb_destructor;
|
||||
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
|
||||
sk_mem_charge(sk, skb->truesize);
|
||||
}
|
||||
|
||||
|
@ -1212,41 +1211,48 @@ struct sk_buff *netlink_alloc_large_skb(unsigned int size, int broadcast)
|
|||
int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
|
||||
long *timeo, struct sock *ssk)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
struct netlink_sock *nlk;
|
||||
unsigned int rmem;
|
||||
|
||||
nlk = nlk_sk(sk);
|
||||
rmem = atomic_add_return(skb->truesize, &sk->sk_rmem_alloc);
|
||||
|
||||
if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
|
||||
test_bit(NETLINK_S_CONGESTED, &nlk->state))) {
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
if (!*timeo) {
|
||||
if (!ssk || netlink_is_kernel(ssk))
|
||||
netlink_overrun(sk);
|
||||
sock_put(sk);
|
||||
kfree_skb(skb);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(&nlk->wait, &wait);
|
||||
|
||||
if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
|
||||
test_bit(NETLINK_S_CONGESTED, &nlk->state)) &&
|
||||
!sock_flag(sk, SOCK_DEAD))
|
||||
*timeo = schedule_timeout(*timeo);
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&nlk->wait, &wait);
|
||||
sock_put(sk);
|
||||
|
||||
if (signal_pending(current)) {
|
||||
kfree_skb(skb);
|
||||
return sock_intr_errno(*timeo);
|
||||
}
|
||||
return 1;
|
||||
if ((rmem == skb->truesize || rmem < READ_ONCE(sk->sk_rcvbuf)) &&
|
||||
!test_bit(NETLINK_S_CONGESTED, &nlk->state)) {
|
||||
netlink_skb_set_owner_r(skb, sk);
|
||||
return 0;
|
||||
}
|
||||
netlink_skb_set_owner_r(skb, sk);
|
||||
return 0;
|
||||
|
||||
atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
|
||||
|
||||
if (!*timeo) {
|
||||
if (!ssk || netlink_is_kernel(ssk))
|
||||
netlink_overrun(sk);
|
||||
sock_put(sk);
|
||||
kfree_skb(skb);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(&nlk->wait, &wait);
|
||||
rmem = atomic_read(&sk->sk_rmem_alloc);
|
||||
|
||||
if (((rmem && rmem + skb->truesize > READ_ONCE(sk->sk_rcvbuf)) ||
|
||||
test_bit(NETLINK_S_CONGESTED, &nlk->state)) &&
|
||||
!sock_flag(sk, SOCK_DEAD))
|
||||
*timeo = schedule_timeout(*timeo);
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&nlk->wait, &wait);
|
||||
sock_put(sk);
|
||||
|
||||
if (signal_pending(current)) {
|
||||
kfree_skb(skb);
|
||||
return sock_intr_errno(*timeo);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
|
||||
|
@ -1307,6 +1313,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb,
|
|||
ret = -ECONNREFUSED;
|
||||
if (nlk->netlink_rcv != NULL) {
|
||||
ret = skb->len;
|
||||
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
|
||||
netlink_skb_set_owner_r(skb, sk);
|
||||
NETLINK_CB(skb).sk = ssk;
|
||||
netlink_deliver_tap_kernel(sk, ssk, skb);
|
||||
|
@ -1383,13 +1390,19 @@ EXPORT_SYMBOL_GPL(netlink_strict_get_check);
|
|||
static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
unsigned int rmem, rcvbuf;
|
||||
|
||||
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
|
||||
rmem = atomic_add_return(skb->truesize, &sk->sk_rmem_alloc);
|
||||
rcvbuf = READ_ONCE(sk->sk_rcvbuf);
|
||||
|
||||
if ((rmem != skb->truesize || rmem <= rcvbuf) &&
|
||||
!test_bit(NETLINK_S_CONGESTED, &nlk->state)) {
|
||||
netlink_skb_set_owner_r(skb, sk);
|
||||
__netlink_sendskb(sk, skb);
|
||||
return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
|
||||
return rmem > (rcvbuf >> 1);
|
||||
}
|
||||
|
||||
atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2249,6 +2262,7 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
|
|||
struct module *module;
|
||||
int err = -ENOBUFS;
|
||||
int alloc_min_size;
|
||||
unsigned int rmem;
|
||||
int alloc_size;
|
||||
|
||||
if (!lock_taken)
|
||||
|
@ -2258,9 +2272,6 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
|
|||
goto errout_skb;
|
||||
}
|
||||
|
||||
if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
|
||||
goto errout_skb;
|
||||
|
||||
/* NLMSG_GOODSIZE is small to avoid high order allocations being
|
||||
* required, but it makes sense to _attempt_ a 32KiB allocation
|
||||
* to reduce number of system calls on dump operations, if user
|
||||
|
@ -2283,6 +2294,12 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
|
|||
if (!skb)
|
||||
goto errout_skb;
|
||||
|
||||
rmem = atomic_add_return(skb->truesize, &sk->sk_rmem_alloc);
|
||||
if (rmem >= READ_ONCE(sk->sk_rcvbuf)) {
|
||||
atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
|
||||
goto errout_skb;
|
||||
}
|
||||
|
||||
/* Trim skb to allocated size. User is expected to provide buffer as
|
||||
* large as max(min_dump_alloc, 32KiB (max_recvmsg_len capped at
|
||||
* netlink_recvmsg())). dump will pack as many smaller messages as
|
||||
|
|
|
@ -361,12 +361,15 @@ struct rxrpc_local {
|
|||
struct list_head new_client_calls; /* Newly created client calls need connection */
|
||||
spinlock_t client_call_lock; /* Lock for ->new_client_calls */
|
||||
struct sockaddr_rxrpc srx; /* local address */
|
||||
/* Provide a kvec table sufficiently large to manage either a DATA
|
||||
* packet with a maximum set of jumbo subpackets or a PING ACK padded
|
||||
* out to 64K with zeropages for PMTUD.
|
||||
*/
|
||||
struct kvec kvec[1 + RXRPC_MAX_NR_JUMBO > 3 + 16 ?
|
||||
1 + RXRPC_MAX_NR_JUMBO : 3 + 16];
|
||||
union {
|
||||
/* Provide a kvec table sufficiently large to manage either a
|
||||
* DATA packet with a maximum set of jumbo subpackets or a PING
|
||||
* ACK padded out to 64K with zeropages for PMTUD.
|
||||
*/
|
||||
struct kvec kvec[1 + RXRPC_MAX_NR_JUMBO > 3 + 16 ?
|
||||
1 + RXRPC_MAX_NR_JUMBO : 3 + 16];
|
||||
struct bio_vec bvec[3 + 16];
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -149,6 +149,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
|
|||
|
||||
id_in_use:
|
||||
write_unlock(&rx->call_lock);
|
||||
rxrpc_prefail_call(call, RXRPC_CALL_LOCAL_ERROR, -EBADSLT);
|
||||
rxrpc_cleanup_call(call);
|
||||
_leave(" = -EBADSLT");
|
||||
return -EBADSLT;
|
||||
|
@ -254,6 +255,9 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
|
|||
unsigned short call_tail, conn_tail, peer_tail;
|
||||
unsigned short call_count, conn_count;
|
||||
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
/* #calls >= #conns >= #peers must hold true. */
|
||||
call_head = smp_load_acquire(&b->call_backlog_head);
|
||||
call_tail = b->call_backlog_tail;
|
||||
|
|
|
@ -924,7 +924,7 @@ void rxrpc_send_response(struct rxrpc_connection *conn, struct sk_buff *response
|
|||
{
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(response);
|
||||
struct scatterlist sg[16];
|
||||
struct bio_vec bvec[16];
|
||||
struct bio_vec *bvec = conn->local->bvec;
|
||||
struct msghdr msg;
|
||||
size_t len = sp->resp.len;
|
||||
__be32 wserial;
|
||||
|
@ -938,6 +938,9 @@ void rxrpc_send_response(struct rxrpc_connection *conn, struct sk_buff *response
|
|||
if (ret < 0)
|
||||
goto fail;
|
||||
nr_sg = ret;
|
||||
ret = -EIO;
|
||||
if (WARN_ON_ONCE(nr_sg > ARRAY_SIZE(conn->local->bvec)))
|
||||
goto fail;
|
||||
|
||||
for (int i = 0; i < nr_sg; i++)
|
||||
bvec_set_page(&bvec[i], sg_page(&sg[i]), sg[i].length, sg[i].offset);
|
||||
|
|
|
@ -336,17 +336,22 @@ out:
|
|||
return q;
|
||||
}
|
||||
|
||||
static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
|
||||
static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
unsigned long cl;
|
||||
const struct Qdisc_class_ops *cops = p->ops->cl_ops;
|
||||
|
||||
if (cops == NULL)
|
||||
return NULL;
|
||||
if (cops == NULL) {
|
||||
NL_SET_ERR_MSG(extack, "Parent qdisc is not classful");
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
cl = cops->find(p, classid);
|
||||
|
||||
if (cl == 0)
|
||||
return NULL;
|
||||
if (cl == 0) {
|
||||
NL_SET_ERR_MSG(extack, "Specified class not found");
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
return cops->leaf(p, cl);
|
||||
}
|
||||
|
||||
|
@ -596,16 +601,6 @@ out:
|
|||
qdisc_skb_cb(skb)->pkt_len = pkt_len;
|
||||
}
|
||||
|
||||
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
|
||||
{
|
||||
if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
|
||||
pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
|
||||
txt, qdisc->ops->id, qdisc->handle >> 16);
|
||||
qdisc->flags |= TCQ_F_WARN_NONWC;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(qdisc_warn_nonwc);
|
||||
|
||||
static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
|
||||
{
|
||||
struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
|
||||
|
@ -1490,7 +1485,7 @@ static int __tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
NL_SET_ERR_MSG(extack, "Failed to find qdisc with specified classid");
|
||||
return -ENOENT;
|
||||
}
|
||||
q = qdisc_leaf(p, clid);
|
||||
q = qdisc_leaf(p, clid, extack);
|
||||
} else if (dev_ingress_queue(dev)) {
|
||||
q = rtnl_dereference(dev_ingress_queue(dev)->qdisc_sleeping);
|
||||
}
|
||||
|
@ -1501,6 +1496,8 @@ static int __tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
NL_SET_ERR_MSG(extack, "Cannot find specified qdisc on specified device");
|
||||
return -ENOENT;
|
||||
}
|
||||
if (IS_ERR(q))
|
||||
return PTR_ERR(q);
|
||||
|
||||
if (tcm->tcm_handle && q->handle != tcm->tcm_handle) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid handle");
|
||||
|
@ -1602,7 +1599,9 @@ static int __tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
NL_SET_ERR_MSG(extack, "Failed to find specified qdisc");
|
||||
return -ENOENT;
|
||||
}
|
||||
q = qdisc_leaf(p, clid);
|
||||
q = qdisc_leaf(p, clid, extack);
|
||||
if (IS_ERR(q))
|
||||
return PTR_ERR(q);
|
||||
} else if (dev_ingress_queue_create(dev)) {
|
||||
q = rtnl_dereference(dev_ingress_queue(dev)->qdisc_sleeping);
|
||||
}
|
||||
|
|
|
@ -835,22 +835,6 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
qdisc_peek_len(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
skb = sch->ops->peek(sch);
|
||||
if (unlikely(skb == NULL)) {
|
||||
qdisc_warn_nonwc("qdisc_peek_len", sch);
|
||||
return 0;
|
||||
}
|
||||
len = qdisc_pkt_len(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
hfsc_adjust_levels(struct hfsc_class *cl)
|
||||
{
|
||||
|
|
|
@ -989,7 +989,7 @@ static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg,
|
|||
|
||||
if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */
|
||||
list_del_init(&cl->alist);
|
||||
else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) {
|
||||
else if (cl->deficit < qdisc_peek_len(cl->qdisc)) {
|
||||
cl->deficit += agg->lmax;
|
||||
list_move_tail(&cl->alist, &agg->active);
|
||||
}
|
||||
|
|
|
@ -704,8 +704,10 @@ static void tipc_topsrv_stop(struct net *net)
|
|||
for (id = 0; srv->idr_in_use; id++) {
|
||||
con = idr_find(&srv->conn_idr, id);
|
||||
if (con) {
|
||||
conn_get(con);
|
||||
spin_unlock_bh(&srv->idr_lock);
|
||||
tipc_conn_close(con);
|
||||
conn_put(con);
|
||||
spin_lock_bh(&srv->idr_lock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -407,6 +407,8 @@ EXPORT_SYMBOL_GPL(vsock_enqueue_accept);
|
|||
|
||||
static bool vsock_use_local_transport(unsigned int remote_cid)
|
||||
{
|
||||
lockdep_assert_held(&vsock_register_mutex);
|
||||
|
||||
if (!transport_local)
|
||||
return false;
|
||||
|
||||
|
@ -464,6 +466,8 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
|
|||
|
||||
remote_flags = vsk->remote_addr.svm_flags;
|
||||
|
||||
mutex_lock(&vsock_register_mutex);
|
||||
|
||||
switch (sk->sk_type) {
|
||||
case SOCK_DGRAM:
|
||||
new_transport = transport_dgram;
|
||||
|
@ -479,12 +483,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
|
|||
new_transport = transport_h2g;
|
||||
break;
|
||||
default:
|
||||
return -ESOCKTNOSUPPORT;
|
||||
ret = -ESOCKTNOSUPPORT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (vsk->transport) {
|
||||
if (vsk->transport == new_transport)
|
||||
return 0;
|
||||
if (vsk->transport == new_transport) {
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* transport->release() must be called with sock lock acquired.
|
||||
* This path can only be taken during vsock_connect(), where we
|
||||
|
@ -508,8 +515,16 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
|
|||
/* We increase the module refcnt to prevent the transport unloading
|
||||
* while there are open sockets assigned to it.
|
||||
*/
|
||||
if (!new_transport || !try_module_get(new_transport->module))
|
||||
return -ENODEV;
|
||||
if (!new_transport || !try_module_get(new_transport->module)) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* It's safe to release the mutex after a successful try_module_get().
|
||||
* Whichever transport `new_transport` points at, it won't go away until
|
||||
* the last module_put() below or in vsock_deassign_transport().
|
||||
*/
|
||||
mutex_unlock(&vsock_register_mutex);
|
||||
|
||||
if (sk->sk_type == SOCK_SEQPACKET) {
|
||||
if (!new_transport->seqpacket_allow ||
|
||||
|
@ -528,12 +543,31 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
|
|||
vsk->transport = new_transport;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
mutex_unlock(&vsock_register_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vsock_assign_transport);
|
||||
|
||||
/*
|
||||
* Provide safe access to static transport_{h2g,g2h,dgram,local} callbacks.
|
||||
* Otherwise we may race with module removal. Do not use on `vsk->transport`.
|
||||
*/
|
||||
static u32 vsock_registered_transport_cid(const struct vsock_transport **transport)
|
||||
{
|
||||
u32 cid = VMADDR_CID_ANY;
|
||||
|
||||
mutex_lock(&vsock_register_mutex);
|
||||
if (*transport)
|
||||
cid = (*transport)->get_local_cid();
|
||||
mutex_unlock(&vsock_register_mutex);
|
||||
|
||||
return cid;
|
||||
}
|
||||
|
||||
bool vsock_find_cid(unsigned int cid)
|
||||
{
|
||||
if (transport_g2h && cid == transport_g2h->get_local_cid())
|
||||
if (cid == vsock_registered_transport_cid(&transport_g2h))
|
||||
return true;
|
||||
|
||||
if (transport_h2g && cid == VMADDR_CID_HOST)
|
||||
|
@ -2536,18 +2570,19 @@ static long vsock_dev_do_ioctl(struct file *filp,
|
|||
unsigned int cmd, void __user *ptr)
|
||||
{
|
||||
u32 __user *p = ptr;
|
||||
u32 cid = VMADDR_CID_ANY;
|
||||
int retval = 0;
|
||||
u32 cid;
|
||||
|
||||
switch (cmd) {
|
||||
case IOCTL_VM_SOCKETS_GET_LOCAL_CID:
|
||||
/* To be compatible with the VMCI behavior, we prioritize the
|
||||
* guest CID instead of well-know host CID (VMADDR_CID_HOST).
|
||||
*/
|
||||
if (transport_g2h)
|
||||
cid = transport_g2h->get_local_cid();
|
||||
else if (transport_h2g)
|
||||
cid = transport_h2g->get_local_cid();
|
||||
cid = vsock_registered_transport_cid(&transport_g2h);
|
||||
if (cid == VMADDR_CID_ANY)
|
||||
cid = vsock_registered_transport_cid(&transport_h2g);
|
||||
if (cid == VMADDR_CID_ANY)
|
||||
cid = vsock_registered_transport_cid(&transport_local);
|
||||
|
||||
if (put_user(cid, p) != 0)
|
||||
retval = -EFAULT;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
--mss=1000
|
||||
|
||||
`./defaults.sh
|
||||
sysctl -q net.ipv4.tcp_rmem="4096 131072 $((32*1024*1024))"`
|
||||
|
||||
// Test that a not-yet-accepted socket does not change
|
||||
// its initial sk_rcvbuf (tcp_rmem[1]) when receiving ooo packets.
|
||||
|
||||
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 65535 <mss 1000,nop,nop,sackOK,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 10>
|
||||
+.1 < . 1:1(0) ack 1 win 257
|
||||
+0 < . 2001:41001(39000) ack 1 win 257
|
||||
+0 > . 1:1(0) ack 1 <nop,nop,sack 2001:41001>
|
||||
+0 < . 41001:101001(60000) ack 1 win 257
|
||||
+0 > . 1:1(0) ack 1 <nop,nop,sack 2001:101001>
|
||||
+0 < . 1:1001(1000) ack 1 win 257
|
||||
+0 > . 1:1(0) ack 1001 <nop,nop,sack 2001:101001>
|
||||
+0 < . 1001:2001(1000) ack 1 win 257
|
||||
+0 > . 1:1(0) ack 101001
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
+0 %{ assert SK_MEMINFO_RCVBUF == 131072, SK_MEMINFO_RCVBUF }%
|
||||
|
||||
+0 close(4) = 0
|
||||
+0 close(3) = 0
|
||||
|
||||
// Test that ooo packets for accepted sockets do increase sk_rcvbuf
|
||||
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:0(0) win 65535 <mss 1000,nop,nop,sackOK,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 10>
|
||||
+.1 < . 1:1(0) ack 1 win 257
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
+0 < . 2001:41001(39000) ack 1 win 257
|
||||
+0 > . 1:1(0) ack 1 <nop,nop,sack 2001:41001>
|
||||
+0 < . 41001:101001(60000) ack 1 win 257
|
||||
+0 > . 1:1(0) ack 1 <nop,nop,sack 2001:101001>
|
||||
|
||||
+0 %{ assert SK_MEMINFO_RCVBUF > 131072, SK_MEMINFO_RCVBUF }%
|
||||
|
|
@ -635,5 +635,42 @@
|
|||
"$TC qdisc del dev $DUMMY handle 1:0 root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "d74b",
|
||||
"name": "Test use-after-free with DRR/NETEM/BLACKHOLE chain",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"hfsc",
|
||||
"drr",
|
||||
"netem",
|
||||
"blackhole"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": [
|
||||
"nsPlugin",
|
||||
"scapyPlugin"
|
||||
]
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.11.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY root handle 1: drr",
|
||||
"$TC filter add dev $DUMMY parent 1: basic classid 1:1",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:1 drr",
|
||||
"$TC qdisc add dev $DUMMY parent 1:1 handle 2: hfsc def 1",
|
||||
"$TC class add dev $DUMMY parent 2: classid 2:1 hfsc rt m1 8 d 1 m2 0",
|
||||
"$TC qdisc add dev $DUMMY parent 2:1 handle 3: netem",
|
||||
"$TC qdisc add dev $DUMMY parent 3:1 handle 4: blackhole",
|
||||
"ping -c1 -W0.01 -I $DUMMY 10.10.11.11 || true",
|
||||
"$TC class del dev $DUMMY classid 1:1"
|
||||
],
|
||||
"cmdUnderTest": "ping -c1 -W0.01 -I $DUMMY 10.10.11.11",
|
||||
"expExitCode": "1",
|
||||
"verifyCmd": "$TC -j class ls dev $DUMMY classid 1:1",
|
||||
"matchJSON": [],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root handle 1: drr"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue
Block a user