Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Nov 2015 02:11:41 +0000 (18:11 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Nov 2015 02:11:41 +0000 (18:11 -0800)
Pull networking fixes from David Miller:

 1) Fix null deref in xt_TEE netfilter module, from Eric Dumazet.

 2) Several spots need to get to the original listner for SYN-ACK
    packets, most spots got this ok but some were not.  Whilst covering
    the remaining cases, create a helper to do this.  From Eric Dumazet.

 3) Missiing check of return value from alloc_netdev() in CAIF SPI code,
    from Rasmus Villemoes.

 4) Don't sleep while != TASK_RUNNING in macvtap, from Vlad Yasevich.

 5) Use after free in mvneta driver, from Justin Maggard.

 6) Fix race on dst->flags access in dst_release(), from Eric Dumazet.

 7) Add missing ZLIB_INFLATE dependency for new qed driver.  From Arnd
    Bergmann.

 8) Fix multicast getsockopt deadlock, from WANG Cong.

 9) Fix deadlock in btusb, from Kuba Pawlak.

10) Some ipv6_add_dev() failure paths were not cleaning up the SNMP6
    counter state.  From Sabrina Dubroca.

11) Fix packet_bind() race, which can cause lost notifications, from
    Francesco Ruggeri.

12) Fix MAC restoration in qlcnic driver during bonding mode changes,
    from Jarod Wilson.

13) Revert bridging forward delay change which broke libvirt and other
    userspace things, from Vlad Yasevich.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (65 commits)
  Revert "bridge: Allow forward delay to be cfgd when STP enabled"
  bpf_trace: Make dependent on PERF_EVENTS
  qed: select ZLIB_INFLATE
  net: fix a race in dst_release()
  net: mvneta: Fix memory use after free.
  net: Documentation: Fix default value tcp_limit_output_bytes
  macvtap: Resolve possible __might_sleep warning in macvtap_do_read()
  mvneta: add FIXED_PHY dependency
  net: caif: check return value of alloc_netdev
  net: hisilicon: NET_VENDOR_HISILICON should depend on HAS_DMA
  drivers: net: xgene: fix RGMII 10/100Mb mode
  netfilter: nft_meta: use skb_to_full_sk() helper
  net_sched: em_meta: use skb_to_full_sk() helper
  sched: cls_flow: use skb_to_full_sk() helper
  netfilter: xt_owner: use skb_to_full_sk() helper
  smack: use skb_to_full_sk() helper
  net: add skb_to_full_sk() helper and use it in selinux_netlbl_skbuff_setsid()
  bpf: doc: correct arch list for supported eBPF JIT
  dwc_eth_qos: Delete an unnecessary check before the function call "of_node_put"
  bonding: fix panic on non-ARPHRD_ETHER enslave failure
  ...

68 files changed:
Documentation/devicetree/bindings/net/cpsw.txt
Documentation/networking/filter.txt
Documentation/networking/ip-sysctl.txt
drivers/bluetooth/btusb.c
drivers/net/bonding/bond_main.c
drivers/net/caif/caif_spi.c
drivers/net/dsa/mv88e6171.c
drivers/net/dsa/mv88e6352.c
drivers/net/dsa/mv88e6xxx.c
drivers/net/dsa/mv88e6xxx.h
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
drivers/net/ethernet/apm/xgene/xgene_enet_main.c
drivers/net/ethernet/broadcom/Kconfig
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
drivers/net/ethernet/hisilicon/Kconfig
drivers/net/ethernet/marvell/Kconfig
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/qlogic/Kconfig
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/synopsys/dwc_eth_qos.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/fjes/fjes_hw.c
drivers/net/macvtap.c
drivers/net/usb/qmi_wwan.c
drivers/nfc/nfcmrvl/Kconfig
drivers/nfc/nfcmrvl/fw_dnld.c
drivers/nfc/nfcmrvl/main.c
drivers/nfc/nfcmrvl/uart.c
include/linux/netdevice.h
include/linux/tcp.h
include/net/bluetooth/l2cap.h
include/net/dst_metadata.h
include/net/inet_sock.h
kernel/trace/Kconfig
lib/test_bpf.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bridge/br_stp.c
net/core/dev.c
net/core/dst.c
net/ipv4/fib_semantics.c
net/ipv4/igmp.c
net/ipv4/ip_sockglue.c
net/ipv4/netfilter/nf_defrag_ipv4.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv6/addrconf.c
net/ipv6/tcp_ipv6.c
net/netfilter/nf_nat_redirect.c
net/netfilter/nfnetlink.c
net/netfilter/nft_meta.c
net/netfilter/xt_TEE.c
net/netfilter/xt_owner.c
net/packet/af_packet.c
net/sched/cls_flow.c
net/sched/em_meta.c
net/vmw_vsock/vmci_transport.c
security/selinux/hooks.c
security/selinux/netlabel.c
security/smack/smack_netfilter.c

index 4efca560adda4b22f0498f123f053650e4427da5..9853f8e7096613e990c28cc545b39ab7f26afddc 100644 (file)
@@ -48,6 +48,11 @@ Optional properties:
 - mac-address          : See ethernet.txt file in the same directory
 - phy-handle           : See ethernet.txt file in the same directory
 
+Slave sub-nodes:
+- fixed-link           : See fixed-link.txt file in the same directory
+                         Either the properties phy_id and phy-mode,
+                         or the sub-node fixed-link can be specified
+
 Note: "ti,hwmods" field is used to fetch the base address and irq
 resources from TI, omap hwmod data base during device registration.
 Future plan is to migrate hwmod data base contents into device tree
index 135581f015e1eb4298c063ebd938ccf2ec2cb461..96da119a47e70fefa7844137c13ea33f070dc077 100644 (file)
@@ -596,9 +596,9 @@ skb pointer). All constraints and restrictions from bpf_check_classic() apply
 before a conversion to the new layout is being done behind the scenes!
 
 Currently, the classic BPF format is being used for JITing on most of the
-architectures. Only x86-64 performs JIT compilation from eBPF instruction set,
-however, future work will migrate other JIT compilers as well, so that they
-will profit from the very same benefits.
+architectures. x86-64, aarch64 and s390x perform JIT compilation from eBPF
+instruction set, however, future work will migrate other JIT compilers as well,
+so that they will profit from the very same benefits.
 
 Some core changes of the new internal format:
 
index 05915be862356cf75230851920af5d4738b095b5..2ea4c45cf1c8736ccd577eff75058bb32ed0ca95 100644 (file)
@@ -709,7 +709,7 @@ tcp_limit_output_bytes - INTEGER
        typical pfifo_fast qdiscs.
        tcp_limit_output_bytes limits the number of bytes on qdisc
        or device to reduce artificial RTT/cwnd and reduce bufferbloat.
-       Default: 131072
+       Default: 262144
 
 tcp_challenge_ack_limit - INTEGER
        Limits number of Challenge ACK sent per second, as recommended
index e33dacf5bd98765178ddac60f7d50d742de555ac..92f0ee388f9e0bfddd0cdf32b684edf25741d991 100644 (file)
@@ -1372,6 +1372,8 @@ static void btusb_work(struct work_struct *work)
                }
 
                if (data->isoc_altsetting != new_alts) {
+                       unsigned long flags;
+
                        clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
                        usb_kill_anchored_urbs(&data->isoc_anchor);
 
@@ -1384,10 +1386,10 @@ static void btusb_work(struct work_struct *work)
                         * Clear outstanding fragment when selecting a new
                         * alternate setting.
                         */
-                       spin_lock(&data->rxlock);
+                       spin_lock_irqsave(&data->rxlock, flags);
                        kfree_skb(data->sco_skb);
                        data->sco_skb = NULL;
-                       spin_unlock(&data->rxlock);
+                       spin_unlock_irqrestore(&data->rxlock, flags);
 
                        if (__set_isoc_interface(hdev, new_alts) < 0)
                                return;
index b4351caf8e013dbe15fcaf7402e8c9dbaeee9abb..9e0f8a7ef8b1695e0b79c8324e6adfe2e0ed9f4e 100644 (file)
@@ -1749,6 +1749,7 @@ err_undo_flags:
                                            slave_dev->dev_addr))
                        eth_hw_addr_random(bond_dev);
                if (bond_dev->type != ARPHRD_ETHER) {
+                       dev_close(bond_dev);
                        ether_setup(bond_dev);
                        bond_dev->flags |= IFF_MASTER;
                        bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
index de3962014af70c8a979f4cb63b063583ba4927a9..4721948a92f6a1db9cea13d66810041be5ec88e4 100644 (file)
@@ -730,11 +730,14 @@ int cfspi_spi_probe(struct platform_device *pdev)
        int res;
        dev = (struct cfspi_dev *)pdev->dev.platform_data;
 
-       ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d",
-                           NET_NAME_UNKNOWN, cfspi_setup);
        if (!dev)
                return -ENODEV;
 
+       ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d",
+                           NET_NAME_UNKNOWN, cfspi_setup);
+       if (!ndev)
+               return -ENOMEM;
+
        cfspi = netdev_priv(ndev);
        netif_stop_queue(ndev);
        cfspi->ndev = ndev;
index 54aa00012dd0ce5ca36427c0cfb41f773ea47138..6e18213b9c04434a1feaae0c87da255859632732 100644 (file)
@@ -103,6 +103,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 #endif
        .get_regs_len           = mv88e6xxx_get_regs_len,
        .get_regs               = mv88e6xxx_get_regs,
+       .port_join_bridge       = mv88e6xxx_port_bridge_join,
+       .port_leave_bridge      = mv88e6xxx_port_bridge_leave,
        .port_stp_update        = mv88e6xxx_port_stp_update,
        .port_pvid_get          = mv88e6xxx_port_pvid_get,
        .port_vlan_prepare      = mv88e6xxx_port_vlan_prepare,
index ff846d0cfcebeff1b332b8f8ae1ca48d106c667d..cc6c5455341839eb91ba55dfd23e96e954c41fb7 100644 (file)
@@ -323,6 +323,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
        .set_eeprom             = mv88e6352_set_eeprom,
        .get_regs_len           = mv88e6xxx_get_regs_len,
        .get_regs               = mv88e6xxx_get_regs,
+       .port_join_bridge       = mv88e6xxx_port_bridge_join,
+       .port_leave_bridge      = mv88e6xxx_port_bridge_leave,
        .port_stp_update        = mv88e6xxx_port_stp_update,
        .port_pvid_get          = mv88e6xxx_port_pvid_get,
        .port_vlan_prepare      = mv88e6xxx_port_vlan_prepare,
index 04cff58d771bd5a86f3b2a0bf2a047de1ee4b6f4..b06dba05594aaeb79988487bc431412b3dfae2c4 100644 (file)
@@ -1462,6 +1462,10 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
                                const struct switchdev_obj_port_vlan *vlan,
                                struct switchdev_trans *trans)
 {
+       /* We reserve a few VLANs to isolate unbridged ports */
+       if (vlan->vid_end >= 4000)
+               return -EOPNOTSUPP;
+
        /* We don't need any dynamic resource from the kernel (yet),
         * so skip the prepare phase.
         */
@@ -1870,6 +1874,36 @@ unlock:
        return err;
 }
 
+int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members)
+{
+       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+       const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port;
+       int err;
+
+       /* The port joined a bridge, so leave its reserved VLAN */
+       mutex_lock(&ps->smi_mutex);
+       err = _mv88e6xxx_port_vlan_del(ds, port, pvid);
+       if (!err)
+               err = _mv88e6xxx_port_pvid_set(ds, port, 0);
+       mutex_unlock(&ps->smi_mutex);
+       return err;
+}
+
+int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members)
+{
+       struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+       const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port;
+       int err;
+
+       /* The port left the bridge, so join its reserved VLAN */
+       mutex_lock(&ps->smi_mutex);
+       err = _mv88e6xxx_port_vlan_add(ds, port, pvid, true);
+       if (!err)
+               err = _mv88e6xxx_port_pvid_set(ds, port, pvid);
+       mutex_unlock(&ps->smi_mutex);
+       return err;
+}
+
 static void mv88e6xxx_bridge_work(struct work_struct *work)
 {
        struct mv88e6xxx_priv_state *ps;
@@ -2140,6 +2174,14 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
                ret = mv88e6xxx_setup_port(ds, i);
                if (ret < 0)
                        return ret;
+
+               if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
+                       continue;
+
+               /* setup the unbridged state */
+               ret = mv88e6xxx_port_bridge_leave(ds, i, 0);
+               if (ret < 0)
+                       return ret;
        }
        return 0;
 }
index fb9a8739712f3cfc8a4f1736d594d221dedeeb89..21c8daa03f788e369caa9eb2fe12c764607acd62 100644 (file)
@@ -468,6 +468,8 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
 int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
 int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
                      struct phy_device *phydev, struct ethtool_eee *e);
+int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members);
+int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members);
 int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
 int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
                                const struct switchdev_obj_port_vlan *vlan,
index 33850a0f7e823b08a322cd53107904da7d1f78da..c31e691d11fc2eb5b786fc3769f700563f63a0da 100644 (file)
@@ -459,6 +459,45 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
        xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
 }
 
+static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
+{
+       struct device *dev = &pdata->pdev->dev;
+
+       if (dev->of_node) {
+               struct clk *parent = clk_get_parent(pdata->clk);
+
+               switch (pdata->phy_speed) {
+               case SPEED_10:
+                       clk_set_rate(parent, 2500000);
+                       break;
+               case SPEED_100:
+                       clk_set_rate(parent, 25000000);
+                       break;
+               default:
+                       clk_set_rate(parent, 125000000);
+                       break;
+               }
+       }
+#ifdef CONFIG_ACPI
+       else {
+               switch (pdata->phy_speed) {
+               case SPEED_10:
+                       acpi_evaluate_object(ACPI_HANDLE(dev),
+                                            "S10", NULL, NULL);
+                       break;
+               case SPEED_100:
+                       acpi_evaluate_object(ACPI_HANDLE(dev),
+                                            "S100", NULL, NULL);
+                       break;
+               default:
+                       acpi_evaluate_object(ACPI_HANDLE(dev),
+                                            "S1G", NULL, NULL);
+                       break;
+               }
+       }
+#endif
+}
+
 static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
 {
        struct device *dev = &pdata->pdev->dev;
@@ -477,12 +516,14 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
        switch (pdata->phy_speed) {
        case SPEED_10:
                ENET_INTERFACE_MODE2_SET(&mc2, 1);
+               intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE);
                CFG_MACMODE_SET(&icm0, 0);
                CFG_WAITASYNCRD_SET(&icm2, 500);
                rgmii &= ~CFG_SPEED_1250;
                break;
        case SPEED_100:
                ENET_INTERFACE_MODE2_SET(&mc2, 1);
+               intf_ctl &= ~ENET_GHD_MODE;
                intf_ctl |= ENET_LHD_MODE;
                CFG_MACMODE_SET(&icm0, 1);
                CFG_WAITASYNCRD_SET(&icm2, 80);
@@ -490,12 +531,15 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
                break;
        default:
                ENET_INTERFACE_MODE2_SET(&mc2, 2);
+               intf_ctl &= ~ENET_LHD_MODE;
                intf_ctl |= ENET_GHD_MODE;
-
+               CFG_MACMODE_SET(&icm0, 2);
+               CFG_WAITASYNCRD_SET(&icm2, 0);
                if (dev->of_node) {
                        CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay);
                        CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay);
                }
+               rgmii |= CFG_SPEED_1250;
 
                xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value);
                value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
@@ -503,7 +547,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
                break;
        }
 
-       mc2 |= FULL_DUPLEX2;
+       mc2 |= FULL_DUPLEX2 | PAD_CRC;
        xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
        xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
 
@@ -522,6 +566,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
        /* Rtype should be copied from FP */
        xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0);
        xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);
+       xgene_enet_configure_clock(pdata);
 
        /* Rx-Tx traffic resume */
        xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
index 6dee73c3c1e132a7be7387e6e72be7c9b5239afe..c153a1dc5ff78136c4fc99d1ec60970d99e095a0 100644 (file)
@@ -181,6 +181,7 @@ enum xgene_enet_rm {
 #define ENET_LHD_MODE                  BIT(25)
 #define ENET_GHD_MODE                  BIT(26)
 #define FULL_DUPLEX2                   BIT(0)
+#define PAD_CRC                                BIT(2)
 #define SCAN_AUTO_INCR                 BIT(5)
 #define TBYT_ADDR                      0x38
 #define TPKT_ADDR                      0x39
index ce1068771b327e711fd1723065f9f3ad3c5dadc3..991412ce6f48fbbf6fdfd6255003a0aa90e67e01 100644 (file)
@@ -698,7 +698,6 @@ static int xgene_enet_open(struct net_device *ndev)
        else
                schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);
 
-       netif_carrier_off(ndev);
        netif_start_queue(ndev);
 
        return ret;
index 67a7d520d9f54fcf9eadf4fa81b05b17d76dd55a..8550df189ceb709290c8b1caad4a3132dcb6a810 100644 (file)
@@ -173,6 +173,7 @@ config SYSTEMPORT
 config BNXT
        tristate "Broadcom NetXtreme-C/E support"
        depends on PCI
+       depends on VXLAN || VXLAN=n
        select FW_LOADER
        select LIBCRC32C
        ---help---
index 6c2e0c622831c13f12fc1bd238bfc69f56cc5443..db15c5ee09c53a528ea405961734dae927af0e06 100644 (file)
@@ -1292,8 +1292,6 @@ static inline int bnxt_has_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
        return TX_CMP_VALID(txcmp, raw_cons);
 }
 
-#define CAG_LEGACY_INT_STATUS  0x2014
-
 static irqreturn_t bnxt_inta(int irq, void *dev_instance)
 {
        struct bnxt_napi *bnapi = dev_instance;
@@ -1305,7 +1303,7 @@ static irqreturn_t bnxt_inta(int irq, void *dev_instance)
        prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]);
 
        if (!bnxt_has_work(bp, cpr)) {
-               int_status = readl(bp->bar0 + CAG_LEGACY_INT_STATUS);
+               int_status = readl(bp->bar0 + BNXT_CAG_REG_LEGACY_INT_STATUS);
                /* return if erroneous interrupt */
                if (!(int_status & (0x10000 << cpr->cp_ring_struct.fw_ring_id)))
                        return IRQ_NONE;
@@ -4527,10 +4525,25 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
        return rc;
 }
 
+/* Common routine to pre-map certain register block to different GRC window.
+ * A PF has 16 4K windows and a VF has 4 4K windows. However, only 15 windows
+ * in PF and 3 windows in VF that can be customized to map in different
+ * register blocks.
+ */
+static void bnxt_preset_reg_win(struct bnxt *bp)
+{
+       if (BNXT_PF(bp)) {
+               /* CAG registers map to GRC window #4 */
+               writel(BNXT_CAG_REG_BASE,
+                      bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 12);
+       }
+}
+
 static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
 {
        int rc = 0;
 
+       bnxt_preset_reg_win(bp);
        netif_carrier_off(bp->dev);
        if (irq_re_init) {
                rc = bnxt_setup_int_mode(bp);
@@ -5294,7 +5307,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
        struct bnxt_ntuple_filter *fltr, *new_fltr;
        struct flow_keys *fkeys;
        struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb);
-       int rc = 0, idx;
+       int rc = 0, idx, bit_id;
        struct hlist_head *head;
 
        if (skb->encapsulation)
@@ -5332,14 +5345,15 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
        rcu_read_unlock();
 
        spin_lock_bh(&bp->ntp_fltr_lock);
-       new_fltr->sw_id = bitmap_find_free_region(bp->ntp_fltr_bmap,
-                                                 BNXT_NTP_FLTR_MAX_FLTR, 0);
-       if (new_fltr->sw_id < 0) {
+       bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap,
+                                        BNXT_NTP_FLTR_MAX_FLTR, 0);
+       if (bit_id < 0) {
                spin_unlock_bh(&bp->ntp_fltr_lock);
                rc = -ENOMEM;
                goto err_free;
        }
 
+       new_fltr->sw_id = (u16)bit_id;
        new_fltr->flow_id = flow_id;
        new_fltr->rxq = rxq_index;
        hlist_add_head_rcu(&new_fltr->hash, head);
index 4f2267ca482d1d7fcf2d32efbcccf966e5089445..674bc5159b91c7cd4972561fae11dd1bbed7d53c 100644 (file)
@@ -166,9 +166,11 @@ struct rx_cmp {
 #define RX_CMP_HASH_VALID(rxcmp)                               \
        ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID))
 
+#define RSS_PROFILE_ID_MASK    0x1f
+
 #define RX_CMP_HASH_TYPE(rxcmp)                                        \
-       ((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
-        RX_CMP_RSS_HASH_TYPE_SHIFT)
+       (((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
+         RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
 
 struct rx_cmp_ext {
        __le32 rx_cmp_flags2;
@@ -282,9 +284,9 @@ struct rx_tpa_start_cmp {
         cpu_to_le32(RX_TPA_START_CMP_FLAGS_RSS_VALID))
 
 #define TPA_START_HASH_TYPE(rx_tpa_start)                              \
-       ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) &       \
-         RX_TPA_START_CMP_RSS_HASH_TYPE) >>                            \
-        RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT)
+       (((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) &      \
+          RX_TPA_START_CMP_RSS_HASH_TYPE) >>                           \
+         RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
 
 #define TPA_START_AGG_ID(rx_tpa_start)                                 \
        ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) &       \
@@ -839,6 +841,10 @@ struct bnxt_queue_info {
        u8      queue_profile;
 };
 
+#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
+#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014
+#define BNXT_CAG_REG_BASE              0x300000
+
 struct bnxt {
        void __iomem            *bar0;
        void __iomem            *bar1;
@@ -959,11 +965,11 @@ struct bnxt {
 #define BNXT_RX_MASK_SP_EVENT          0
 #define BNXT_RX_NTP_FLTR_SP_EVENT      1
 #define BNXT_LINK_CHNG_SP_EVENT                2
-#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT        4
-#define BNXT_VXLAN_ADD_PORT_SP_EVENT   8
-#define BNXT_VXLAN_DEL_PORT_SP_EVENT   16
-#define BNXT_RESET_TASK_SP_EVENT       32
-#define BNXT_RST_RING_SP_EVENT         64
+#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT        3
+#define BNXT_VXLAN_ADD_PORT_SP_EVENT   4
+#define BNXT_VXLAN_DEL_PORT_SP_EVENT   5
+#define BNXT_RESET_TASK_SP_EVENT       6
+#define BNXT_RST_RING_SP_EVENT         7
 
        struct bnxt_pf_info     pf;
 #ifdef CONFIG_BNXT_SRIOV
index 60989e7e266a212033f39f58f9927bbdd3da4854..f4cf6886106906d90bff221038b83914d9bbbd24 100644 (file)
@@ -258,7 +258,7 @@ static int bnxt_set_vf_attr(struct bnxt *bp, int num_vfs)
        return 0;
 }
 
-static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp)
+static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp, int num_vfs)
 {
        int i, rc = 0;
        struct bnxt_pf_info *pf = &bp->pf;
@@ -267,7 +267,7 @@ static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp)
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1);
 
        mutex_lock(&bp->hwrm_cmd_lock);
-       for (i = pf->first_vf_id; i < pf->first_vf_id + pf->active_vfs; i++) {
+       for (i = pf->first_vf_id; i < pf->first_vf_id + num_vfs; i++) {
                req.vf_id = cpu_to_le16(i);
                rc = _hwrm_send_message(bp, &req, sizeof(req),
                                        HWRM_CMD_TIMEOUT);
@@ -509,7 +509,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
 
 err_out2:
        /* Free the resources reserved for various VF's */
-       bnxt_hwrm_func_vf_resource_free(bp);
+       bnxt_hwrm_func_vf_resource_free(bp, *num_vfs);
 
 err_out1:
        bnxt_free_vf_resources(bp);
@@ -519,13 +519,19 @@ err_out1:
 
 void bnxt_sriov_disable(struct bnxt *bp)
 {
-       if (!bp->pf.active_vfs)
-               return;
+       u16 num_vfs = pci_num_vf(bp->pdev);
 
-       pci_disable_sriov(bp->pdev);
+       if (!num_vfs)
+               return;
 
-       /* Free the resources reserved for various VF's */
-       bnxt_hwrm_func_vf_resource_free(bp);
+       if (pci_vfs_assigned(bp->pdev)) {
+               netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n",
+                           num_vfs);
+       } else {
+               pci_disable_sriov(bp->pdev);
+               /* Free the HW resources reserved for various VF's */
+               bnxt_hwrm_func_vf_resource_free(bp, num_vfs);
+       }
 
        bnxt_free_vf_resources(bp);
 
@@ -552,17 +558,25 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs)
        }
        bp->sriov_cfg = true;
        rtnl_unlock();
-       if (!num_vfs) {
-               bnxt_sriov_disable(bp);
-               return 0;
+
+       if (pci_vfs_assigned(bp->pdev)) {
+               netdev_warn(dev, "Unable to configure SRIOV since some VFs are assigned to VMs.\n");
+               num_vfs = 0;
+               goto sriov_cfg_exit;
        }
 
        /* Check if enabled VFs is same as requested */
-       if (num_vfs == bp->pf.active_vfs)
-               return 0;
+       if (num_vfs && num_vfs == bp->pf.active_vfs)
+               goto sriov_cfg_exit;
+
+       /* if there are previous existing VFs, clean them up */
+       bnxt_sriov_disable(bp);
+       if (!num_vfs)
+               goto sriov_cfg_exit;
 
        bnxt_sriov_enable(bp, &num_vfs);
 
+sriov_cfg_exit:
        bp->sriov_cfg = false;
        wake_up(&bp->sriov_cfg_wait);
 
index f250dec488fd2a2b908a0cb67bb2df61c53ac7ee..74beb1867230c9cf62a60a2843825316e6d9cdbc 100644 (file)
@@ -5,7 +5,8 @@
 config NET_VENDOR_HISILICON
        bool "Hisilicon devices"
        default y
-       depends on OF && (ARM || ARM64 || COMPILE_TEST)
+       depends on OF && HAS_DMA
+       depends on ARM || ARM64 || COMPILE_TEST
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
 
index 80af9ffce5ead1bd62e61499ff2e0ff9f6e04732..a1c862b4664de02667f7d4c751f1d9a7e8686ee6 100644 (file)
@@ -44,6 +44,7 @@ config MVNETA
        tristate "Marvell Armada 370/38x/XP network interface support"
        depends on PLAT_ORION
        select MVMDIO
+       select FIXED_PHY
        ---help---
          This driver supports the network interface units in the
          Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.
index a47496a020d99eb2b56f185c3be8f1cf797b567a..e84c7f2634d3759805326707a29c33737bcad615 100644 (file)
@@ -1493,9 +1493,9 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
                struct mvneta_rx_desc *rx_desc = rxq->descs + i;
                void *data = (void *)rx_desc->buf_cookie;
 
-               mvneta_frag_free(pp, data);
                dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
                                 MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
+               mvneta_frag_free(pp, data);
        }
 
        if (rx_done)
index 30a6f246dfc9f004ac68f4b2cc84658186dce9e6..ddcfcab034c23b122596b5e733708d8666737ae6 100644 (file)
@@ -94,6 +94,7 @@ config NETXEN_NIC
 config QED
        tristate "QLogic QED 25/40/100Gb core driver"
        depends on PCI
+       select ZLIB_INFLATE
        ---help---
          This enables the support for ...
 
index b9b7b7e6fa534cc70cd96a97aaf7afb12f734b3f..803b190ccada97b30b28098666146f9d05ad1c54 100644 (file)
@@ -223,6 +223,7 @@ int qed_resc_alloc(struct qed_dev *cdev)
                if (!p_hwfn->p_tx_cids) {
                        DP_NOTICE(p_hwfn,
                                  "Failed to allocate memory for Tx Cids\n");
+                       rc = -ENOMEM;
                        goto alloc_err;
                }
 
@@ -230,6 +231,7 @@ int qed_resc_alloc(struct qed_dev *cdev)
                if (!p_hwfn->p_rx_cids) {
                        DP_NOTICE(p_hwfn,
                                  "Failed to allocate memory for Rx Cids\n");
+                       rc = -ENOMEM;
                        goto alloc_err;
                }
        }
@@ -281,14 +283,17 @@ int qed_resc_alloc(struct qed_dev *cdev)
 
                /* EQ */
                p_eq = qed_eq_alloc(p_hwfn, 256);
-
-               if (!p_eq)
+               if (!p_eq) {
+                       rc = -ENOMEM;
                        goto alloc_err;
+               }
                p_hwfn->p_eq = p_eq;
 
                p_consq = qed_consq_alloc(p_hwfn);
-               if (!p_consq)
+               if (!p_consq) {
+                       rc = -ENOMEM;
                        goto alloc_err;
+               }
                p_hwfn->p_consq = p_consq;
 
                /* DMA info initialization */
@@ -303,6 +308,7 @@ int qed_resc_alloc(struct qed_dev *cdev)
        cdev->reset_stats = kzalloc(sizeof(*cdev->reset_stats), GFP_KERNEL);
        if (!cdev->reset_stats) {
                DP_NOTICE(cdev, "Failed to allocate reset statistics\n");
+               rc = -ENOMEM;
                goto alloc_err;
        }
 
@@ -562,7 +568,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
        }
 
        /* Enable classification by MAC if needed */
-       if (hw_mode & MODE_MF_SI) {
+       if (hw_mode & (1 << MODE_MF_SI)) {
                DP_VERBOSE(p_hwfn, NETIF_MSG_HW,
                           "Configuring TAGMAC_CLS_TYPE\n");
                STORE_RT_REG(p_hwfn,
index 2e399b6137a27899e97108cf5f35024f8b4d2ed0..de50e84902afe3b6a26c422d34a687ec9bc523ec 100644 (file)
@@ -251,11 +251,6 @@ void qed_int_sp_dpc(unsigned long hwfn_cookie)
        int arr_size;
        u16 rc = 0;
 
-       if (!p_hwfn) {
-               DP_ERR(p_hwfn->cdev, "DPC called - no hwfn!\n");
-               return;
-       }
-
        if (!p_hwfn->p_sp_sb) {
                DP_ERR(p_hwfn->cdev, "DPC called - no p_sp_sb\n");
                return;
index d4481454b5f8d8e6951c942d505f080074edc650..1205f6f9c941735a9f7bafb88e36705e4a5de7f2 100644 (file)
@@ -353,7 +353,8 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EINVAL;
 
-       if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data))
+       if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data) &&
+           ether_addr_equal_unaligned(netdev->dev_addr, addr->sa_data))
                return 0;
 
        if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
index 6150a235b72ccaf8bf58dd862362b02fe7f0cfae..e7bab7909ed9e1868dd5f8457b3cfc96c92788f1 100644 (file)
@@ -1098,7 +1098,7 @@ static struct mdiobb_ops bb_ops = {
 static void sh_eth_ring_free(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
-       int i;
+       int ringsize, i;
 
        /* Free Rx skb ringbuffer */
        if (mdp->rx_skbuff) {
@@ -1115,6 +1115,20 @@ static void sh_eth_ring_free(struct net_device *ndev)
        }
        kfree(mdp->tx_skbuff);
        mdp->tx_skbuff = NULL;
+
+       if (mdp->rx_ring) {
+               ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
+               dma_free_coherent(NULL, ringsize, mdp->rx_ring,
+                                 mdp->rx_desc_dma);
+               mdp->rx_ring = NULL;
+       }
+
+       if (mdp->tx_ring) {
+               ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
+               dma_free_coherent(NULL, ringsize, mdp->tx_ring,
+                                 mdp->tx_desc_dma);
+               mdp->tx_ring = NULL;
+       }
 }
 
 /* format skb and descriptor buffer */
@@ -1199,7 +1213,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
 static int sh_eth_ring_init(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
-       int rx_ringsize, tx_ringsize, ret = 0;
+       int rx_ringsize, tx_ringsize;
 
        /* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
         * card needs room to do 8 byte alignment, +2 so we can reserve
@@ -1214,26 +1228,20 @@ static int sh_eth_ring_init(struct net_device *ndev)
        /* Allocate RX and TX skb rings */
        mdp->rx_skbuff = kcalloc(mdp->num_rx_ring, sizeof(*mdp->rx_skbuff),
                                 GFP_KERNEL);
-       if (!mdp->rx_skbuff) {
-               ret = -ENOMEM;
-               return ret;
-       }
+       if (!mdp->rx_skbuff)
+               return -ENOMEM;
 
        mdp->tx_skbuff = kcalloc(mdp->num_tx_ring, sizeof(*mdp->tx_skbuff),
                                 GFP_KERNEL);
-       if (!mdp->tx_skbuff) {
-               ret = -ENOMEM;
-               goto skb_ring_free;
-       }
+       if (!mdp->tx_skbuff)
+               goto ring_free;
 
        /* Allocate all Rx descriptors. */
        rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
        mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
                                          GFP_KERNEL);
-       if (!mdp->rx_ring) {
-               ret = -ENOMEM;
-               goto skb_ring_free;
-       }
+       if (!mdp->rx_ring)
+               goto ring_free;
 
        mdp->dirty_rx = 0;
 
@@ -1241,42 +1249,15 @@ static int sh_eth_ring_init(struct net_device *ndev)
        tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
        mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
                                          GFP_KERNEL);
-       if (!mdp->tx_ring) {
-               ret = -ENOMEM;
-               goto desc_ring_free;
-       }
-       return ret;
-
-desc_ring_free:
-       /* free DMA buffer */
-       dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
+       if (!mdp->tx_ring)
+               goto ring_free;
+       return 0;
 
-skb_ring_free:
-       /* Free Rx and Tx skb ring buffer */
+ring_free:
+       /* Free Rx and Tx skb ring buffer and DMA buffer */
        sh_eth_ring_free(ndev);
-       mdp->tx_ring = NULL;
-       mdp->rx_ring = NULL;
-
-       return ret;
-}
-
-static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
-{
-       int ringsize;
-
-       if (mdp->rx_ring) {
-               ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
-               dma_free_coherent(NULL, ringsize, mdp->rx_ring,
-                                 mdp->rx_desc_dma);
-               mdp->rx_ring = NULL;
-       }
 
-       if (mdp->tx_ring) {
-               ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
-               dma_free_coherent(NULL, ringsize, mdp->tx_ring,
-                                 mdp->tx_desc_dma);
-               mdp->tx_ring = NULL;
-       }
+       return -ENOMEM;
 }
 
 static int sh_eth_dev_init(struct net_device *ndev, bool start)
@@ -2239,10 +2220,8 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
 
                sh_eth_dev_exit(ndev);
 
-               /* Free all the skbuffs in the Rx queue. */
+               /* Free all the skbuffs in the Rx queue and the DMA buffers. */
                sh_eth_ring_free(ndev);
-               /* Free DMA buffer */
-               sh_eth_free_dma_buffer(mdp);
        }
 
        /* Set new parameters */
@@ -2487,12 +2466,9 @@ static int sh_eth_close(struct net_device *ndev)
 
        free_irq(ndev->irq, ndev);
 
-       /* Free all the skbuffs in the Rx queue. */
+       /* Free all the skbuffs in the Rx queue and the DMA buffer. */
        sh_eth_ring_free(ndev);
 
-       /* free DMA buffer */
-       sh_eth_free_dma_buffer(mdp);
-
        pm_runtime_put_sync(&mdp->pdev->dev);
 
        mdp->is_opened = 0;
index 11baa4b197793f583eba9a5dc5c53aefb145ff9b..0cd3ecff768b3df5a3dbd7bdf2b73e06d81affff 100644 (file)
@@ -354,7 +354,7 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv)
 
 static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
 {
-       int phy_iface = phy_iface = bsp_priv->phy_iface;
+       int phy_iface = bsp_priv->phy_iface;
 
        if (enable) {
                if (!bsp_priv->clk_enabled) {
index 85b3326775b821f99be5d5e3dc5a065517797852..9066d7a8483c34ed5ee1ca2a697453eb55564584 100644 (file)
@@ -2970,8 +2970,7 @@ err_out_unregister_netdev:
 err_out_clk_dis_aper:
        clk_disable_unprepare(lp->apb_pclk);
 err_out_free_netdev:
-       if (lp->phy_node)
-               of_node_put(lp->phy_node);
+       of_node_put(lp->phy_node);
        free_netdev(ndev);
        platform_set_drvdata(pdev, NULL);
        return ret;
index 040fbc1e55080a4d025df2a2fae888da6151008c..48b92c9de12a5af4f75ab6b48b4ffd39a77d6ed5 100644 (file)
@@ -2037,6 +2037,19 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
                        continue;
 
                priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0);
+               if (of_phy_is_fixed_link(slave_node)) {
+                       struct phy_device *pd;
+
+                       ret = of_phy_register_fixed_link(slave_node);
+                       if (ret)
+                               return ret;
+                       pd = of_phy_find_device(slave_node);
+                       if (!pd)
+                               return -ENODEV;
+                       snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
+                                PHY_ID_FMT, pd->bus->id, pd->phy_id);
+                       goto no_phy_slave;
+               }
                parp = of_get_property(slave_node, "phy_id", &lenp);
                if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
                        dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i);
index 2d3848c9dc35a7f0047fb0189c0669b70dc776dc..bb8b5304d85117354595d707585613e572ce24c0 100644 (file)
@@ -143,9 +143,7 @@ static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh)
 
 static void fjes_hw_free_epbuf(struct epbuf_handler *epbh)
 {
-       if (epbh->buffer)
-               vfree(epbh->buffer);
-
+       vfree(epbh->buffer);
        epbh->buffer = NULL;
        epbh->size = 0;
 
index 197c93937c2d577e56cf7fab8dcef07313bf75f4..54036ae0a388c9a34cbb92fc832980fc1e584dc2 100644 (file)
@@ -935,6 +935,9 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
                /* Nothing to read, let's sleep */
                schedule();
        }
+       if (!noblock)
+               finish_wait(sk_sleep(&q->sk), &wait);
+
        if (skb) {
                ret = macvtap_put_user(q, skb, to);
                if (unlikely(ret < 0))
@@ -942,8 +945,6 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
                else
                        consume_skb(skb);
        }
-       if (!noblock)
-               finish_wait(sk_sleep(&q->sk), &wait);
        return ret;
 }
 
index c54719984c4bdd0da0e36dd54ab1430708483b0b..34799eaace41bcdb93cfa4c1ed76af31ae052ef3 100644 (file)
@@ -771,6 +771,7 @@ static const struct usb_device_id products[] = {
        {QMI_GOBI_DEVICE(0x05c6, 0x9245)},      /* Samsung Gobi 2000 Modem device (VL176) */
        {QMI_GOBI_DEVICE(0x03f0, 0x251d)},      /* HP Gobi 2000 Modem device (VP412) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9215)},      /* Acer Gobi 2000 Modem device (VP413) */
+       {QMI_FIXED_INTF(0x05c6, 0x9215, 4)},    /* Quectel EC20 Mini PCIe */
        {QMI_GOBI_DEVICE(0x05c6, 0x9265)},      /* Asus Gobi 2000 Modem device (VR305) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9235)},      /* Top Global Gobi 2000 Modem device (VR306) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9275)},      /* iRex Technologies Gobi 2000 Modem device (VR307) */
@@ -802,10 +803,24 @@ static const struct usb_device_id products[] = {
 };
 MODULE_DEVICE_TABLE(usb, products);
 
+static bool quectel_ec20_detected(struct usb_interface *intf)
+{
+       struct usb_device *dev = interface_to_usbdev(intf);
+
+       if (dev->actconfig &&
+           le16_to_cpu(dev->descriptor.idVendor) == 0x05c6 &&
+           le16_to_cpu(dev->descriptor.idProduct) == 0x9215 &&
+           dev->actconfig->desc.bNumInterfaces == 5)
+               return true;
+
+       return false;
+}
+
 static int qmi_wwan_probe(struct usb_interface *intf,
                          const struct usb_device_id *prod)
 {
        struct usb_device_id *id = (struct usb_device_id *)prod;
+       struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
 
        /* Workaround to enable dynamic IDs.  This disables usbnet
         * blacklisting functionality.  Which, if required, can be
@@ -817,6 +832,12 @@ static int qmi_wwan_probe(struct usb_interface *intf,
                id->driver_info = (unsigned long)&qmi_wwan_info;
        }
 
+       /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */
+       if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) {
+               dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n");
+               return -ENODEV;
+       }
+
        return usbnet_probe(intf, id);
 }
 
index 444ca94697d96e213d69020f14e4535e0366f3e4..670af76922e03e94c8f33f8399b01df7afefae00 100644 (file)
@@ -44,7 +44,7 @@ config NFC_MRVL_I2C
 
 config NFC_MRVL_SPI
        tristate "Marvell NFC-over-SPI driver"
-       depends on NFC_MRVL && SPI
+       depends on NFC_MRVL && NFC_NCI_SPI
        help
          Marvell NFC-over-SPI driver.
 
index bfa771392b1fb47669b914f9000a8f2be6fd9133..f8dcdf4b24f6ff8b63a1a70e9e5249b997209780 100644 (file)
@@ -113,9 +113,12 @@ static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error)
        }
 
        atomic_set(&priv->ndev->cmd_cnt, 0);
-       del_timer_sync(&priv->ndev->cmd_timer);
 
-       del_timer_sync(&priv->fw_dnld.timer);
+       if (timer_pending(&priv->ndev->cmd_timer))
+               del_timer_sync(&priv->ndev->cmd_timer);
+
+       if (timer_pending(&priv->fw_dnld.timer))
+               del_timer_sync(&priv->fw_dnld.timer);
 
        nfc_info(priv->dev, "FW loading over (%d)]\n", error);
 
@@ -472,9 +475,12 @@ void       nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv)
 void   nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv,
                                   struct sk_buff *skb)
 {
+       /* Discard command timer */
+       if (timer_pending(&priv->ndev->cmd_timer))
+               del_timer_sync(&priv->ndev->cmd_timer);
+
        /* Allow next command */
        atomic_set(&priv->ndev->cmd_cnt, 1);
-       del_timer_sync(&priv->ndev->cmd_timer);
 
        /* Queue and trigger rx work */
        skb_queue_tail(&priv->fw_dnld.rx_q, skb);
index 8079ae0de21ebac54153e7202bb469ae413ed765..51c8240a1672a1a329d40b4cb97dbf3582e48f83 100644 (file)
@@ -194,6 +194,9 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
 
        nfcmrvl_fw_dnld_deinit(priv);
 
+       if (priv->config.reset_n_io)
+               devm_gpio_free(priv->dev, priv->config.reset_n_io);
+
        nci_unregister_device(ndev);
        nci_free_device(ndev);
        kfree(priv);
@@ -251,8 +254,6 @@ void nfcmrvl_chip_halt(struct nfcmrvl_private *priv)
                gpio_set_value(priv->config.reset_n_io, 0);
 }
 
-#ifdef CONFIG_OF
-
 int nfcmrvl_parse_dt(struct device_node *node,
                     struct nfcmrvl_platform_data *pdata)
 {
@@ -275,16 +276,6 @@ int nfcmrvl_parse_dt(struct device_node *node,
 
        return 0;
 }
-
-#else
-
-int nfcmrvl_parse_dt(struct device_node *node,
-                    struct nfcmrvl_platform_data *pdata)
-{
-       return -ENODEV;
-}
-
-#endif
 EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt);
 
 MODULE_AUTHOR("Marvell International Ltd.");
index f3d041c4f249e05dced87bd76786bc8a612fd915..83a99e38e7bd316d949e44d1bc530865ac22befe 100644 (file)
@@ -67,8 +67,6 @@ static struct nfcmrvl_if_ops uart_ops = {
        .nci_update_config = nfcmrvl_uart_nci_update_config
 };
 
-#ifdef CONFIG_OF
-
 static int nfcmrvl_uart_parse_dt(struct device_node *node,
                                 struct nfcmrvl_platform_data *pdata)
 {
@@ -102,16 +100,6 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
        return 0;
 }
 
-#else
-
-static int nfcmrvl_uart_parse_dt(struct device_node *node,
-                                struct nfcmrvl_platform_data *pdata)
-{
-       return -ENODEV;
-}
-
-#endif
-
 /*
 ** NCI UART OPS
 */
@@ -152,10 +140,6 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
        nu->drv_data = priv;
        nu->ndev = priv->ndev;
 
-       /* Set BREAK */
-       if (priv->config.break_control && nu->tty->ops->break_ctl)
-               nu->tty->ops->break_ctl(nu->tty, -1);
-
        return 0;
 }
 
@@ -174,6 +158,9 @@ static void nfcmrvl_nci_uart_tx_start(struct nci_uart *nu)
 {
        struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data;
 
+       if (priv->ndev->nfc_dev->fw_download_in_progress)
+               return;
+
        /* Remove BREAK to wake up the NFCC */
        if (priv->config.break_control && nu->tty->ops->break_ctl) {
                nu->tty->ops->break_ctl(nu->tty, 0);
@@ -185,13 +172,18 @@ static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu)
 {
        struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data;
 
+       if (priv->ndev->nfc_dev->fw_download_in_progress)
+               return;
+
        /*
        ** To ensure that if the NFCC goes in DEEP SLEEP sate we can wake him
        ** up. we set BREAK. Once we will be ready to send again we will remove
        ** it.
        */
-       if (priv->config.break_control && nu->tty->ops->break_ctl)
+       if (priv->config.break_control && nu->tty->ops->break_ctl) {
                nu->tty->ops->break_ctl(nu->tty, -1);
+               usleep_range(1000, 3000);
+       }
 }
 
 static struct nci_uart nfcmrvl_nci_uart = {
index a9e3bf42d287317b17d5a6666658ba34b22381f8..d20891465247dfaa983225ce9336b14c91cb7fab 100644 (file)
@@ -1322,6 +1322,7 @@ enum netdev_priv_flags {
 #define IFF_L3MDEV_MASTER              IFF_L3MDEV_MASTER
 #define IFF_NO_QUEUE                   IFF_NO_QUEUE
 #define IFF_OPENVSWITCH                        IFF_OPENVSWITCH
+#define IFF_L3MDEV_SLAVE               IFF_L3MDEV_SLAVE
 
 /**
  *     struct net_device - The DEVICE structure.
index c906f453458119324414f984ee60056194093988..b386361ba3e87226c329924bc1992252fcf0b9d6 100644 (file)
@@ -397,6 +397,13 @@ static inline void fastopen_queue_tune(struct sock *sk, int backlog)
        queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn);
 }
 
+static inline void tcp_move_syn(struct tcp_sock *tp,
+                               struct request_sock *req)
+{
+       tp->saved_syn = req->saved_syn;
+       req->saved_syn = NULL;
+}
+
 static inline void tcp_saved_syn_free(struct tcp_sock *tp)
 {
        kfree(tp->saved_syn);
index c98afc08cc2612e046cd070b22d25aa18a88c457..52899291f40144c0dab97e135b0c9762ade5c8d1 100644 (file)
@@ -275,6 +275,8 @@ struct l2cap_conn_rsp {
 #define L2CAP_CR_AUTHORIZATION 0x0006
 #define L2CAP_CR_BAD_KEY_SIZE  0x0007
 #define L2CAP_CR_ENCRYPTION    0x0008
+#define L2CAP_CR_INVALID_SCID  0x0009
+#define L2CAP_CR_SCID_IN_USE   0x0010
 
 /* connect/create channel status */
 #define L2CAP_CS_NO_INFO       0x0000
index ce009710120ca8b541615b237a329ee089ec357b..6816f0fa5693dc275e1e4997375f29b5d99f7b64 100644 (file)
@@ -63,12 +63,13 @@ static inline struct metadata_dst *tun_rx_dst(int md_size)
 static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
 {
        struct metadata_dst *md_dst = skb_metadata_dst(skb);
-       int md_size = md_dst->u.tun_info.options_len;
+       int md_size;
        struct metadata_dst *new_md;
 
        if (!md_dst)
                return ERR_PTR(-EINVAL);
 
+       md_size = md_dst->u.tun_info.options_len;
        new_md = metadata_dst_alloc(md_size, GFP_ATOMIC);
        if (!new_md)
                return ERR_PTR(-ENOMEM);
index f5bf7310e3343468bddf7e51940a77ed497ad7f1..2134e6d815bcb0611a2f65cd7b4da44cb7762b8c 100644 (file)
@@ -210,6 +210,18 @@ struct inet_sock {
 #define IP_CMSG_ORIGDSTADDR    BIT(6)
 #define IP_CMSG_CHECKSUM       BIT(7)
 
+/* SYNACK messages might be attached to request sockets.
+ * Some places want to reach the listener in this case.
+ */
+static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
+{
+       struct sock *sk = skb->sk;
+
+       if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
+               sk = inet_reqsk(sk)->rsk_listener;
+       return sk;
+}
+
 static inline struct inet_sock *inet_sk(const struct sock *sk)
 {
        return (struct inet_sock *)sk;
index 8d6363f42169c62c61e9a035d615a89966135b0f..e45db6b0d8784a762fb5d088fea8b731135c05ae 100644 (file)
@@ -434,7 +434,7 @@ config UPROBE_EVENT
 
 config BPF_EVENTS
        depends on BPF_SYSCALL
-       depends on KPROBE_EVENT || UPROBE_EVENT
+       depends on (KPROBE_EVENT || UPROBE_EVENT) && PERF_EVENTS
        bool
        default y
        help
index d1377390b3adda70bafe7464186e034d1fd7bd01..10cd1860e5b04aa339853ff893855941aba41600 100644 (file)
@@ -5055,6 +5055,36 @@ static struct bpf_test tests[] = {
                {},
                { {0x1, 0x0 } },
        },
+       {
+               "MOD default X",
+               .u.insns = {
+                       /*
+                        * A = 0x42
+                        * A = A mod X ; this halt the filter execution if X is 0
+                        * ret 0x42
+                        */
+                       BPF_STMT(BPF_LD | BPF_IMM, 0x42),
+                       BPF_STMT(BPF_ALU | BPF_MOD | BPF_X, 0),
+                       BPF_STMT(BPF_RET | BPF_K, 0x42),
+               },
+               CLASSIC | FLAG_NO_DATA,
+               {},
+               { {0x1, 0x0 } },
+       },
+       {
+               "MOD default A",
+               .u.insns = {
+                       /*
+                        * A = A mod 1
+                        * ret A
+                        */
+                       BPF_STMT(BPF_ALU | BPF_MOD | BPF_K, 0x1),
+                       BPF_STMT(BPF_RET | BPF_A, 0x0),
+               },
+               CLASSIC | FLAG_NO_DATA,
+               {},
+               { {0x1, 0x0 } },
+       },
        {
                "JMP EQ default A",
                .u.insns = {
index 83a6aacfab31cb136745001a03fcb6368d7b259f..62edbf1b114e8371fe7167eb81d75c59ebe47908 100644 (file)
@@ -508,12 +508,6 @@ static void le_setup(struct hci_request *req)
        /* Read LE Supported States */
        hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
 
-       /* Read LE White List Size */
-       hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
-
-       /* Clear LE White List */
-       hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
-
        /* LE-only controllers have LE implicitly enabled */
        if (!lmp_bredr_capable(hdev))
                hci_dev_set_flag(hdev, HCI_LE_ENABLED);
@@ -832,6 +826,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
                        hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
                }
 
+               if (hdev->commands[26] & 0x40) {
+                       /* Read LE White List Size */
+                       hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE,
+                                   0, NULL);
+               }
+
+               if (hdev->commands[26] & 0x80) {
+                       /* Clear LE White List */
+                       hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
+               }
+
                if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
                        /* Read LE Maximum Data Length */
                        hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
index 7c65ee200c29215c6b3f050cfbb881873be4946a..66e8b6ee19a525d8cc54032843934b0fedb11dc7 100644 (file)
@@ -239,7 +239,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
        else
                dyn_end = L2CAP_CID_DYN_END;
 
-       for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
+       for (cid = L2CAP_CID_DYN_START; cid <= dyn_end; cid++) {
                if (!__l2cap_get_chan_by_scid(conn, cid))
                        return cid;
        }
@@ -5250,7 +5250,9 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
        credits = __le16_to_cpu(rsp->credits);
        result  = __le16_to_cpu(rsp->result);
 
-       if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
+       if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 ||
+                                          dcid < L2CAP_CID_DYN_START ||
+                                          dcid > L2CAP_CID_LE_DYN_END))
                return -EPROTO;
 
        BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
@@ -5270,6 +5272,11 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
 
        switch (result) {
        case L2CAP_CR_SUCCESS:
+               if (__l2cap_get_chan_by_dcid(conn, dcid)) {
+                       err = -EBADSLT;
+                       break;
+               }
+
                chan->ident = 0;
                chan->dcid = dcid;
                chan->omtu = mtu;
@@ -5437,9 +5444,16 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
                goto response_unlock;
        }
 
+       /* Check for valid dynamic CID range */
+       if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
+               result = L2CAP_CR_INVALID_SCID;
+               chan = NULL;
+               goto response_unlock;
+       }
+
        /* Check if we already have channel with that dcid */
        if (__l2cap_get_chan_by_dcid(conn, scid)) {
-               result = L2CAP_CR_NO_MEM;
+               result = L2CAP_CR_SCID_IN_USE;
                chan = NULL;
                goto response_unlock;
        }
index 80c34d70218c0f9d2066016e3f5ba5fc56656490..f7e8dee64fc80ec04152788c945dea1b346b3dcd 100644 (file)
@@ -600,12 +600,17 @@ void __br_set_forward_delay(struct net_bridge *br, unsigned long t)
 int br_set_forward_delay(struct net_bridge *br, unsigned long val)
 {
        unsigned long t = clock_t_to_jiffies(val);
-
-       if (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)
-               return -ERANGE;
+       int err = -ERANGE;
 
        spin_lock_bh(&br->lock);
+       if (br->stp_enabled != BR_NO_STP &&
+           (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY))
+               goto unlock;
+
        __br_set_forward_delay(br, t);
+       err = 0;
+
+unlock:
        spin_unlock_bh(&br->lock);
-       return 0;
+       return err;
 }
index 8ce3f74cd6b99d68445065a96772a388c927fb7d..ab9b8d0d115e4ce479fed2aa8304947be09f1f32 100644 (file)
@@ -6402,7 +6402,7 @@ int __netdev_update_features(struct net_device *dev)
        struct net_device *upper, *lower;
        netdev_features_t features;
        struct list_head *iter;
-       int err = 0;
+       int err = -1;
 
        ASSERT_RTNL();
 
@@ -6419,7 +6419,7 @@ int __netdev_update_features(struct net_device *dev)
                features = netdev_sync_upper_features(dev, upper, features);
 
        if (dev->features == features)
-               return 0;
+               goto sync_lower;
 
        netdev_dbg(dev, "Features changed: %pNF -> %pNF\n",
                &dev->features, &features);
@@ -6434,6 +6434,7 @@ int __netdev_update_features(struct net_device *dev)
                return -1;
        }
 
+sync_lower:
        /* some features must be disabled on lower devices when disabled
         * on an upper device (think: bonding master or bridge)
         */
@@ -6443,7 +6444,7 @@ int __netdev_update_features(struct net_device *dev)
        if (!err)
                dev->features = features;
 
-       return 1;
+       return err < 0 ? 0 : 1;
 }
 
 /**
index 2a1818065e126d4645076f391e4dd689051e9d43..e6dc77252fe9fa3e401529426079f094c9f6f999 100644 (file)
@@ -306,7 +306,7 @@ void dst_release(struct dst_entry *dst)
                if (unlikely(newrefcnt < 0))
                        net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
                                             __func__, dst, newrefcnt);
-               if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt)
+               if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
                        call_rcu(&dst->rcu_head, dst_destroy_rcu);
        }
 }
index 3e87447e65c777ff969d366136d2015e3cf9a8e2..d97268e8ff103bd229de4fb99bbb40f51e61082d 100644 (file)
@@ -923,14 +923,21 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
        if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
            fib_prefsrc != cfg->fc_dst) {
                u32 tb_id = cfg->fc_table;
+               int rc;
 
                if (tb_id == RT_TABLE_MAIN)
                        tb_id = RT_TABLE_LOCAL;
 
-               if (inet_addr_type_table(cfg->fc_nlinfo.nl_net,
-                                        fib_prefsrc, tb_id) != RTN_LOCAL) {
-                       return false;
+               rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net,
+                                         fib_prefsrc, tb_id);
+
+               if (rc != RTN_LOCAL && tb_id != RT_TABLE_LOCAL) {
+                       rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net,
+                                                 fib_prefsrc, RT_TABLE_LOCAL);
                }
+
+               if (rc != RTN_LOCAL)
+                       return false;
        }
        return true;
 }
index 64aaf3522a59f30672689f7309987606773ccb0c..6baf36e11808e5c93c2e092139bed60cdacc4c8a 100644 (file)
@@ -2392,11 +2392,11 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
        struct ip_sf_socklist *psl;
        struct net *net = sock_net(sk);
 
+       ASSERT_RTNL();
+
        if (!ipv4_is_multicast(addr))
                return -EINVAL;
 
-       rtnl_lock();
-
        imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
        imr.imr_address.s_addr = msf->imsf_interface;
        imr.imr_ifindex = 0;
@@ -2417,7 +2417,6 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
                goto done;
        msf->imsf_fmode = pmc->sfmode;
        psl = rtnl_dereference(pmc->sflist);
-       rtnl_unlock();
        if (!psl) {
                len = 0;
                count = 0;
@@ -2436,7 +2435,6 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
                return -EFAULT;
        return 0;
 done:
-       rtnl_unlock();
        return err;
 }
 
@@ -2450,6 +2448,8 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
        struct inet_sock *inet = inet_sk(sk);
        struct ip_sf_socklist *psl;
 
+       ASSERT_RTNL();
+
        psin = (struct sockaddr_in *)&gsf->gf_group;
        if (psin->sin_family != AF_INET)
                return -EINVAL;
@@ -2457,8 +2457,6 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
        if (!ipv4_is_multicast(addr))
                return -EINVAL;
 
-       rtnl_lock();
-
        err = -EADDRNOTAVAIL;
 
        for_each_pmc_rtnl(inet, pmc) {
@@ -2470,7 +2468,6 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
                goto done;
        gsf->gf_fmode = pmc->sfmode;
        psl = rtnl_dereference(pmc->sflist);
-       rtnl_unlock();
        count = psl ? psl->sl_count : 0;
        copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
        gsf->gf_numsrc = count;
@@ -2490,7 +2487,6 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
        }
        return 0;
 done:
-       rtnl_unlock();
        return err;
 }
 
index c3c359ad66e3ddb8295b160de30130b405238072..5f73a7c03e27d334c771f144825c4a2f718d71ba 100644 (file)
@@ -1251,11 +1251,22 @@ EXPORT_SYMBOL(compat_ip_setsockopt);
  *     the _received_ ones. The set sets the _sent_ ones.
  */
 
+static bool getsockopt_needs_rtnl(int optname)
+{
+       switch (optname) {
+       case IP_MSFILTER:
+       case MCAST_MSFILTER:
+               return true;
+       }
+       return false;
+}
+
 static int do_ip_getsockopt(struct sock *sk, int level, int optname,
                            char __user *optval, int __user *optlen, unsigned int flags)
 {
        struct inet_sock *inet = inet_sk(sk);
-       int val;
+       bool needs_rtnl = getsockopt_needs_rtnl(optname);
+       int val, err = 0;
        int len;
 
        if (level != SOL_IP)
@@ -1269,6 +1280,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        if (len < 0)
                return -EINVAL;
 
+       if (needs_rtnl)
+               rtnl_lock();
        lock_sock(sk);
 
        switch (optname) {
@@ -1386,39 +1399,35 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        case IP_MSFILTER:
        {
                struct ip_msfilter msf;
-               int err;
 
                if (len < IP_MSFILTER_SIZE(0)) {
-                       release_sock(sk);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
                if (copy_from_user(&msf, optval, IP_MSFILTER_SIZE(0))) {
-                       release_sock(sk);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
                err = ip_mc_msfget(sk, &msf,
                                   (struct ip_msfilter __user *)optval, optlen);
-               release_sock(sk);
-               return err;
+               goto out;
        }
        case MCAST_MSFILTER:
        {
                struct group_filter gsf;
-               int err;
 
                if (len < GROUP_FILTER_SIZE(0)) {
-                       release_sock(sk);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
                if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) {
-                       release_sock(sk);
-                       return -EFAULT;
+                       err = -EFAULT;
+                       goto out;
                }
                err = ip_mc_gsfget(sk, &gsf,
                                   (struct group_filter __user *)optval,
                                   optlen);
-               release_sock(sk);
-               return err;
+               goto out;
        }
        case IP_MULTICAST_ALL:
                val = inet->mc_all;
@@ -1485,6 +1494,12 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
                        return -EFAULT;
        }
        return 0;
+
+out:
+       release_sock(sk);
+       if (needs_rtnl)
+               rtnl_unlock();
+       return err;
 }
 
 int ip_getsockopt(struct sock *sk, int level,
index 0e5591c2ee9f6d66acb47ce2cbbf31403dc286f7..6fb869f646bf7a15b2f012cc1982c2a9f3d5935f 100644 (file)
@@ -67,10 +67,9 @@ static unsigned int ipv4_conntrack_defrag(void *priv,
                                          const struct nf_hook_state *state)
 {
        struct sock *sk = skb->sk;
-       struct inet_sock *inet = inet_sk(skb->sk);
 
-       if (sk && (sk->sk_family == PF_INET) &&
-           inet->nodefrag)
+       if (sk && sk_fullsock(sk) && (sk->sk_family == PF_INET) &&
+           inet_sk(sk)->nodefrag)
                return NF_ACCEPT;
 
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
index 25300c5e283bc3879fa4400628d4a29141d52e3e..a0bd7a55193e351c9ec75a469315c44e76195fd1 100644 (file)
@@ -48,14 +48,14 @@ static void set_local_port_range(struct net *net, int range[2])
 {
        bool same_parity = !((range[0] ^ range[1]) & 1);
 
-       write_seqlock(&net->ipv4.ip_local_ports.lock);
+       write_seqlock_bh(&net->ipv4.ip_local_ports.lock);
        if (same_parity && !net->ipv4.ip_local_ports.warned) {
                net->ipv4.ip_local_ports.warned = true;
                pr_err_ratelimited("ip_local_port_range: prefer different parity for start/end values.\n");
        }
        net->ipv4.ip_local_ports.range[0] = range[0];
        net->ipv4.ip_local_ports.range[1] = range[1];
-       write_sequnlock(&net->ipv4.ip_local_ports.lock);
+       write_sequnlock_bh(&net->ipv4.ip_local_ports.lock);
 }
 
 /* Validate changes from /proc interface. */
index 1c2648bbac4b22b55739dde4d92dd2ca0533f77a..950e28c0cdf25e23658926cdcf37335aed3fb193 100644 (file)
@@ -1326,6 +1326,8 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
        if (__inet_inherit_port(sk, newsk) < 0)
                goto put_and_exit;
        *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
+       if (*own_req)
+               tcp_move_syn(newtp, req);
 
        return newsk;
 
index 3575dd1e5b6775ad8a35bb3ce0e951bc01e37e7c..ac6b1961ffeb32a40b662300aebee4ba182ce31a 100644 (file)
@@ -551,9 +551,6 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
                newtp->rack.mstamp.v64 = 0;
                newtp->rack.advanced = 0;
 
-               newtp->saved_syn = req->saved_syn;
-               req->saved_syn = NULL;
-
                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS);
        }
        return newsk;
index d72fa90d6feb0122d15d68d6d862e5299d331008..d84742f003a9fca65a3545abdb7a4d517989ed4c 100644 (file)
@@ -418,6 +418,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
        if (err) {
                ipv6_mc_destroy_dev(ndev);
                del_timer(&ndev->regen_timer);
+               snmp6_unregister_dev(ndev);
                goto err_release;
        }
        /* protected by rtnl_lock */
index ea2f4d5440b58266f46525114e7bd9d025fb91d6..5baa8e754e412c454ca22c03822cc57c29df8c35 100644 (file)
@@ -1140,14 +1140,18 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
                goto out;
        }
        *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
-       /* Clone pktoptions received with SYN, if we own the req */
-       if (*own_req && ireq->pktopts) {
-               newnp->pktoptions = skb_clone(ireq->pktopts,
-                                             sk_gfp_atomic(sk, GFP_ATOMIC));
-               consume_skb(ireq->pktopts);
-               ireq->pktopts = NULL;
-               if (newnp->pktoptions)
-                       skb_set_owner_r(newnp->pktoptions, newsk);
+       if (*own_req) {
+               tcp_move_syn(newtp, req);
+
+               /* Clone pktoptions received with SYN, if we own the req */
+               if (ireq->pktopts) {
+                       newnp->pktoptions = skb_clone(ireq->pktopts,
+                                                     sk_gfp_atomic(sk, GFP_ATOMIC));
+                       consume_skb(ireq->pktopts);
+                       ireq->pktopts = NULL;
+                       if (newnp->pktoptions)
+                               skb_set_owner_r(newnp->pktoptions, newsk);
+               }
        }
 
        return newsk;
index 97b75f9bfbcd6852bdff9ca2d2e218b3539a0f8b..d43869879fcfcea6ca23e3a579bd21f8aa855b10 100644 (file)
@@ -55,7 +55,7 @@ nf_nat_redirect_ipv4(struct sk_buff *skb,
 
                rcu_read_lock();
                indev = __in_dev_get_rcu(skb->dev);
-               if (indev != NULL) {
+               if (indev && indev->ifa_list) {
                        ifa = indev->ifa_list;
                        newdst = ifa->ifa_local;
                }
index f1d9e887f5b157b58578a5a7244d65be788bb13b..46453ab318db0bf2a4bc957dcad6742ccbcacc92 100644 (file)
@@ -492,7 +492,7 @@ static int nfnetlink_bind(struct net *net, int group)
        type = nfnl_group2type[group];
 
        rcu_read_lock();
-       ss = nfnetlink_get_subsys(type);
+       ss = nfnetlink_get_subsys(type << 8);
        rcu_read_unlock();
        if (!ss)
                request_module("nfnetlink-subsys-%d", type);
index e4ad2c24bc4122e6470966f75da7b92f8273ba51..9dfaf4d55ee0b1bd92d8d7d2e64eebc42e8e5b04 100644 (file)
@@ -31,6 +31,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
        const struct nft_meta *priv = nft_expr_priv(expr);
        const struct sk_buff *skb = pkt->skb;
        const struct net_device *in = pkt->in, *out = pkt->out;
+       struct sock *sk;
        u32 *dest = &regs->data[priv->dreg];
 
        switch (priv->key) {
@@ -86,33 +87,35 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                *(u16 *)dest = out->type;
                break;
        case NFT_META_SKUID:
-               if (skb->sk == NULL || !sk_fullsock(skb->sk))
+               sk = skb_to_full_sk(skb);
+               if (!sk || !sk_fullsock(sk))
                        goto err;
 
-               read_lock_bh(&skb->sk->sk_callback_lock);
-               if (skb->sk->sk_socket == NULL ||
-                   skb->sk->sk_socket->file == NULL) {
-                       read_unlock_bh(&skb->sk->sk_callback_lock);
+               read_lock_bh(&sk->sk_callback_lock);
+               if (sk->sk_socket == NULL ||
+                   sk->sk_socket->file == NULL) {
+                       read_unlock_bh(&sk->sk_callback_lock);
                        goto err;
                }
 
                *dest = from_kuid_munged(&init_user_ns,
-                               skb->sk->sk_socket->file->f_cred->fsuid);
-               read_unlock_bh(&skb->sk->sk_callback_lock);
+                               sk->sk_socket->file->f_cred->fsuid);
+               read_unlock_bh(&sk->sk_callback_lock);
                break;
        case NFT_META_SKGID:
-               if (skb->sk == NULL || !sk_fullsock(skb->sk))
+               sk = skb_to_full_sk(skb);
+               if (!sk || !sk_fullsock(sk))
                        goto err;
 
-               read_lock_bh(&skb->sk->sk_callback_lock);
-               if (skb->sk->sk_socket == NULL ||
-                   skb->sk->sk_socket->file == NULL) {
-                       read_unlock_bh(&skb->sk->sk_callback_lock);
+               read_lock_bh(&sk->sk_callback_lock);
+               if (sk->sk_socket == NULL ||
+                   sk->sk_socket->file == NULL) {
+                       read_unlock_bh(&sk->sk_callback_lock);
                        goto err;
                }
                *dest = from_kgid_munged(&init_user_ns,
-                                skb->sk->sk_socket->file->f_cred->fsgid);
-               read_unlock_bh(&skb->sk->sk_callback_lock);
+                                sk->sk_socket->file->f_cred->fsgid);
+               read_unlock_bh(&sk->sk_callback_lock);
                break;
 #ifdef CONFIG_IP_ROUTE_CLASSID
        case NFT_META_RTCLASSID: {
@@ -168,9 +171,10 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                break;
 #ifdef CONFIG_CGROUP_NET_CLASSID
        case NFT_META_CGROUP:
-               if (skb->sk == NULL || !sk_fullsock(skb->sk))
+               sk = skb_to_full_sk(skb);
+               if (!sk || !sk_fullsock(sk))
                        goto err;
-               *dest = skb->sk->sk_classid;
+               *dest = sk->sk_classid;
                break;
 #endif
        default:
index 899b06115fc53c87ea34eb1bf975666e1992ca98..3eff7b67cdf2f5277c2004cf48c2f4e37c218068 100644 (file)
@@ -31,8 +31,9 @@ static unsigned int
 tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_tee_tginfo *info = par->targinfo;
+       int oif = info->priv ? info->priv->oif : 0;
 
-       nf_dup_ipv4(par->net, skb, par->hooknum, &info->gw.in, info->priv->oif);
+       nf_dup_ipv4(par->net, skb, par->hooknum, &info->gw.in, oif);
 
        return XT_CONTINUE;
 }
@@ -42,8 +43,9 @@ static unsigned int
 tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 {
        const struct xt_tee_tginfo *info = par->targinfo;
+       int oif = info->priv ? info->priv->oif : 0;
 
-       nf_dup_ipv6(par->net, skb, par->hooknum, &info->gw.in6, info->priv->oif);
+       nf_dup_ipv6(par->net, skb, par->hooknum, &info->gw.in6, oif);
 
        return XT_CONTINUE;
 }
index ca2e577ed8ac196caca1190d9ae65557bd5ab8ed..1302b475abcbe0c6c2f7c93d416635005ae9b91f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/skbuff.h>
 #include <linux/file.h>
 #include <net/sock.h>
+#include <net/inet_sock.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_owner.h>
 
@@ -33,8 +34,9 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
        const struct xt_owner_match_info *info = par->matchinfo;
        const struct file *filp;
+       struct sock *sk = skb_to_full_sk(skb);
 
-       if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+       if (sk == NULL || sk->sk_socket == NULL)
                return (info->match ^ info->invert) == 0;
        else if (info->match & info->invert & XT_OWNER_SOCKET)
                /*
@@ -43,7 +45,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
                 */
                return false;
 
-       filp = skb->sk->sk_socket->file;
+       filp = sk->sk_socket->file;
        if (filp == NULL)
                return ((info->match ^ info->invert) &
                       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
index 691660b9b7effdc59d10517ebf099ca8736efe14..af399cac5205402480300ae7b7d6fbb2094095fb 100644 (file)
@@ -2911,22 +2911,40 @@ static int packet_release(struct socket *sock)
  *     Attach a packet hook.
  */
 
-static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
+static int packet_do_bind(struct sock *sk, const char *name, int ifindex,
+                         __be16 proto)
 {
        struct packet_sock *po = pkt_sk(sk);
        struct net_device *dev_curr;
        __be16 proto_curr;
        bool need_rehook;
+       struct net_device *dev = NULL;
+       int ret = 0;
+       bool unlisted = false;
 
-       if (po->fanout) {
-               if (dev)
-                       dev_put(dev);
-
+       if (po->fanout)
                return -EINVAL;
-       }
 
        lock_sock(sk);
        spin_lock(&po->bind_lock);
+       rcu_read_lock();
+
+       if (name) {
+               dev = dev_get_by_name_rcu(sock_net(sk), name);
+               if (!dev) {
+                       ret = -ENODEV;
+                       goto out_unlock;
+               }
+       } else if (ifindex) {
+               dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
+               if (!dev) {
+                       ret = -ENODEV;
+                       goto out_unlock;
+               }
+       }
+
+       if (dev)
+               dev_hold(dev);
 
        proto_curr = po->prot_hook.type;
        dev_curr = po->prot_hook.dev;
@@ -2934,14 +2952,29 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
        need_rehook = proto_curr != proto || dev_curr != dev;
 
        if (need_rehook) {
-               unregister_prot_hook(sk, true);
+               if (po->running) {
+                       rcu_read_unlock();
+                       __unregister_prot_hook(sk, true);
+                       rcu_read_lock();
+                       dev_curr = po->prot_hook.dev;
+                       if (dev)
+                               unlisted = !dev_get_by_index_rcu(sock_net(sk),
+                                                                dev->ifindex);
+               }
 
                po->num = proto;
                po->prot_hook.type = proto;
-               po->prot_hook.dev = dev;
 
-               po->ifindex = dev ? dev->ifindex : 0;
-               packet_cached_dev_assign(po, dev);
+               if (unlikely(unlisted)) {
+                       dev_put(dev);
+                       po->prot_hook.dev = NULL;
+                       po->ifindex = -1;
+                       packet_cached_dev_reset(po);
+               } else {
+                       po->prot_hook.dev = dev;
+                       po->ifindex = dev ? dev->ifindex : 0;
+                       packet_cached_dev_assign(po, dev);
+               }
        }
        if (dev_curr)
                dev_put(dev_curr);
@@ -2949,7 +2982,7 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
        if (proto == 0 || !need_rehook)
                goto out_unlock;
 
-       if (!dev || (dev->flags & IFF_UP)) {
+       if (!unlisted && (!dev || (dev->flags & IFF_UP))) {
                register_prot_hook(sk);
        } else {
                sk->sk_err = ENETDOWN;
@@ -2958,9 +2991,10 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
        }
 
 out_unlock:
+       rcu_read_unlock();
        spin_unlock(&po->bind_lock);
        release_sock(sk);
-       return 0;
+       return ret;
 }
 
 /*
@@ -2972,8 +3006,6 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
 {
        struct sock *sk = sock->sk;
        char name[15];
-       struct net_device *dev;
-       int err = -ENODEV;
 
        /*
         *      Check legality
@@ -2983,19 +3015,13 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
                return -EINVAL;
        strlcpy(name, uaddr->sa_data, sizeof(name));
 
-       dev = dev_get_by_name(sock_net(sk), name);
-       if (dev)
-               err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
-       return err;
+       return packet_do_bind(sk, name, 0, pkt_sk(sk)->num);
 }
 
 static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr;
        struct sock *sk = sock->sk;
-       struct net_device *dev = NULL;
-       int err;
-
 
        /*
         *      Check legality
@@ -3006,16 +3032,8 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len
        if (sll->sll_family != AF_PACKET)
                return -EINVAL;
 
-       if (sll->sll_ifindex) {
-               err = -ENODEV;
-               dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex);
-               if (dev == NULL)
-                       goto out;
-       }
-       err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num);
-
-out:
-       return err;
+       return packet_do_bind(sk, NULL, sll->sll_ifindex,
+                             sll->sll_protocol ? : pkt_sk(sk)->num);
 }
 
 static struct proto packet_proto = {
index 536838b657bfcfb8e33596b7a7d5aec76b72e4f4..fbfec6a188390007fd30cf0a351e74f5b2d77057 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <net/inet_sock.h>
 
 #include <net/pkt_cls.h>
 #include <net/ip.h>
@@ -197,8 +198,11 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb)
 
 static u32 flow_get_skuid(const struct sk_buff *skb)
 {
-       if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
-               kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid;
+       struct sock *sk = skb_to_full_sk(skb);
+
+       if (sk && sk->sk_socket && sk->sk_socket->file) {
+               kuid_t skuid = sk->sk_socket->file->f_cred->fsuid;
+
                return from_kuid(&init_user_ns, skuid);
        }
        return 0;
@@ -206,8 +210,11 @@ static u32 flow_get_skuid(const struct sk_buff *skb)
 
 static u32 flow_get_skgid(const struct sk_buff *skb)
 {
-       if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
-               kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid;
+       struct sock *sk = skb_to_full_sk(skb);
+
+       if (sk && sk->sk_socket && sk->sk_socket->file) {
+               kgid_t skgid = sk->sk_socket->file->f_cred->fsgid;
+
                return from_kgid(&init_user_ns, skgid);
        }
        return 0;
index b5294ce20cd467063721cea69348cb35d7999921..f2aabc0089da203cd6b4d5b15eea40ad5299babe 100644 (file)
@@ -343,119 +343,145 @@ META_COLLECTOR(int_sk_refcnt)
 
 META_COLLECTOR(int_sk_rcvbuf)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_rcvbuf;
+       dst->value = sk->sk_rcvbuf;
 }
 
 META_COLLECTOR(int_sk_shutdown)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_shutdown;
+       dst->value = sk->sk_shutdown;
 }
 
 META_COLLECTOR(int_sk_proto)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_protocol;
+       dst->value = sk->sk_protocol;
 }
 
 META_COLLECTOR(int_sk_type)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_type;
+       dst->value = sk->sk_type;
 }
 
 META_COLLECTOR(int_sk_rmem_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = sk_rmem_alloc_get(skb->sk);
+       dst->value = sk_rmem_alloc_get(sk);
 }
 
 META_COLLECTOR(int_sk_wmem_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = sk_wmem_alloc_get(skb->sk);
+       dst->value = sk_wmem_alloc_get(sk);
 }
 
 META_COLLECTOR(int_sk_omem_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = atomic_read(&skb->sk->sk_omem_alloc);
+       dst->value = atomic_read(&sk->sk_omem_alloc);
 }
 
 META_COLLECTOR(int_sk_rcv_qlen)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_receive_queue.qlen;
+       dst->value = sk->sk_receive_queue.qlen;
 }
 
 META_COLLECTOR(int_sk_snd_qlen)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_write_queue.qlen;
+       dst->value = sk->sk_write_queue.qlen;
 }
 
 META_COLLECTOR(int_sk_wmem_queued)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_wmem_queued;
+       dst->value = sk->sk_wmem_queued;
 }
 
 META_COLLECTOR(int_sk_fwd_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_forward_alloc;
+       dst->value = sk->sk_forward_alloc;
 }
 
 META_COLLECTOR(int_sk_sndbuf)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_sndbuf;
+       dst->value = sk->sk_sndbuf;
 }
 
 META_COLLECTOR(int_sk_alloc)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = (__force int) skb->sk->sk_allocation;
+       dst->value = (__force int) sk->sk_allocation;
 }
 
 META_COLLECTOR(int_sk_hash)
@@ -469,92 +495,112 @@ META_COLLECTOR(int_sk_hash)
 
 META_COLLECTOR(int_sk_lingertime)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_lingertime / HZ;
+       dst->value = sk->sk_lingertime / HZ;
 }
 
 META_COLLECTOR(int_sk_err_qlen)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_error_queue.qlen;
+       dst->value = sk->sk_error_queue.qlen;
 }
 
 META_COLLECTOR(int_sk_ack_bl)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_ack_backlog;
+       dst->value = sk->sk_ack_backlog;
 }
 
 META_COLLECTOR(int_sk_max_ack_bl)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_max_ack_backlog;
+       dst->value = sk->sk_max_ack_backlog;
 }
 
 META_COLLECTOR(int_sk_prio)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_priority;
+       dst->value = sk->sk_priority;
 }
 
 META_COLLECTOR(int_sk_rcvlowat)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_rcvlowat;
+       dst->value = sk->sk_rcvlowat;
 }
 
 META_COLLECTOR(int_sk_rcvtimeo)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_rcvtimeo / HZ;
+       dst->value = sk->sk_rcvtimeo / HZ;
 }
 
 META_COLLECTOR(int_sk_sndtimeo)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_sndtimeo / HZ;
+       dst->value = sk->sk_sndtimeo / HZ;
 }
 
 META_COLLECTOR(int_sk_sendmsg_off)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_frag.offset;
+       dst->value = sk->sk_frag.offset;
 }
 
 META_COLLECTOR(int_sk_write_pend)
 {
-       if (skip_nonlocal(skb)) {
+       const struct sock *sk = skb_to_full_sk(skb);
+
+       if (!sk) {
                *err = -1;
                return;
        }
-       dst->value = skb->sk->sk_write_pending;
+       dst->value = sk->sk_write_pending;
 }
 
 /**************************************************************************
index 400d87294de3f72ca343814525fcec67564d0b47..0a369bb440e77e03262ae48a7e3519db35c87835 100644 (file)
@@ -1234,7 +1234,7 @@ vmci_transport_recv_connecting_server(struct sock *listener,
        /* Callers of accept() will be be waiting on the listening socket, not
         * the pending socket.
         */
-       listener->sk_state_change(listener);
+       listener->sk_data_ready(listener);
 
        return 0;
 
index 9e591e5989bef8db6369d2afb4354b0a1e96efa4..d0cfaa9f19d08034a3c3600d8381ed166a369388 100644 (file)
@@ -4933,7 +4933,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                                                int ifindex,
                                                u16 family)
 {
-       struct sock *sk = skb->sk;
+       struct sock *sk = skb_to_full_sk(skb);
        struct sk_security_struct *sksec;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
@@ -4988,7 +4988,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
        if (!secmark_active && !peerlbl_active)
                return NF_ACCEPT;
 
-       sk = skb->sk;
+       sk = skb_to_full_sk(skb);
 
 #ifdef CONFIG_XFRM
        /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
@@ -5033,8 +5033,6 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
                u32 skb_sid;
                struct sk_security_struct *sksec;
 
-               if (sk->sk_state == TCP_NEW_SYN_RECV)
-                       sk = inet_reqsk(sk)->rsk_listener;
                sksec = sk->sk_security;
                if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
                        return NF_DROP;
index 0364120d1ec8705da7e8c1636f645d0885731509..1f989a539fd4abe08e3797b5d49f7b26ded4fe41 100644 (file)
@@ -245,7 +245,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
 
        /* if this is a locally generated packet check to see if it is already
         * being labeled by it's parent socket, if it is just exit */
-       sk = skb->sk;
+       sk = skb_to_full_sk(skb);
        if (sk != NULL) {
                struct sk_security_struct *sksec = sk->sk_security;
                if (sksec->nlbl_state != NLBL_REQSKB)
index 6d1706c9777e64fc69ca305e6ef55a2d563bb29d..aa6bf1b22ec5b3ec3d8e64db683d7db92b2c4f1b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/netdevice.h>
+#include <net/inet_sock.h>
 #include "smack.h"
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -25,11 +26,12 @@ static unsigned int smack_ipv6_output(void *priv,
                                        struct sk_buff *skb,
                                        const struct nf_hook_state *state)
 {
+       struct sock *sk = skb_to_full_sk(skb);
        struct socket_smack *ssp;
        struct smack_known *skp;
 
-       if (skb && skb->sk && skb->sk->sk_security) {
-               ssp = skb->sk->sk_security;
+       if (sk && sk->sk_security) {
+               ssp = sk->sk_security;
                skp = ssp->smk_out;
                skb->secmark = skp->smk_secid;
        }
@@ -42,11 +44,12 @@ static unsigned int smack_ipv4_output(void *priv,
                                        struct sk_buff *skb,
                                        const struct nf_hook_state *state)
 {
+       struct sock *sk = skb_to_full_sk(skb);
        struct socket_smack *ssp;
        struct smack_known *skp;
 
-       if (skb && skb->sk && skb->sk->sk_security) {
-               ssp = skb->sk->sk_security;
+       if (sk && sk->sk_security) {
+               ssp = sk->sk_security;
                skp = ssp->smk_out;
                skb->secmark = skp->smk_secid;
        }