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:
Linus Torvalds 2022-11-03 10:51:59 -07:00
commit 9521c9d6a5
50 changed files with 402 additions and 191 deletions

View File

@ -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

View File

@ -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)

View File

@ -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++) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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>");

View File

@ -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;
}
}

View File

@ -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))

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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)

View File

@ -132,12 +132,17 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
ret = -EREMOTEIO;
} else
ret = 0;
kfree_skb(skb);
}
if (ret) {
kfree_skb(skb);
return ret;
}
consume_skb(skb);
return 0;
}
static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
const void *param)
{

View File

@ -80,12 +80,15 @@ 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;
}
consume_skb(skb);
return 0;
}
static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
struct sk_buff *skb)
{

View File

@ -110,13 +110,17 @@ 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 0;
}
static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
{
struct s3fwrn5_info *info = nci_get_drvdata(ndev);

View File

@ -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) { \

View File

@ -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;

View File

@ -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:

View File

@ -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,

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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,9 +1434,16 @@ 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)

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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
}

View File

@ -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,
#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));
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)

View File

@ -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)

View File

@ -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) &&

View File

@ -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 },
};

View File

@ -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,

View File

@ -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)

View File

@ -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++;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;