Merge tag 'net-6.1-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Nov 2022 17:51:59 +0000 (10:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Nov 2022 17:51:59 +0000 (10:51 -0700)
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
  ...

50 files changed:
MAINTAINERS
drivers/bluetooth/virtio_bt.c
drivers/isdn/hardware/mISDN/netjet.c
drivers/isdn/mISDN/core.c
drivers/net/dsa/dsa_loop.c
drivers/net/ethernet/adi/adin1110.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
drivers/net/ethernet/microchip/lan966x/lan966x_main.c
drivers/net/ethernet/microchip/lan966x/lan966x_main.h
drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
drivers/net/ethernet/xilinx/xilinx_emaclite.c
drivers/net/phy/mdio_bus.c
drivers/net/tun.c
drivers/nfc/fdp/fdp.c
drivers/nfc/nfcmrvl/i2c.c
drivers/nfc/nxp-nci/core.c
drivers/nfc/s3fwrn5/core.c
include/net/netlink.h
include/net/sock.h
lib/nlattr.c
net/bluetooth/hci_conn.c
net/bluetooth/iso.c
net/bluetooth/l2cap_core.c
net/bridge/br_netlink.c
net/bridge/br_sysfs_br.c
net/core/neighbour.c
net/dsa/dsa2.c
net/ipv4/af_inet.c
net/ipv4/tcp_bpf.c
net/ipv4/tcp_ulp.c
net/ipv4/udp_bpf.c
net/ipv6/route.c
net/ipv6/udp.c
net/netfilter/ipset/ip_set_hash_gen.h
net/netfilter/ipvs/ip_vs_app.c
net/netfilter/ipvs/ip_vs_conn.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_payload.c
net/openvswitch/datapath.c
net/rose/rose_link.c
net/sched/sch_red.c
net/smc/af_smc.c
net/unix/unix_bpf.c
net/vmw_vsock/af_vsock.c

index 9774e7b..e1bc31a 100644 (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
index 67c2126..fd281d4 100644 (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)
index a52f275..f844713 100644 (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++) {
index a41b4b2..7ea0100 100644 (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;
 
 }
index b9107fe..5b139f2 100644 (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);
 
index 1744d62..606c976 100644 (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>");
index 28ef4d3..f623c12 100644 (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;
                }
        }
 
index 65dbfbe..9282381 100644 (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))
index a42035c..e694893 100644 (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)
index be2fd03..20ee5b2 100644 (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;
        }
index 9656071..4ec3399 100644 (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
index 1d90b93..fb5087f 100644 (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)
 
index 8d7260c..3c44660 100644 (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)
index 054d5ce..0556542 100644 (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;
 }
 
index 017dbbd..79fa787 100644 (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);
index 05848ff..a3967f8 100644 (file)
  * @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
index f82090b..1cd604c 100644 (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);
index 27c6d23..9466280 100644 (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();
index c6b3334..f12f903 100644 (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)
index acef0cf..24436c9 100644 (file)
@@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
                        ret = -EREMOTEIO;
                } else
                        ret = 0;
+       }
+
+       if (ret) {
                kfree_skb(skb);
+               return ret;
        }
 
-       return ret;
+       consume_skb(skb);
+       return 0;
 }
 
 static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
index 7c93d48..580cb6e 100644 (file)
@@ -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,
index 1c41200..0270e05 100644 (file)
@@ -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)
index 4418b19..6bfa972 100644 (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) {                   \
index 22f8bab..5db0254 100644 (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;
index 40f22b1..b67a53e 100644 (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:
index 7a59c44..a6c1286 100644 (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,
index 613039b..f825857 100644 (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;
index 1f34b82..9c24947 100644 (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) {
index 5aeb364..d087fd4 100644 (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);
index 612e367..ea73354 100644 (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);
index 3c4786b..a77a85e 100644 (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;
index af0e2c0..e504a18 100644 (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,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;
index 3dd0239..4728087 100644 (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;
index a1626af..c501c32 100644 (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);
index 7c27aa6..9ae50b1 100644 (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;
index ff15918..e5dc91d 100644 (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);
index 69252eb..2f355f0 100644 (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;
 }
index 129ec5a..bc65e5b 100644 (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;
 }
 
index 6e39130..3adc291 100644 (file)
 #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);
index f9b16f2..fdacbc3 100644 (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
 }
index 8c04bb5..13534e0 100644 (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,
-                       &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)
index 18319a6..e29e4cc 100644 (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)
index 58d9cbc..76bd4d0 100644 (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) &&
index 088244f..4edd899 100644 (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 },
 };
 
index 155263e..8b84869 100644 (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,
index 8b96a56..0f77ae8 100644 (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)
index a5a401f..9812932 100644 (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++;
index 3ccbf3c..e12d4fa 100644 (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);
 
index 7cf14c6..e9bf155 100644 (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;
 }
 
index ee41870..884eca7 100644 (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;