forked from Minki/linux
Networking fixes for 6.1-rc4, including fixes from bluetooth and
netfilter. Current release - regressions: - net: several zerocopy flags fixes - netfilter: fix possible memory leak in nf_nat_init() - openvswitch: add missing .resv_start_op Previous releases - regressions: - neigh: fix null-ptr-deref in neigh_table_clear() - sched: fix use after free in red_enqueue() - dsa: fall back to default tagger if we can't load the one from DT - bluetooth: fix use-after-free in l2cap_conn_del() Previous releases - always broken: - netfilter: netlink notifier might race to release objects - nfc: fix potential memory leak of skb - bluetooth: fix use-after-free caused by l2cap_reassemble_sdu - bluetooth: use skb_put to set length - eth: tun: fix bugs for oversize packet when napi frags enabled - eth: lan966x: fixes for when MTU is changed - eth: dwmac-loongson: fix invalid mdio_node -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmNjnBISHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOkSvwP/RokbplLXVut8xlEzeYP48tFAcM/aUmy iWbz47IZNOXeWfQxP9kzDD9y1gqVJVrEt9bsPMingjArYSgOZYBssXbKeI4Lofeh EzQ8B9dJbxIBMHx5bTRhL9pSYYhUnqPAsQKqm6Bvi2YZ4EmMK0WtnSn1O2egMg6Y eNuFPTdRiO6Zs9vXF4iyYBPj3Wdg7oUGSjyluKF5Wwfk3GFt/a9iAoctk6gIZlDU Tq7pQ9Qs6dk8em8G3qdUalaWuswY/a/jh8QpGvGVaY6ncgSkD4M883UyvR23SOne V4jE/VbPOQpmkzkRkFY27GIMBg1IGXqq4gcB3aw8LL9+G446UJrtvy4OyiOex/Rg yJ9FmHdtFndQLiu7cHgQuUZ5s2B/UwVXLo3MD+KEwJ2bzo6vDp1mQsiUN7lttdrc AYgxyn0tH0tFADHGZZ0NspTAlgfmBsytXTGWdEfMUkMYDicC62XNnf2akwJlSpQU mJdzc/N23JXxd3dPFv0brDDj9Kl1DC3eUcCbWwDTtdiqQc6BKnnfAQ4+kd8gBUed 5cXYNcuRi5sQ9ZfvGUCdDxi+kzFMvjRvYo45AnPJsoURlZwKI2EEFdcEsw5CF3Co QHWm8r7SFeG26oDgfs7R1o/uQr8Cxk8e7t0Pd3iKaslSrO4i/7cQioFhZF4sdjPr GB6K67t/qvdE =34Ef -----END PGP SIGNATURE----- Merge tag 'net-6.1-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from bluetooth and netfilter. Current release - regressions: - net: several zerocopy flags fixes - netfilter: fix possible memory leak in nf_nat_init() - openvswitch: add missing .resv_start_op Previous releases - regressions: - neigh: fix null-ptr-deref in neigh_table_clear() - sched: fix use after free in red_enqueue() - dsa: fall back to default tagger if we can't load the one from DT - bluetooth: fix use-after-free in l2cap_conn_del() Previous releases - always broken: - netfilter: netlink notifier might race to release objects - nfc: fix potential memory leak of skb - bluetooth: fix use-after-free caused by l2cap_reassemble_sdu - bluetooth: use skb_put to set length - eth: tun: fix bugs for oversize packet when napi frags enabled - eth: lan966x: fixes for when MTU is changed - eth: dwmac-loongson: fix invalid mdio_node" * tag 'net-6.1-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (53 commits) vsock: fix possible infinite sleep in vsock_connectible_wait_data() vsock: remove the unused 'wait' in vsock_connectible_recvmsg() ipv6: fix WARNING in ip6_route_net_exit_late() bridge: Fix flushing of dynamic FDB entries net, neigh: Fix null-ptr-deref in neigh_table_clear() net/smc: Fix possible leaked pernet namespace in smc_init() stmmac: dwmac-loongson: fix invalid mdio_node ibmvnic: Free rwi on reset success net: mdio: fix undefined behavior in bit shift for __mdiobus_register Bluetooth: L2CAP: Fix attempting to access uninitialized memory Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm Bluetooth: L2CAP: Fix accepting connection request for invalid SPSM Bluetooth: hci_conn: Fix not restoring ISO buffer count on disconnect Bluetooth: L2CAP: Fix memory leak in vhci_write Bluetooth: L2CAP: fix use-after-free in l2cap_conn_del() Bluetooth: virtio_bt: Use skb_put to set length Bluetooth: hci_conn: Fix CIS connection dst_type handling Bluetooth: L2CAP: Fix use-after-free caused by l2cap_reassemble_sdu netfilter: ipset: enforce documented limit to prevent allocating huge memory isdn: mISDN: netjet: fix wrong check of device registration ...
This commit is contained in:
commit
9521c9d6a5
@ -5041,7 +5041,7 @@ F: drivers/scsi/snic/
|
||||
|
||||
CISCO VIC ETHERNET NIC DRIVER
|
||||
M: Christian Benvenuti <benve@cisco.com>
|
||||
M: Govindarajulu Varadarajan <_govind@gmx.com>
|
||||
M: Satish Kharat <satishkh@cisco.com>
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/cisco/enic/
|
||||
|
||||
@ -9778,7 +9778,10 @@ S: Supported
|
||||
F: drivers/pci/hotplug/rpaphp*
|
||||
|
||||
IBM Power SRIOV Virtual NIC Device Driver
|
||||
M: Dany Madden <drt@linux.ibm.com>
|
||||
M: Haren Myneni <haren@linux.ibm.com>
|
||||
M: Rick Lindsley <ricklind@linux.ibm.com>
|
||||
R: Nick Child <nnac123@linux.ibm.com>
|
||||
R: Dany Madden <danymadden@us.ibm.com>
|
||||
R: Thomas Falcon <tlfalcon@linux.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
@ -219,7 +219,7 @@ static void virtbt_rx_work(struct work_struct *work)
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
skb->len = len;
|
||||
skb_put(skb, len);
|
||||
virtbt_rx_handle(vbt, skb);
|
||||
|
||||
if (virtbt_add_inbuf(vbt) < 0)
|
||||
|
@ -956,7 +956,7 @@ nj_release(struct tiger_hw *card)
|
||||
}
|
||||
if (card->irq > 0)
|
||||
free_irq(card->irq, card);
|
||||
if (card->isac.dch.dev.dev.class)
|
||||
if (device_is_registered(&card->isac.dch.dev.dev))
|
||||
mISDN_unregister_device(&card->isac.dch.dev);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
@ -233,11 +233,12 @@ mISDN_register_device(struct mISDNdevice *dev,
|
||||
if (debug & DEBUG_CORE)
|
||||
printk(KERN_DEBUG "mISDN_register %s %d\n",
|
||||
dev_name(&dev->dev), dev->id);
|
||||
dev->dev.class = &mISDN_class;
|
||||
|
||||
err = create_stack(dev);
|
||||
if (err)
|
||||
goto error1;
|
||||
|
||||
dev->dev.class = &mISDN_class;
|
||||
dev->dev.platform_data = dev;
|
||||
dev->dev.parent = parent;
|
||||
dev_set_drvdata(&dev->dev, dev);
|
||||
@ -249,8 +250,8 @@ mISDN_register_device(struct mISDNdevice *dev,
|
||||
|
||||
error3:
|
||||
delete_stack(dev);
|
||||
return err;
|
||||
error1:
|
||||
put_device(&dev->dev);
|
||||
return err;
|
||||
|
||||
}
|
||||
|
@ -376,6 +376,17 @@ static struct mdio_driver dsa_loop_drv = {
|
||||
|
||||
#define NUM_FIXED_PHYS (DSA_LOOP_NUM_PORTS - 2)
|
||||
|
||||
static void dsa_loop_phydevs_unregister(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NUM_FIXED_PHYS; i++)
|
||||
if (!IS_ERR(phydevs[i])) {
|
||||
fixed_phy_unregister(phydevs[i]);
|
||||
phy_device_free(phydevs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init dsa_loop_init(void)
|
||||
{
|
||||
struct fixed_phy_status status = {
|
||||
@ -383,23 +394,23 @@ static int __init dsa_loop_init(void)
|
||||
.speed = SPEED_100,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
unsigned int i;
|
||||
unsigned int i, ret;
|
||||
|
||||
for (i = 0; i < NUM_FIXED_PHYS; i++)
|
||||
phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL);
|
||||
|
||||
return mdio_driver_register(&dsa_loop_drv);
|
||||
ret = mdio_driver_register(&dsa_loop_drv);
|
||||
if (ret)
|
||||
dsa_loop_phydevs_unregister();
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(dsa_loop_init);
|
||||
|
||||
static void __exit dsa_loop_exit(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
mdio_driver_unregister(&dsa_loop_drv);
|
||||
for (i = 0; i < NUM_FIXED_PHYS; i++)
|
||||
if (!IS_ERR(phydevs[i]))
|
||||
fixed_phy_unregister(phydevs[i]);
|
||||
dsa_loop_phydevs_unregister();
|
||||
}
|
||||
module_exit(dsa_loop_exit);
|
||||
|
||||
|
@ -1512,16 +1512,15 @@ static struct notifier_block adin1110_switchdev_notifier = {
|
||||
.notifier_call = adin1110_switchdev_event,
|
||||
};
|
||||
|
||||
static void adin1110_unregister_notifiers(void *data)
|
||||
static void adin1110_unregister_notifiers(void)
|
||||
{
|
||||
unregister_switchdev_blocking_notifier(&adin1110_switchdev_blocking_notifier);
|
||||
unregister_switchdev_notifier(&adin1110_switchdev_notifier);
|
||||
unregister_netdevice_notifier(&adin1110_netdevice_nb);
|
||||
}
|
||||
|
||||
static int adin1110_setup_notifiers(struct adin1110_priv *priv)
|
||||
static int adin1110_setup_notifiers(void)
|
||||
{
|
||||
struct device *dev = &priv->spidev->dev;
|
||||
int ret;
|
||||
|
||||
ret = register_netdevice_notifier(&adin1110_netdevice_nb);
|
||||
@ -1536,13 +1535,14 @@ static int adin1110_setup_notifiers(struct adin1110_priv *priv)
|
||||
if (ret < 0)
|
||||
goto err_sdev;
|
||||
|
||||
return devm_add_action_or_reset(dev, adin1110_unregister_notifiers, NULL);
|
||||
return 0;
|
||||
|
||||
err_sdev:
|
||||
unregister_switchdev_notifier(&adin1110_switchdev_notifier);
|
||||
|
||||
err_netdev:
|
||||
unregister_netdevice_notifier(&adin1110_netdevice_nb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1613,10 +1613,6 @@ static int adin1110_probe_netdevs(struct adin1110_priv *priv)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = adin1110_setup_notifiers(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < priv->cfg->ports_nr; i++) {
|
||||
ret = devm_register_netdev(dev, priv->ports[i]->netdev);
|
||||
if (ret < 0) {
|
||||
@ -1693,7 +1689,31 @@ static struct spi_driver adin1110_driver = {
|
||||
.probe = adin1110_probe,
|
||||
.id_table = adin1110_spi_id,
|
||||
};
|
||||
module_spi_driver(adin1110_driver);
|
||||
|
||||
static int __init adin1110_driver_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = adin1110_setup_notifiers();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = spi_register_driver(&adin1110_driver);
|
||||
if (ret < 0) {
|
||||
adin1110_unregister_notifiers();
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit adin1110_exit(void)
|
||||
{
|
||||
adin1110_unregister_notifiers();
|
||||
spi_unregister_driver(&adin1110_driver);
|
||||
}
|
||||
module_init(adin1110_driver_init);
|
||||
module_exit(adin1110_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ADIN1110 Network driver");
|
||||
MODULE_AUTHOR("Alexandru Tachici <alexandru.tachici@analog.com>");
|
||||
|
@ -713,7 +713,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
|
||||
dev_kfree_skb_any(skb);
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev, "Tx DMA memory map failed\n");
|
||||
return NETDEV_TX_BUSY;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
bdp->cbd_datlen = cpu_to_fec16(size);
|
||||
@ -775,7 +775,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
|
||||
dev_kfree_skb_any(skb);
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev, "Tx DMA memory map failed\n");
|
||||
return NETDEV_TX_BUSY;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3007,19 +3007,19 @@ static void __ibmvnic_reset(struct work_struct *work)
|
||||
rwi = get_next_rwi(adapter);
|
||||
|
||||
/*
|
||||
* If there is another reset queued, free the previous rwi
|
||||
* and process the new reset even if previous reset failed
|
||||
* (the previous reset could have failed because of a fail
|
||||
* over for instance, so process the fail over).
|
||||
*
|
||||
* If there are no resets queued and the previous reset failed,
|
||||
* the adapter would be in an undefined state. So retry the
|
||||
* previous reset as a hard reset.
|
||||
*
|
||||
* Else, free the previous rwi and, if there is another reset
|
||||
* queued, process the new reset even if previous reset failed
|
||||
* (the previous reset could have failed because of a fail
|
||||
* over for instance, so process the fail over).
|
||||
*/
|
||||
if (rwi)
|
||||
kfree(tmprwi);
|
||||
else if (rc)
|
||||
if (!rwi && rc)
|
||||
rwi = tmprwi;
|
||||
else
|
||||
kfree(tmprwi);
|
||||
|
||||
if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER ||
|
||||
rwi->reset_reason == VNIC_RESET_MOBILITY || rc))
|
||||
|
@ -414,13 +414,15 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
|
||||
/* Get the received frame and unmap it */
|
||||
db = &rx->dcbs[rx->dcb_index].db[rx->db_index];
|
||||
page = rx->page[rx->dcb_index][rx->db_index];
|
||||
|
||||
dma_sync_single_for_cpu(lan966x->dev, (dma_addr_t)db->dataptr,
|
||||
FDMA_DCB_STATUS_BLOCKL(db->status),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order);
|
||||
if (unlikely(!skb))
|
||||
goto unmap_page;
|
||||
|
||||
dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr,
|
||||
FDMA_DCB_STATUS_BLOCKL(db->status),
|
||||
DMA_FROM_DEVICE);
|
||||
skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status));
|
||||
|
||||
lan966x_ifh_get_src_port(skb->data, &src_port);
|
||||
@ -429,6 +431,10 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
|
||||
if (WARN_ON(src_port >= lan966x->num_phys_ports))
|
||||
goto free_skb;
|
||||
|
||||
dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr,
|
||||
PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE,
|
||||
DMA_ATTR_SKIP_CPU_SYNC);
|
||||
|
||||
skb->dev = lan966x->ports[src_port]->dev;
|
||||
skb_pull(skb, IFH_LEN * sizeof(u32));
|
||||
|
||||
@ -454,9 +460,9 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
|
||||
free_skb:
|
||||
kfree_skb(skb);
|
||||
unmap_page:
|
||||
dma_unmap_page(lan966x->dev, (dma_addr_t)db->dataptr,
|
||||
FDMA_DCB_STATUS_BLOCKL(db->status),
|
||||
DMA_FROM_DEVICE);
|
||||
dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr,
|
||||
PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE,
|
||||
DMA_ATTR_SKIP_CPU_SYNC);
|
||||
__free_pages(page, rx->page_order);
|
||||
|
||||
return NULL;
|
||||
@ -668,12 +674,14 @@ static int lan966x_fdma_get_max_mtu(struct lan966x *lan966x)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lan966x->num_phys_ports; ++i) {
|
||||
struct lan966x_port *port;
|
||||
int mtu;
|
||||
|
||||
if (!lan966x->ports[i])
|
||||
port = lan966x->ports[i];
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
mtu = lan966x->ports[i]->dev->mtu;
|
||||
mtu = lan_rd(lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
|
||||
if (mtu > max_mtu)
|
||||
max_mtu = mtu;
|
||||
}
|
||||
@ -733,6 +741,8 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)
|
||||
|
||||
max_mtu = lan966x_fdma_get_max_mtu(lan966x);
|
||||
max_mtu += IFH_LEN * sizeof(u32);
|
||||
max_mtu += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
max_mtu += VLAN_HLEN * 2;
|
||||
|
||||
if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 ==
|
||||
lan966x->rx.page_order)
|
||||
|
@ -386,7 +386,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
|
||||
int old_mtu = dev->mtu;
|
||||
int err;
|
||||
|
||||
lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(new_mtu),
|
||||
lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(new_mtu)),
|
||||
lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
|
||||
dev->mtu = new_mtu;
|
||||
|
||||
@ -395,7 +395,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
||||
err = lan966x_fdma_change_mtu(lan966x);
|
||||
if (err) {
|
||||
lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(old_mtu),
|
||||
lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(old_mtu)),
|
||||
lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
|
||||
dev->mtu = old_mtu;
|
||||
}
|
||||
|
@ -26,6 +26,8 @@
|
||||
#define LAN966X_BUFFER_MEMORY (160 * 1024)
|
||||
#define LAN966X_BUFFER_MIN_SZ 60
|
||||
|
||||
#define LAN966X_HW_MTU(mtu) ((mtu) + ETH_HLEN + ETH_FCS_LEN)
|
||||
|
||||
#define PGID_AGGR 64
|
||||
#define PGID_SRC 80
|
||||
#define PGID_ENTRIES 89
|
||||
|
@ -585,6 +585,21 @@ enum lan966x_target {
|
||||
#define DEV_MAC_MAXLEN_CFG_MAX_LEN_GET(x)\
|
||||
FIELD_GET(DEV_MAC_MAXLEN_CFG_MAX_LEN, x)
|
||||
|
||||
/* DEV:MAC_CFG_STATUS:MAC_TAGS_CFG */
|
||||
#define DEV_MAC_TAGS_CFG(t) __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 12, 0, 1, 4)
|
||||
|
||||
#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA BIT(1)
|
||||
#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(x)\
|
||||
FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
|
||||
#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_GET(x)\
|
||||
FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
|
||||
|
||||
#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0)
|
||||
#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
|
||||
FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
|
||||
#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
|
||||
FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
|
||||
|
||||
/* DEV:MAC_CFG_STATUS:MAC_IFG_CFG */
|
||||
#define DEV_MAC_IFG_CFG(t) __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 20, 0, 1, 4)
|
||||
|
||||
|
@ -169,6 +169,12 @@ void lan966x_vlan_port_apply(struct lan966x_port *port)
|
||||
ANA_VLAN_CFG_VLAN_POP_CNT,
|
||||
lan966x, ANA_VLAN_CFG(port->chip_port));
|
||||
|
||||
lan_rmw(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(port->vlan_aware) |
|
||||
DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(port->vlan_aware),
|
||||
DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
|
||||
DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA,
|
||||
lan966x, DEV_MAC_TAGS_CFG(port->chip_port));
|
||||
|
||||
/* Drop frames with multicast source address */
|
||||
val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1);
|
||||
if (port->vlan_aware && !pvid)
|
||||
|
@ -1059,8 +1059,10 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
|
||||
|
||||
/* Allocate and initialise a struct net_device */
|
||||
net_dev = alloc_etherdev_mq(sizeof(probe_data), EFX_MAX_CORE_TX_QUEUES);
|
||||
if (!net_dev)
|
||||
return -ENOMEM;
|
||||
if (!net_dev) {
|
||||
rc = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
probe_ptr = netdev_priv(net_dev);
|
||||
*probe_ptr = probe_data;
|
||||
efx->net_dev = net_dev;
|
||||
@ -1132,6 +1134,8 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
|
||||
WARN_ON(rc > 0);
|
||||
netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc);
|
||||
free_netdev(net_dev);
|
||||
fail0:
|
||||
kfree(probe_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,6 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
|
||||
struct stmmac_resources res;
|
||||
struct device_node *np;
|
||||
int ret, i, phy_mode;
|
||||
bool mdio = false;
|
||||
|
||||
np = dev_of_node(&pdev->dev);
|
||||
|
||||
@ -69,12 +68,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
|
||||
if (!plat)
|
||||
return -ENOMEM;
|
||||
|
||||
plat->mdio_node = of_get_child_by_name(np, "mdio");
|
||||
if (plat->mdio_node) {
|
||||
dev_err(&pdev->dev, "Found MDIO subnode\n");
|
||||
mdio = true;
|
||||
}
|
||||
dev_info(&pdev->dev, "Found MDIO subnode\n");
|
||||
|
||||
if (mdio) {
|
||||
plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*plat->mdio_bus_data),
|
||||
GFP_KERNEL);
|
||||
|
@ -108,7 +108,7 @@
|
||||
* @next_tx_buf_to_use: next Tx buffer to write to
|
||||
* @next_rx_buf_to_use: next Rx buffer to read from
|
||||
* @base_addr: base address of the Emaclite device
|
||||
* @reset_lock: lock used for synchronization
|
||||
* @reset_lock: lock to serialize xmit and tx_timeout execution
|
||||
* @deferred_skb: holds an skb (for transmission at a later time) when the
|
||||
* Tx buffer is not free
|
||||
* @phy_dev: pointer to the PHY device
|
||||
|
@ -583,7 +583,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
|
||||
}
|
||||
|
||||
for (i = 0; i < PHY_MAX_ADDR; i++) {
|
||||
if ((bus->phy_mask & (1 << i)) == 0) {
|
||||
if ((bus->phy_mask & BIT(i)) == 0) {
|
||||
struct phy_device *phydev;
|
||||
|
||||
phydev = mdiobus_scan(bus, i);
|
||||
|
@ -1459,7 +1459,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (it->nr_segs > MAX_SKB_FRAGS + 1)
|
||||
if (it->nr_segs > MAX_SKB_FRAGS + 1 ||
|
||||
len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN))
|
||||
return ERR_PTR(-EMSGSIZE);
|
||||
|
||||
local_bh_disable();
|
||||
|
@ -249,11 +249,19 @@ static int fdp_nci_close(struct nci_dev *ndev)
|
||||
static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
|
||||
{
|
||||
struct fdp_nci_info *info = nci_get_drvdata(ndev);
|
||||
int ret;
|
||||
|
||||
if (atomic_dec_and_test(&info->data_pkt_counter))
|
||||
info->data_pkt_counter_cb(ndev);
|
||||
|
||||
return info->phy_ops->write(info->phy, skb);
|
||||
ret = info->phy_ops->write(info->phy, skb);
|
||||
if (ret < 0) {
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
consume_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fdp_nci_request_firmware(struct nci_dev *ndev)
|
||||
|
@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
|
||||
ret = -EREMOTEIO;
|
||||
} else
|
||||
ret = 0;
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (ret) {
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
consume_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
|
||||
|
@ -80,10 +80,13 @@ static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
|
||||
return -EINVAL;
|
||||
|
||||
r = info->phy_ops->write(info->phy_id, skb);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
kfree_skb(skb);
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
consume_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
|
||||
|
@ -110,11 +110,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
ret = s3fwrn5_write(info, skb);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
kfree_skb(skb);
|
||||
mutex_unlock(&info->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
consume_skb(skb);
|
||||
mutex_unlock(&info->mutex);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
|
||||
|
@ -181,6 +181,8 @@ enum {
|
||||
NLA_S64,
|
||||
NLA_BITFIELD32,
|
||||
NLA_REJECT,
|
||||
NLA_BE16,
|
||||
NLA_BE32,
|
||||
__NLA_TYPE_MAX,
|
||||
};
|
||||
|
||||
@ -231,6 +233,7 @@ enum nla_policy_validation {
|
||||
* NLA_U32, NLA_U64,
|
||||
* NLA_S8, NLA_S16,
|
||||
* NLA_S32, NLA_S64,
|
||||
* NLA_BE16, NLA_BE32,
|
||||
* NLA_MSECS Leaving the length field zero will verify the
|
||||
* given type fits, using it verifies minimum length
|
||||
* just like "All other"
|
||||
@ -261,6 +264,8 @@ enum nla_policy_validation {
|
||||
* NLA_U16,
|
||||
* NLA_U32,
|
||||
* NLA_U64,
|
||||
* NLA_BE16,
|
||||
* NLA_BE32,
|
||||
* NLA_S8,
|
||||
* NLA_S16,
|
||||
* NLA_S32,
|
||||
@ -317,19 +322,10 @@ struct nla_policy {
|
||||
u8 validation_type;
|
||||
u16 len;
|
||||
union {
|
||||
const u32 bitfield32_valid;
|
||||
const u32 mask;
|
||||
const char *reject_message;
|
||||
const struct nla_policy *nested_policy;
|
||||
struct netlink_range_validation *range;
|
||||
struct netlink_range_validation_signed *range_signed;
|
||||
struct {
|
||||
s16 min, max;
|
||||
u8 network_byte_order:1;
|
||||
};
|
||||
int (*validate)(const struct nlattr *attr,
|
||||
struct netlink_ext_ack *extack);
|
||||
/* This entry is special, and used for the attribute at index 0
|
||||
/**
|
||||
* @strict_start_type: first attribute to validate strictly
|
||||
*
|
||||
* This entry is special, and used for the attribute at index 0
|
||||
* only, and specifies special data about the policy, namely it
|
||||
* specifies the "boundary type" where strict length validation
|
||||
* starts for any attribute types >= this value, also, strict
|
||||
@ -348,6 +344,19 @@ struct nla_policy {
|
||||
* was added to enforce strict validation from thereon.
|
||||
*/
|
||||
u16 strict_start_type;
|
||||
|
||||
/* private: use NLA_POLICY_*() to set */
|
||||
const u32 bitfield32_valid;
|
||||
const u32 mask;
|
||||
const char *reject_message;
|
||||
const struct nla_policy *nested_policy;
|
||||
struct netlink_range_validation *range;
|
||||
struct netlink_range_validation_signed *range_signed;
|
||||
struct {
|
||||
s16 min, max;
|
||||
};
|
||||
int (*validate)(const struct nlattr *attr,
|
||||
struct netlink_ext_ack *extack);
|
||||
};
|
||||
};
|
||||
|
||||
@ -369,6 +378,8 @@ struct nla_policy {
|
||||
(tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64)
|
||||
#define __NLA_IS_SINT_TYPE(tp) \
|
||||
(tp == NLA_S8 || tp == NLA_S16 || tp == NLA_S32 || tp == NLA_S64)
|
||||
#define __NLA_IS_BEINT_TYPE(tp) \
|
||||
(tp == NLA_BE16 || tp == NLA_BE32)
|
||||
|
||||
#define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition))
|
||||
#define NLA_ENSURE_UINT_TYPE(tp) \
|
||||
@ -382,6 +393,7 @@ struct nla_policy {
|
||||
#define NLA_ENSURE_INT_OR_BINARY_TYPE(tp) \
|
||||
(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) || \
|
||||
__NLA_IS_SINT_TYPE(tp) || \
|
||||
__NLA_IS_BEINT_TYPE(tp) || \
|
||||
tp == NLA_MSECS || \
|
||||
tp == NLA_BINARY) + tp)
|
||||
#define NLA_ENSURE_NO_VALIDATION_PTR(tp) \
|
||||
@ -389,6 +401,8 @@ struct nla_policy {
|
||||
tp != NLA_REJECT && \
|
||||
tp != NLA_NESTED && \
|
||||
tp != NLA_NESTED_ARRAY) + tp)
|
||||
#define NLA_ENSURE_BEINT_TYPE(tp) \
|
||||
(__NLA_ENSURE(__NLA_IS_BEINT_TYPE(tp)) + tp)
|
||||
|
||||
#define NLA_POLICY_RANGE(tp, _min, _max) { \
|
||||
.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \
|
||||
@ -419,14 +433,6 @@ struct nla_policy {
|
||||
.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp), \
|
||||
.validation_type = NLA_VALIDATE_MAX, \
|
||||
.max = _max, \
|
||||
.network_byte_order = 0, \
|
||||
}
|
||||
|
||||
#define NLA_POLICY_MAX_BE(tp, _max) { \
|
||||
.type = NLA_ENSURE_UINT_TYPE(tp), \
|
||||
.validation_type = NLA_VALIDATE_MAX, \
|
||||
.max = _max, \
|
||||
.network_byte_order = 1, \
|
||||
}
|
||||
|
||||
#define NLA_POLICY_MASK(tp, _mask) { \
|
||||
|
@ -1889,6 +1889,13 @@ void sock_kfree_s(struct sock *sk, void *mem, int size);
|
||||
void sock_kzfree_s(struct sock *sk, void *mem, int size);
|
||||
void sk_send_sigurg(struct sock *sk);
|
||||
|
||||
static inline void sock_replace_proto(struct sock *sk, struct proto *proto)
|
||||
{
|
||||
if (sk->sk_socket)
|
||||
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
WRITE_ONCE(sk->sk_prot, proto);
|
||||
}
|
||||
|
||||
struct sockcm_cookie {
|
||||
u64 transmit_time;
|
||||
u32 mark;
|
||||
|
41
lib/nlattr.c
41
lib/nlattr.c
@ -124,10 +124,12 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
|
||||
range->max = U8_MAX;
|
||||
break;
|
||||
case NLA_U16:
|
||||
case NLA_BE16:
|
||||
case NLA_BINARY:
|
||||
range->max = U16_MAX;
|
||||
break;
|
||||
case NLA_U32:
|
||||
case NLA_BE32:
|
||||
range->max = U32_MAX;
|
||||
break;
|
||||
case NLA_U64:
|
||||
@ -159,31 +161,6 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
|
||||
}
|
||||
}
|
||||
|
||||
static u64 nla_get_attr_bo(const struct nla_policy *pt,
|
||||
const struct nlattr *nla)
|
||||
{
|
||||
switch (pt->type) {
|
||||
case NLA_U16:
|
||||
if (pt->network_byte_order)
|
||||
return ntohs(nla_get_be16(nla));
|
||||
|
||||
return nla_get_u16(nla);
|
||||
case NLA_U32:
|
||||
if (pt->network_byte_order)
|
||||
return ntohl(nla_get_be32(nla));
|
||||
|
||||
return nla_get_u32(nla);
|
||||
case NLA_U64:
|
||||
if (pt->network_byte_order)
|
||||
return be64_to_cpu(nla_get_be64(nla));
|
||||
|
||||
return nla_get_u64(nla);
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nla_validate_range_unsigned(const struct nla_policy *pt,
|
||||
const struct nlattr *nla,
|
||||
struct netlink_ext_ack *extack,
|
||||
@ -197,9 +174,13 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt,
|
||||
value = nla_get_u8(nla);
|
||||
break;
|
||||
case NLA_U16:
|
||||
value = nla_get_u16(nla);
|
||||
break;
|
||||
case NLA_U32:
|
||||
value = nla_get_u32(nla);
|
||||
break;
|
||||
case NLA_U64:
|
||||
value = nla_get_attr_bo(pt, nla);
|
||||
value = nla_get_u64(nla);
|
||||
break;
|
||||
case NLA_MSECS:
|
||||
value = nla_get_u64(nla);
|
||||
@ -207,6 +188,12 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt,
|
||||
case NLA_BINARY:
|
||||
value = nla_len(nla);
|
||||
break;
|
||||
case NLA_BE16:
|
||||
value = ntohs(nla_get_be16(nla));
|
||||
break;
|
||||
case NLA_BE32:
|
||||
value = ntohl(nla_get_be32(nla));
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -334,6 +321,8 @@ static int nla_validate_int_range(const struct nla_policy *pt,
|
||||
case NLA_U64:
|
||||
case NLA_MSECS:
|
||||
case NLA_BINARY:
|
||||
case NLA_BE16:
|
||||
case NLA_BE32:
|
||||
return nla_validate_range_unsigned(pt, nla, extack, validate);
|
||||
case NLA_S8:
|
||||
case NLA_S16:
|
||||
|
@ -1067,10 +1067,21 @@ int hci_conn_del(struct hci_conn *conn)
|
||||
hdev->acl_cnt += conn->sent;
|
||||
} else {
|
||||
struct hci_conn *acl = conn->link;
|
||||
|
||||
if (acl) {
|
||||
acl->link = NULL;
|
||||
hci_conn_drop(acl);
|
||||
}
|
||||
|
||||
/* Unacked ISO frames */
|
||||
if (conn->type == ISO_LINK) {
|
||||
if (hdev->iso_pkts)
|
||||
hdev->iso_cnt += conn->sent;
|
||||
else if (hdev->le_pkts)
|
||||
hdev->le_cnt += conn->sent;
|
||||
else
|
||||
hdev->acl_cnt += conn->sent;
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->amp_mgr)
|
||||
@ -1761,6 +1772,7 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
if (!cis)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
cis->cleanup = cis_cleanup;
|
||||
cis->dst_type = dst_type;
|
||||
}
|
||||
|
||||
if (cis->state == BT_CONNECTED)
|
||||
@ -2140,12 +2152,6 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
struct hci_conn *le;
|
||||
struct hci_conn *cis;
|
||||
|
||||
/* Convert from ISO socket address type to HCI address type */
|
||||
if (dst_type == BDADDR_LE_PUBLIC)
|
||||
dst_type = ADDR_LE_DEV_PUBLIC;
|
||||
else
|
||||
dst_type = ADDR_LE_DEV_RANDOM;
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
||||
le = hci_connect_le(hdev, dst, dst_type, false,
|
||||
BT_SECURITY_LOW,
|
||||
|
@ -235,6 +235,14 @@ static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline u8 le_addr_type(u8 bdaddr_type)
|
||||
{
|
||||
if (bdaddr_type == BDADDR_LE_PUBLIC)
|
||||
return ADDR_LE_DEV_PUBLIC;
|
||||
else
|
||||
return ADDR_LE_DEV_RANDOM;
|
||||
}
|
||||
|
||||
static int iso_connect_bis(struct sock *sk)
|
||||
{
|
||||
struct iso_conn *conn;
|
||||
@ -328,14 +336,16 @@ static int iso_connect_cis(struct sock *sk)
|
||||
/* Just bind if DEFER_SETUP has been set */
|
||||
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
|
||||
hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
|
||||
iso_pi(sk)->dst_type, &iso_pi(sk)->qos);
|
||||
le_addr_type(iso_pi(sk)->dst_type),
|
||||
&iso_pi(sk)->qos);
|
||||
if (IS_ERR(hcon)) {
|
||||
err = PTR_ERR(hcon);
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
|
||||
iso_pi(sk)->dst_type, &iso_pi(sk)->qos);
|
||||
le_addr_type(iso_pi(sk)->dst_type),
|
||||
&iso_pi(sk)->qos);
|
||||
if (IS_ERR(hcon)) {
|
||||
err = PTR_ERR(hcon);
|
||||
goto done;
|
||||
|
@ -1990,7 +1990,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
|
||||
if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
|
||||
continue;
|
||||
|
||||
if (c->psm == psm) {
|
||||
if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) {
|
||||
int src_match, dst_match;
|
||||
int src_any, dst_any;
|
||||
|
||||
@ -3764,7 +3764,8 @@ done:
|
||||
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
|
||||
sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
|
||||
|
||||
if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
|
||||
if (remote_efs &&
|
||||
test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
|
||||
chan->remote_id = efs.id;
|
||||
chan->remote_stype = efs.stype;
|
||||
chan->remote_msdu = le16_to_cpu(efs.msdu);
|
||||
@ -5813,6 +5814,19 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
|
||||
BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
|
||||
scid, mtu, mps);
|
||||
|
||||
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
|
||||
* page 1059:
|
||||
*
|
||||
* Valid range: 0x0001-0x00ff
|
||||
*
|
||||
* Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
|
||||
*/
|
||||
if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
|
||||
result = L2CAP_CR_LE_BAD_PSM;
|
||||
chan = NULL;
|
||||
goto response;
|
||||
}
|
||||
|
||||
/* Check if we have socket listening on psm */
|
||||
pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
|
||||
&conn->hcon->dst, LE_LINK);
|
||||
@ -6001,6 +6015,18 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||
|
||||
psm = req->psm;
|
||||
|
||||
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
|
||||
* page 1059:
|
||||
*
|
||||
* Valid range: 0x0001-0x00ff
|
||||
*
|
||||
* Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
|
||||
*/
|
||||
if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
|
||||
result = L2CAP_CR_LE_BAD_PSM;
|
||||
goto response;
|
||||
}
|
||||
|
||||
BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
|
||||
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
@ -6885,6 +6911,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
|
||||
struct l2cap_ctrl *control,
|
||||
struct sk_buff *skb, u8 event)
|
||||
{
|
||||
struct l2cap_ctrl local_control;
|
||||
int err = 0;
|
||||
bool skb_in_use = false;
|
||||
|
||||
@ -6909,15 +6936,32 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
|
||||
chan->buffer_seq = chan->expected_tx_seq;
|
||||
skb_in_use = true;
|
||||
|
||||
/* l2cap_reassemble_sdu may free skb, hence invalidate
|
||||
* control, so make a copy in advance to use it after
|
||||
* l2cap_reassemble_sdu returns and to avoid the race
|
||||
* condition, for example:
|
||||
*
|
||||
* The current thread calls:
|
||||
* l2cap_reassemble_sdu
|
||||
* chan->ops->recv == l2cap_sock_recv_cb
|
||||
* __sock_queue_rcv_skb
|
||||
* Another thread calls:
|
||||
* bt_sock_recvmsg
|
||||
* skb_recv_datagram
|
||||
* skb_free_datagram
|
||||
* Then the current thread tries to access control, but
|
||||
* it was freed by skb_free_datagram.
|
||||
*/
|
||||
local_control = *control;
|
||||
err = l2cap_reassemble_sdu(chan, skb, control);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
if (control->final) {
|
||||
if (local_control.final) {
|
||||
if (!test_and_clear_bit(CONN_REJ_ACT,
|
||||
&chan->conn_state)) {
|
||||
control->final = 0;
|
||||
l2cap_retransmit_all(chan, control);
|
||||
local_control.final = 0;
|
||||
l2cap_retransmit_all(chan, &local_control);
|
||||
l2cap_ertm_send(chan);
|
||||
}
|
||||
}
|
||||
@ -7297,11 +7341,27 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
|
||||
static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
/* l2cap_reassemble_sdu may free skb, hence invalidate control, so store
|
||||
* the txseq field in advance to use it after l2cap_reassemble_sdu
|
||||
* returns and to avoid the race condition, for example:
|
||||
*
|
||||
* The current thread calls:
|
||||
* l2cap_reassemble_sdu
|
||||
* chan->ops->recv == l2cap_sock_recv_cb
|
||||
* __sock_queue_rcv_skb
|
||||
* Another thread calls:
|
||||
* bt_sock_recvmsg
|
||||
* skb_recv_datagram
|
||||
* skb_free_datagram
|
||||
* Then the current thread tries to access control, but it was freed by
|
||||
* skb_free_datagram.
|
||||
*/
|
||||
u16 txseq = control->txseq;
|
||||
|
||||
BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
|
||||
chan->rx_state);
|
||||
|
||||
if (l2cap_classify_txseq(chan, control->txseq) ==
|
||||
L2CAP_TXSEQ_EXPECTED) {
|
||||
if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) {
|
||||
l2cap_pass_to_tx(chan, control);
|
||||
|
||||
BT_DBG("buffer_seq %u->%u", chan->buffer_seq,
|
||||
@ -7324,8 +7384,8 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
|
||||
}
|
||||
}
|
||||
|
||||
chan->last_acked_seq = control->txseq;
|
||||
chan->expected_tx_seq = __next_seq(chan, control->txseq);
|
||||
chan->last_acked_seq = txseq;
|
||||
chan->expected_tx_seq = __next_seq(chan, txseq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -7581,6 +7641,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
|
||||
return;
|
||||
}
|
||||
|
||||
l2cap_chan_hold(chan);
|
||||
l2cap_chan_lock(chan);
|
||||
} else {
|
||||
BT_DBG("unknown cid 0x%4.4x", cid);
|
||||
@ -8426,9 +8487,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
||||
* expected length.
|
||||
*/
|
||||
if (skb->len < L2CAP_LEN_SIZE) {
|
||||
if (l2cap_recv_frag(conn, skb, conn->mtu) < 0)
|
||||
goto drop;
|
||||
return;
|
||||
l2cap_recv_frag(conn, skb, conn->mtu);
|
||||
break;
|
||||
}
|
||||
|
||||
len = get_unaligned_le16(skb->data) + L2CAP_HDR_SIZE;
|
||||
@ -8472,7 +8532,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
||||
|
||||
/* Header still could not be read just continue */
|
||||
if (conn->rx_skb->len < L2CAP_LEN_SIZE)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (skb->len > conn->rx_len) {
|
||||
|
@ -1332,7 +1332,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
|
||||
|
||||
if (data[IFLA_BR_FDB_FLUSH]) {
|
||||
struct net_bridge_fdb_flush_desc desc = {
|
||||
.flags_mask = BR_FDB_STATIC
|
||||
.flags_mask = BIT(BR_FDB_STATIC)
|
||||
};
|
||||
|
||||
br_fdb_flush(br, &desc);
|
||||
|
@ -345,7 +345,7 @@ static int set_flush(struct net_bridge *br, unsigned long val,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net_bridge_fdb_flush_desc desc = {
|
||||
.flags_mask = BR_FDB_STATIC
|
||||
.flags_mask = BIT(BR_FDB_STATIC)
|
||||
};
|
||||
|
||||
br_fdb_flush(br, &desc);
|
||||
|
@ -409,7 +409,7 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
|
||||
write_lock_bh(&tbl->lock);
|
||||
neigh_flush_dev(tbl, dev, skip_perm);
|
||||
pneigh_ifdown_and_unlock(tbl, dev);
|
||||
pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev));
|
||||
pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
|
||||
if (skb_queue_empty_lockless(&tbl->proxy_queue))
|
||||
del_timer_sync(&tbl->proxy_timer);
|
||||
return 0;
|
||||
|
@ -1409,9 +1409,9 @@ static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp,
|
||||
static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
|
||||
const char *user_protocol)
|
||||
{
|
||||
const struct dsa_device_ops *tag_ops = NULL;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
struct dsa_switch_tree *dst = ds->dst;
|
||||
const struct dsa_device_ops *tag_ops;
|
||||
enum dsa_tag_protocol default_proto;
|
||||
|
||||
/* Find out which protocol the switch would prefer. */
|
||||
@ -1434,10 +1434,17 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
|
||||
}
|
||||
|
||||
tag_ops = dsa_find_tagger_by_name(user_protocol);
|
||||
} else {
|
||||
tag_ops = dsa_tag_driver_get(default_proto);
|
||||
if (IS_ERR(tag_ops)) {
|
||||
dev_warn(ds->dev,
|
||||
"Failed to find a tagging driver for protocol %s, using default\n",
|
||||
user_protocol);
|
||||
tag_ops = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tag_ops)
|
||||
tag_ops = dsa_tag_driver_get(default_proto);
|
||||
|
||||
if (IS_ERR(tag_ops)) {
|
||||
if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
|
||||
return -EPROBE_DEFER;
|
||||
|
@ -754,6 +754,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags,
|
||||
(TCPF_ESTABLISHED | TCPF_SYN_RECV |
|
||||
TCPF_CLOSE_WAIT | TCPF_CLOSE)));
|
||||
|
||||
if (test_bit(SOCK_SUPPORT_ZC, &sock->flags))
|
||||
set_bit(SOCK_SUPPORT_ZC, &newsock->flags);
|
||||
sock_graft(sk2, newsock);
|
||||
|
||||
newsock->state = SS_CONNECTED;
|
||||
|
@ -607,7 +607,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
} else {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
/* Pairs with lockless read in sk_clone_lock() */
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -620,7 +620,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
}
|
||||
|
||||
/* Pairs with lockless read in sk_clone_lock() */
|
||||
WRITE_ONCE(sk->sk_prot, &tcp_bpf_prots[family][config]);
|
||||
sock_replace_proto(sk, &tcp_bpf_prots[family][config]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_bpf_update_proto);
|
||||
|
@ -136,6 +136,9 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
|
||||
if (icsk->icsk_ulp_ops)
|
||||
goto out_err;
|
||||
|
||||
if (sk->sk_socket)
|
||||
clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
|
||||
err = ulp_ops->init(sk);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
@ -141,14 +141,14 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
|
||||
if (restore) {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sk->sk_family == AF_INET6)
|
||||
udp_bpf_check_v6_needs_rebuild(psock->sk_proto);
|
||||
|
||||
WRITE_ONCE(sk->sk_prot, &udp_bpf_prots[family]);
|
||||
sock_replace_proto(sk, &udp_bpf_prots[family]);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(udp_bpf_update_proto);
|
||||
|
@ -6555,10 +6555,16 @@ static void __net_exit ip6_route_net_exit(struct net *net)
|
||||
static int __net_init ip6_route_net_init_late(struct net *net)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_create_net("ipv6_route", 0, net->proc_net, &ipv6_route_seq_ops,
|
||||
sizeof(struct ipv6_route_iter));
|
||||
proc_create_net_single("rt6_stats", 0444, net->proc_net,
|
||||
rt6_stats_seq_show, NULL);
|
||||
if (!proc_create_net("ipv6_route", 0, net->proc_net,
|
||||
&ipv6_route_seq_ops,
|
||||
sizeof(struct ipv6_route_iter)))
|
||||
return -ENOMEM;
|
||||
|
||||
if (!proc_create_net_single("rt6_stats", 0444, net->proc_net,
|
||||
rt6_stats_seq_show, NULL)) {
|
||||
remove_proc_entry("ipv6_route", net->proc_net);
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ int udpv6_init_sock(struct sock *sk)
|
||||
{
|
||||
skb_queue_head_init(&udp_sk(sk)->reader_queue);
|
||||
sk->sk_destruct = udpv6_destruct_sock;
|
||||
set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -42,31 +42,8 @@
|
||||
#define AHASH_MAX_SIZE (6 * AHASH_INIT_SIZE)
|
||||
/* Max muber of elements in the array block when tuned */
|
||||
#define AHASH_MAX_TUNED 64
|
||||
|
||||
#define AHASH_MAX(h) ((h)->bucketsize)
|
||||
|
||||
/* Max number of elements can be tuned */
|
||||
#ifdef IP_SET_HASH_WITH_MULTI
|
||||
static u8
|
||||
tune_bucketsize(u8 curr, u32 multi)
|
||||
{
|
||||
u32 n;
|
||||
|
||||
if (multi < curr)
|
||||
return curr;
|
||||
|
||||
n = curr + AHASH_INIT_SIZE;
|
||||
/* Currently, at listing one hash bucket must fit into a message.
|
||||
* Therefore we have a hard limit here.
|
||||
*/
|
||||
return n > curr && n <= AHASH_MAX_TUNED ? n : curr;
|
||||
}
|
||||
#define TUNE_BUCKETSIZE(h, multi) \
|
||||
((h)->bucketsize = tune_bucketsize((h)->bucketsize, multi))
|
||||
#else
|
||||
#define TUNE_BUCKETSIZE(h, multi)
|
||||
#endif
|
||||
|
||||
/* A hash bucket */
|
||||
struct hbucket {
|
||||
struct rcu_head rcu; /* for call_rcu */
|
||||
@ -936,7 +913,12 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
|
||||
goto set_full;
|
||||
/* Create a new slot */
|
||||
if (n->pos >= n->size) {
|
||||
TUNE_BUCKETSIZE(h, multi);
|
||||
#ifdef IP_SET_HASH_WITH_MULTI
|
||||
if (h->bucketsize >= AHASH_MAX_TUNED)
|
||||
goto set_full;
|
||||
else if (h->bucketsize < multi)
|
||||
h->bucketsize += AHASH_INIT_SIZE;
|
||||
#endif
|
||||
if (n->size >= AHASH_MAX(h)) {
|
||||
/* Trigger rehashing */
|
||||
mtype_data_next(&h->next, d);
|
||||
|
@ -599,13 +599,19 @@ static const struct seq_operations ip_vs_app_seq_ops = {
|
||||
int __net_init ip_vs_app_net_init(struct netns_ipvs *ipvs)
|
||||
{
|
||||
INIT_LIST_HEAD(&ipvs->app_list);
|
||||
proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, &ip_vs_app_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
#ifdef CONFIG_PROC_FS
|
||||
if (!proc_create_net("ip_vs_app", 0, ipvs->net->proc_net,
|
||||
&ip_vs_app_seq_ops,
|
||||
sizeof(struct seq_net_private)))
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __net_exit ip_vs_app_net_cleanup(struct netns_ipvs *ipvs)
|
||||
{
|
||||
unregister_ip_vs_app(ipvs, NULL /* all */);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
remove_proc_entry("ip_vs_app", ipvs->net->proc_net);
|
||||
#endif
|
||||
}
|
||||
|
@ -1265,8 +1265,8 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
|
||||
* The drop rate array needs tuning for real environments.
|
||||
* Called from timer bh only => no locking
|
||||
*/
|
||||
static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
static char todrop_counter[9] = {0};
|
||||
static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
static signed char todrop_counter[9] = {0};
|
||||
int i;
|
||||
|
||||
/* if the conn entry hasn't lasted for 60 seconds, don't drop it.
|
||||
@ -1447,20 +1447,36 @@ int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs)
|
||||
{
|
||||
atomic_set(&ipvs->conn_count, 0);
|
||||
|
||||
proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
|
||||
&ip_vs_conn_seq_ops, sizeof(struct ip_vs_iter_state));
|
||||
proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
|
||||
&ip_vs_conn_sync_seq_ops,
|
||||
sizeof(struct ip_vs_iter_state));
|
||||
#ifdef CONFIG_PROC_FS
|
||||
if (!proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
|
||||
&ip_vs_conn_seq_ops,
|
||||
sizeof(struct ip_vs_iter_state)))
|
||||
goto err_conn;
|
||||
|
||||
if (!proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
|
||||
&ip_vs_conn_sync_seq_ops,
|
||||
sizeof(struct ip_vs_iter_state)))
|
||||
goto err_conn_sync;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
err_conn_sync:
|
||||
remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
|
||||
err_conn:
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs)
|
||||
{
|
||||
/* flush all the connection entries first */
|
||||
ip_vs_conn_flush(ipvs);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
|
||||
remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net);
|
||||
#endif
|
||||
}
|
||||
|
||||
int __init ip_vs_conn_init(void)
|
||||
|
@ -1152,7 +1152,16 @@ static int __init nf_nat_init(void)
|
||||
WARN_ON(nf_nat_hook != NULL);
|
||||
RCU_INIT_POINTER(nf_nat_hook, &nat_hook);
|
||||
|
||||
return register_nf_nat_bpf();
|
||||
ret = register_nf_nat_bpf();
|
||||
if (ret < 0) {
|
||||
RCU_INIT_POINTER(nf_nat_hook, NULL);
|
||||
nf_ct_helper_expectfn_unregister(&follow_master_nat);
|
||||
synchronize_net();
|
||||
unregister_pernet_subsys(&nat_net_ops);
|
||||
kvfree(nf_nat_bysource);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit nf_nat_cleanup(void)
|
||||
|
@ -8465,9 +8465,6 @@ static void nft_commit_release(struct nft_trans *trans)
|
||||
nf_tables_chain_destroy(&trans->ctx);
|
||||
break;
|
||||
case NFT_MSG_DELRULE:
|
||||
if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
|
||||
nft_flow_rule_destroy(nft_trans_flow_rule(trans));
|
||||
|
||||
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
|
||||
break;
|
||||
case NFT_MSG_DELSET:
|
||||
@ -8973,6 +8970,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
||||
nft_rule_expr_deactivate(&trans->ctx,
|
||||
nft_trans_rule(trans),
|
||||
NFT_TRANS_COMMIT);
|
||||
|
||||
if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
|
||||
nft_flow_rule_destroy(nft_trans_flow_rule(trans));
|
||||
break;
|
||||
case NFT_MSG_NEWSET:
|
||||
nft_clear(net, nft_trans_set(trans));
|
||||
@ -10030,6 +10030,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
|
||||
nft_net = nft_pernet(net);
|
||||
deleted = 0;
|
||||
mutex_lock(&nft_net->commit_mutex);
|
||||
if (!list_empty(&nf_tables_destroy_list))
|
||||
rcu_barrier();
|
||||
again:
|
||||
list_for_each_entry(table, &nft_net->tables, list) {
|
||||
if (nft_table_has_owner(table) &&
|
||||
|
@ -173,10 +173,10 @@ static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
|
||||
[NFTA_PAYLOAD_SREG] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_DREG] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_BASE] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_OFFSET] = NLA_POLICY_MAX_BE(NLA_U32, 255),
|
||||
[NFTA_PAYLOAD_LEN] = NLA_POLICY_MAX_BE(NLA_U32, 255),
|
||||
[NFTA_PAYLOAD_OFFSET] = NLA_POLICY_MAX(NLA_BE32, 255),
|
||||
[NFTA_PAYLOAD_LEN] = NLA_POLICY_MAX(NLA_BE32, 255),
|
||||
[NFTA_PAYLOAD_CSUM_TYPE] = { .type = NLA_U32 },
|
||||
[NFTA_PAYLOAD_CSUM_OFFSET] = NLA_POLICY_MAX_BE(NLA_U32, 255),
|
||||
[NFTA_PAYLOAD_CSUM_OFFSET] = NLA_POLICY_MAX(NLA_BE32, 255),
|
||||
[NFTA_PAYLOAD_CSUM_FLAGS] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
|
@ -2544,6 +2544,7 @@ struct genl_family dp_vport_genl_family __ro_after_init = {
|
||||
.parallel_ops = true,
|
||||
.small_ops = dp_vport_genl_ops,
|
||||
.n_small_ops = ARRAY_SIZE(dp_vport_genl_ops),
|
||||
.resv_start_op = OVS_VPORT_CMD_SET + 1,
|
||||
.mcgrps = &ovs_dp_vport_multicast_group,
|
||||
.n_mcgrps = 1,
|
||||
.module = THIS_MODULE,
|
||||
|
@ -236,6 +236,9 @@ void rose_transmit_clear_request(struct rose_neigh *neigh, unsigned int lci, uns
|
||||
unsigned char *dptr;
|
||||
int len;
|
||||
|
||||
if (!neigh->dev)
|
||||
return;
|
||||
|
||||
len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
|
||||
|
||||
if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
|
||||
|
@ -72,6 +72,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
{
|
||||
struct red_sched_data *q = qdisc_priv(sch);
|
||||
struct Qdisc *child = q->qdisc;
|
||||
unsigned int len;
|
||||
int ret;
|
||||
|
||||
q->vars.qavg = red_calc_qavg(&q->parms,
|
||||
@ -126,9 +127,10 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
break;
|
||||
}
|
||||
|
||||
len = qdisc_pkt_len(skb);
|
||||
ret = qdisc_enqueue(skb, child, to_free);
|
||||
if (likely(ret == NET_XMIT_SUCCESS)) {
|
||||
qdisc_qstats_backlog_inc(sch, skb);
|
||||
sch->qstats.backlog += len;
|
||||
sch->q.qlen++;
|
||||
} else if (net_xmit_drop_count(ret)) {
|
||||
q->stats.pdrop++;
|
||||
|
@ -3380,14 +3380,14 @@ static int __init smc_init(void)
|
||||
|
||||
rc = register_pernet_subsys(&smc_net_stat_ops);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto out_pernet_subsys;
|
||||
|
||||
smc_ism_init();
|
||||
smc_clc_init();
|
||||
|
||||
rc = smc_nl_init();
|
||||
if (rc)
|
||||
goto out_pernet_subsys;
|
||||
goto out_pernet_subsys_stat;
|
||||
|
||||
rc = smc_pnet_init();
|
||||
if (rc)
|
||||
@ -3480,6 +3480,8 @@ out_pnet:
|
||||
smc_pnet_exit();
|
||||
out_nl:
|
||||
smc_nl_exit();
|
||||
out_pernet_subsys_stat:
|
||||
unregister_pernet_subsys(&smc_net_stat_ops);
|
||||
out_pernet_subsys:
|
||||
unregister_pernet_subsys(&smc_net_ops);
|
||||
|
||||
|
@ -145,12 +145,12 @@ int unix_dgram_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool re
|
||||
|
||||
if (restore) {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unix_dgram_bpf_check_needs_rebuild(psock->sk_proto);
|
||||
WRITE_ONCE(sk->sk_prot, &unix_dgram_bpf_prot);
|
||||
sock_replace_proto(sk, &unix_dgram_bpf_prot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -158,12 +158,12 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r
|
||||
{
|
||||
if (restore) {
|
||||
sk->sk_write_space = psock->saved_write_space;
|
||||
WRITE_ONCE(sk->sk_prot, psock->sk_proto);
|
||||
sock_replace_proto(sk, psock->sk_proto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unix_stream_bpf_check_needs_rebuild(psock->sk_proto);
|
||||
WRITE_ONCE(sk->sk_prot, &unix_stream_bpf_prot);
|
||||
sock_replace_proto(sk, &unix_stream_bpf_prot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1905,8 +1905,11 @@ static int vsock_connectible_wait_data(struct sock *sk,
|
||||
err = 0;
|
||||
transport = vsk->transport;
|
||||
|
||||
while ((data = vsock_connectible_has_data(vsk)) == 0) {
|
||||
while (1) {
|
||||
prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE);
|
||||
data = vsock_connectible_has_data(vsk);
|
||||
if (data != 0)
|
||||
break;
|
||||
|
||||
if (sk->sk_err != 0 ||
|
||||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
|
||||
@ -2092,8 +2095,6 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
|
||||
const struct vsock_transport *transport;
|
||||
int err;
|
||||
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
sk = sock->sk;
|
||||
vsk = vsock_sk(sk);
|
||||
err = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user