Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 19 Oct 2015 16:55:40 +0000 (09:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 19 Oct 2015 16:55:40 +0000 (09:55 -0700)
Pull networking fixes from David Miller:

 1) Account for extra headroom in ath9k driver, from Felix Fietkau.

 2) Fix OOPS in pppoe driver due to incorrect socket state transition,
    from Guillaume Nault.

 3) Kill memory leak in amd-xgbe debugfx, from Geliang Tang.

 4) Power management fixes for iwlwifi, from Johannes Berg.

 5) Fix races in reqsk_queue_unlink(), from Eric Dumazet.

 6) Fix dst_entry usage in ARP replies, from Jiri Benc.

 7) Cure OOPSes with SO_GET_FILTER, from Daniel Borkmann.

 8) Missing allocation failure check in amd-xgbe, from Tom Lendacky.

 9) Various resource allocation/freeing cures in DSA< from Neil
    Armstrong.

10) A series of bug fixes in the openvswitch conntrack support, from
    Joe Stringer.

11) Fix two cases (BPF and act_mirred) where we have to clean the sender
    cpu stored in the SKB before transmitting.  From WANG Cong and
    Alexei Starovoitov.

12) Disable VLAN filtering in promiscuous mode in mlx5 driver, from
    Achiad Shochat.

13) Older bnx2x chips cannot do 4-tuple UDP hashing, so prevent this
    configuration via ethtool.  From Yuval Mintz.

14) Don't call rt6_uncached_list_flush_dev() from rt6_ifdown() when
    'dev' is NULL, from Eric Biederman.

15) Prevent stalled link synchronization in tipc, from Jon Paul Maloy.

16) kcalloc() gstrings ethtool buffer before having driver fill it in,
    in order to prevent kernel memory leaking.  From Joe Perches.

17) Fix mixxing rt6_info initialization for blackhole routes, from
    Martin KaFai Lau.

18) Kill VLAN regression in via-rhine, from Andrej Ota.

19) Missing pfmemalloc check in sk_add_backlog(), from Eric Dumazet.

20) Fix spurious MSG_TRUNC signalling in netlink dumps, from Ronen Arad.

21) Scrube SKBs when pushing them between namespaces in openvswitch,
    from Joe Stringer.

22) bcmgenet enables link interrupts too early, fix from Florian
    Fainelli.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (92 commits)
  net: bcmgenet: Fix early link interrupt enabling
  tunnels: Don't require remote endpoint or ID during creation.
  openvswitch: Scrub skb between namespaces
  xen-netback: correctly check failed allocation
  net: asix: add support for the Billionton GUSB2AM-1G-B USB adapter
  netlink: Trim skb to alloc size to avoid MSG_TRUNC
  net: add pfmemalloc check in sk_add_backlog()
  via-rhine: fix VLAN receive handling regression.
  ipv6: Initialize rt6_info properly in ip6_blackhole_route()
  ipv6: Move common init code for rt6_info to a new function rt6_info_init()
  Bluetooth: Fix initializing conn_params in scan phase
  Bluetooth: Fix conn_params list update in hci_connect_le_scan_cleanup
  Bluetooth: Fix remove_device behavior for explicit connects
  Bluetooth: Fix LE reconnection logic
  Bluetooth: Fix reference counting for LE-scan based connections
  Bluetooth: Fix double scan updates
  mlxsw: core: Fix race condition in __mlxsw_emad_transmit
  tipc: move fragment importance field to new header position
  ethtool: Use kcalloc instead of kmalloc for ethtool_get_strings
  tipc: eliminate risk of stalled link synchronization
  ...

83 files changed:
MAINTAINERS
arch/arm/net/bpf_jit_32.c
drivers/net/can/sja1000/peak_pci.c
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fsl_pq_mdio.c
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40evf/i40e_adminq.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/en_flow_table.c
drivers/net/ethernet/mellanox/mlx5/core/port.c
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/item.h
drivers/net/ethernet/mellanox/mlxsw/pci.c
drivers/net/ethernet/mellanox/mlxsw/switchx2.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/via/via-rhine.c
drivers/net/geneve.c
drivers/net/phy/Kconfig
drivers/net/ppp/pppoe.c
drivers/net/usb/Kconfig
drivers/net/usb/asix_common.c
drivers/net/usb/asix_devices.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/iwlwifi/dvm/lib.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/xen-netback/xenbus.c
include/net/af_unix.h
include/net/inet_timewait_sock.h
include/net/sock.h
include/uapi/linux/openvswitch.h
include/uapi/linux/rtnetlink.h
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c
net/core/ethtool.c
net/core/filter.c
net/dsa/dsa.c
net/ipv4/arp.c
net/ipv4/inet_connection_sock.c
net/ipv6/addrconf.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/ipv6/xfrm6_policy.c
net/mac80211/debugfs.c
net/mac80211/status.c
net/mac80211/tx.c
net/netlink/af_netlink.c
net/openvswitch/actions.c
net/openvswitch/conntrack.c
net/openvswitch/conntrack.h
net/openvswitch/flow.h
net/openvswitch/flow_netlink.c
net/openvswitch/flow_table.c
net/openvswitch/vport.c
net/sched/act_mirred.c
net/sched/sch_hhf.c
net/switchdev/switchdev.c
net/tipc/msg.h
net/tipc/node.c
net/unix/af_unix.c

index b8577ad9b8a24debb71b8834ce371091754f30c1..fb7d2e4af2003f28c81489e314c4070de2a647d8 100644 (file)
@@ -6793,7 +6793,6 @@ F:        drivers/scsi/megaraid/
 
 MELLANOX ETHERNET DRIVER (mlx4_en)
 M:     Amir Vadai <amirv@mellanox.com>
-M:     Ido Shamay <idos@mellanox.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.mellanox.com
index 876060bcceeb3ea989e24fe18b42910f3cce4058..b8efb8cd1f73ee1cb7de196ae88d9173203c4d2a 100644 (file)
@@ -614,6 +614,7 @@ load_common:
                case BPF_LD | BPF_B | BPF_IND:
                        load_order = 0;
 load_ind:
+                       update_on_xread(ctx);
                        OP_IMM3(ARM_ADD, r_off, r_X, k, ctx);
                        goto load_common;
                case BPF_LDX | BPF_IMM:
index e5fac368068a2320eb06d207934c4b969356237b..131026fbc2d77cbc3ccb5903daa10f8920f8ae17 100644 (file)
@@ -87,6 +87,7 @@ static const struct pci_device_id peak_pci_tbl[] = {
        {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+       {PEAK_PCI_VENDOR_ID, PEAK_PCIE_OEM_ID, PCI_ANY_ID, PCI_ANY_ID,},
 #ifdef CONFIG_CAN_PEAK_PCIEC
        {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
        {PEAK_PCI_VENDOR_ID, PEAK_PCIEC34_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
index 2c063b60db4b02bc48246887fb5d98f6b3de0394..96f485ab612e679dc7065b1e214cb9d73c690d43 100644 (file)
@@ -327,9 +327,13 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
        pdata->debugfs_xpcs_reg = 0;
 
        buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
+       if (!buf)
+               return;
+
        pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
        if (!pdata->xgbe_debugfs) {
                netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
+               kfree(buf);
                return;
        }
 
index aeb7ce64452e14cd3cbe49325f63bae2d99e3ef2..be628bd9fb18b6f0116125e5a3f9ea16ad1d3561 100644 (file)
@@ -3351,6 +3351,13 @@ static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
                        udp_rss_requested = 0;
                else
                        return -EINVAL;
+
+               if (CHIP_IS_E1x(bp) && udp_rss_requested) {
+                       DP(BNX2X_MSG_ETHTOOL,
+                          "57710, 57711 boards don't support RSS according to UDP 4-tuple\n");
+                       return -EINVAL;
+               }
+
                if ((info->flow_type == UDP_V4_FLOW) &&
                    (bp->rss_conf_obj.udp_rss_v4 != udp_rss_requested)) {
                        bp->rss_conf_obj.udp_rss_v4 = udp_rss_requested;
index 3bc701e4c59eb56cc19e11c917dd34c24062754e..1805541b4240e72c79445ea6f50bbc2a74ba13c7 100644 (file)
@@ -1683,6 +1683,24 @@ static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
        bcmgenet_intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
 }
 
+static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)
+{
+       u32 int0_enable = 0;
+
+       /* Monitor cable plug/unplugged event for internal PHY, external PHY
+        * and MoCA PHY
+        */
+       if (priv->internal_phy) {
+               int0_enable |= UMAC_IRQ_LINK_EVENT;
+       } else if (priv->ext_phy) {
+               int0_enable |= UMAC_IRQ_LINK_EVENT;
+       } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
+               if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
+                       int0_enable |= UMAC_IRQ_LINK_EVENT;
+       }
+       bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
+}
+
 static int init_umac(struct bcmgenet_priv *priv)
 {
        struct device *kdev = &priv->pdev->dev;
@@ -1723,15 +1741,8 @@ static int init_umac(struct bcmgenet_priv *priv)
        /* Enable Tx default queue 16 interrupts */
        int0_enable |= UMAC_IRQ_TXDMA_DONE;
 
-       /* Monitor cable plug/unplugged event for internal PHY */
-       if (priv->internal_phy) {
-               int0_enable |= UMAC_IRQ_LINK_EVENT;
-       } else if (priv->ext_phy) {
-               int0_enable |= UMAC_IRQ_LINK_EVENT;
-       } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
-               if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
-                       int0_enable |= UMAC_IRQ_LINK_EVENT;
-
+       /* Configure backpressure vectors for MoCA */
+       if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
                reg = bcmgenet_bp_mc_get(priv);
                reg |= BIT(priv->hw_params->bp_in_en_shift);
 
@@ -2645,6 +2656,9 @@ static void bcmgenet_netif_start(struct net_device *dev)
 
        netif_tx_start_all_queues(dev);
 
+       /* Monitor link interrupts now */
+       bcmgenet_link_intr_enable(priv);
+
        phy_start(priv->phydev);
 }
 
index 821540913343db10f59ae3a03835a084ca82063d..d463563e1f7039ee5176ca36abfdc6bae3f2ed46 100644 (file)
@@ -592,6 +592,7 @@ struct be_adapter {
        int be_get_temp_freq;
        struct be_hwmon hwmon_info;
        u8 pf_number;
+       u8 pci_func_num;
        struct rss_info rss_info;
        /* Filters for packets that need to be sent to BMC */
        u32 bmc_filt_mask;
index eb323913cd39fb981a8c0cc02140c0c7205ee4f8..1795c935ff023fcf795008a49a9a4cd0fce63d9c 100644 (file)
@@ -851,8 +851,10 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
                return status;
 
        dest_wrb = be_cmd_copy(adapter, wrb);
-       if (!dest_wrb)
-               return -EBUSY;
+       if (!dest_wrb) {
+               status = -EBUSY;
+               goto unlock;
+       }
 
        if (use_mcc(adapter))
                status = be_mcc_notify_wait(adapter);
@@ -862,6 +864,7 @@ static int be_cmd_notify_wait(struct be_adapter *adapter,
        if (!status)
                memcpy(wrb, dest_wrb, sizeof(*wrb));
 
+unlock:
        be_cmd_unlock(adapter);
        return status;
 }
@@ -1984,6 +1987,8 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
                         be_if_cap_flags(adapter));
        }
        flags &= be_if_cap_flags(adapter);
+       if (!flags)
+               return -ENOTSUPP;
 
        return __be_cmd_rx_filter(adapter, flags, value);
 }
@@ -2887,6 +2892,7 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
        if (!status) {
                attribs = attribs_cmd.va + sizeof(struct be_cmd_resp_hdr);
                adapter->hba_port_num = attribs->hba_attribs.phy_port;
+               adapter->pci_func_num = attribs->pci_func_num;
                serial_num = attribs->hba_attribs.controller_serial_number;
                for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
                        adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
@@ -3709,7 +3715,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
                        status = -EINVAL;
                        goto err;
                }
-
                adapter->pf_number = desc->pf_num;
                be_copy_nic_desc(res, desc);
        }
@@ -3721,7 +3726,10 @@ err:
        return status;
 }
 
-/* Will use MBOX only if MCCQ has not been created */
+/* Will use MBOX only if MCCQ has not been created
+ * non-zero domain => a PF is querying this on behalf of a VF
+ * zero domain => a PF or a VF is querying this for itself
+ */
 int be_cmd_get_profile_config(struct be_adapter *adapter,
                              struct be_resources *res, u8 query, u8 domain)
 {
@@ -3748,10 +3756,15 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
                               OPCODE_COMMON_GET_PROFILE_CONFIG,
                               cmd.size, &wrb, &cmd);
 
-       req->hdr.domain = domain;
        if (!lancer_chip(adapter))
                req->hdr.version = 1;
        req->type = ACTIVE_PROFILE_TYPE;
+       /* When a function is querying profile information relating to
+        * itself hdr.pf_number must be set to it's pci_func_num + 1
+        */
+       req->hdr.domain = domain;
+       if (domain == 0)
+               req->hdr.pf_num = adapter->pci_func_num + 1;
 
        /* When QUERY_MODIFIABLE_FIELDS_TYPE bit is set, cmd returns the
         * descriptors with all bits set to "1" for the fields which can be
@@ -3921,12 +3934,16 @@ static void be_fill_vf_res_template(struct be_adapter *adapter,
                        vf_if_cap_flags &= ~(BE_IF_FLAGS_RSS |
                                             BE_IF_FLAGS_DEFQ_RSS);
                }
-
-               nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
        } else {
                num_vf_qs = 1;
        }
 
+       if (res_mod.vf_if_cap_flags & BE_IF_FLAGS_VLAN_PROMISCUOUS) {
+               nic_vft->flags |= BIT(IF_CAPS_FLAGS_VALID_SHIFT);
+               vf_if_cap_flags &= ~BE_IF_FLAGS_VLAN_PROMISCUOUS;
+       }
+
+       nic_vft->cap_flags = cpu_to_le32(vf_if_cap_flags);
        nic_vft->rq_count = cpu_to_le16(num_vf_qs);
        nic_vft->txq_count = cpu_to_le16(num_vf_qs);
        nic_vft->rssq_count = cpu_to_le16(num_vf_qs);
index 7d178bdb112eb7d14d5a62d74ea21ecaa30ba0e9..91155ea74f342e2663f18848c9fe5546635e7c05 100644 (file)
@@ -289,7 +289,9 @@ struct be_cmd_req_hdr {
        u32 timeout;            /* dword 1 */
        u32 request_length;     /* dword 2 */
        u8 version;             /* dword 3 */
-       u8 rsvd[3];             /* dword 3 */
+       u8 rsvd1;               /* dword 3 */
+       u8 pf_num;              /* dword 3 */
+       u8 rsvd2;               /* dword 3 */
 };
 
 #define RESP_HDR_INFO_OPCODE_SHIFT     0       /* bits 0 - 7 */
@@ -1652,7 +1654,11 @@ struct mgmt_hba_attribs {
 
 struct mgmt_controller_attrib {
        struct mgmt_hba_attribs hba_attribs;
-       u32 rsvd0[10];
+       u32 rsvd0[2];
+       u16 rsvd1;
+       u8 pci_func_num;
+       u8 rsvd2;
+       u32 rsvd3[7];
 } __packed;
 
 struct be_cmd_req_cntl_attribs {
index 7bf51a1a0a77e12a4812662767dd21767813dc1b..eb48a977f8daabe78d6d5b6a94f6607bf19287b8 100644 (file)
@@ -1123,11 +1123,12 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
                                           struct sk_buff *skb,
                                           struct be_wrb_params *wrb_params)
 {
-       /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or
-        * less may cause a transmit stall on that port. So the work-around is
-        * to pad short packets (<= 32 bytes) to a 36-byte length.
+       /* Lancer, SH and BE3 in SRIOV mode have a bug wherein
+        * packets that are 32b or less may cause a transmit stall
+        * on that port. The workaround is to pad such packets
+        * (len <= 32 bytes) to a minimum length of 36b.
         */
-       if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
+       if (skb->len <= 32) {
                if (skb_put_padto(skb, 36))
                        return NULL;
        }
@@ -4205,10 +4206,6 @@ static int be_get_config(struct be_adapter *adapter)
        int status, level;
        u16 profile_id;
 
-       status = be_cmd_get_cntl_attributes(adapter);
-       if (status)
-               return status;
-
        status = be_cmd_query_fw_cfg(adapter);
        if (status)
                return status;
@@ -4407,6 +4404,11 @@ static int be_setup(struct be_adapter *adapter)
        if (!lancer_chip(adapter))
                be_cmd_req_native_mode(adapter);
 
+       /* Need to invoke this cmd first to get the PCI Function Number */
+       status = be_cmd_get_cntl_attributes(adapter);
+       if (status)
+               return status;
+
        if (!BE2_chip(adapter) && be_physfn(adapter))
                be_alloc_sriov_res(adapter);
 
@@ -4999,7 +5001,15 @@ static bool be_check_ufi_compatibility(struct be_adapter *adapter,
                return false;
        }
 
-       return (fhdr->asic_type_rev >= adapter->asic_rev);
+       /* In BE3 FW images the "asic_type_rev" field doesn't track the
+        * asic_rev of the chips it is compatible with.
+        * When asic_type_rev is 0 the image is compatible only with
+        * pre-BE3-R chips (asic_rev < 0x10)
+        */
+       if (BEx_chip(adapter) && fhdr->asic_type_rev == 0)
+               return adapter->asic_rev < 0x10;
+       else
+               return (fhdr->asic_type_rev >= adapter->asic_rev);
 }
 
 static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
index 3c40f6b9922436a32d255aa627e9d94db45f8477..55c36230e17634c3e063bdb20f4bb6a896bce4a6 100644 (file)
@@ -198,17 +198,28 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
 
 #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
 /*
+ * Return the TBIPA address, starting from the address
+ * of the mapped GFAR MDIO registers (struct gfar)
  * This is mildly evil, but so is our hardware for doing this.
  * Also, we have to cast back to struct gfar because of
  * definition weirdness done in gianfar.h.
  */
-static uint32_t __iomem *get_gfar_tbipa(void __iomem *p)
+static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
 {
        struct gfar __iomem *enet_regs = p;
 
        return &enet_regs->tbipa;
 }
 
+/*
+ * Return the TBIPA address, starting from the address
+ * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar)
+ */
+static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p)
+{
+       return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs));
+}
+
 /*
  * Return the TBIPAR address for an eTSEC2 node
  */
@@ -220,11 +231,12 @@ static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
 
 #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE)
 /*
- * Return the TBIPAR address for a QE MDIO node
+ * Return the TBIPAR address for a QE MDIO node, starting from the address
+ * of the mapped MII registers (struct fsl_pq_mii)
  */
 static uint32_t __iomem *get_ucc_tbipa(void __iomem *p)
 {
-       struct fsl_pq_mdio __iomem *mdio = p;
+       struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii);
 
        return &mdio->utbipar;
 }
@@ -300,14 +312,14 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
                .compatible = "fsl,gianfar-tbi",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = 0,
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mii,
                },
        },
        {
                .compatible = "fsl,gianfar-mdio",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = 0,
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mii,
                },
        },
        {
@@ -315,7 +327,7 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
                .compatible = "gianfar",
                .data = &(struct fsl_pq_mdio_data) {
                        .mii_offset = offsetof(struct fsl_pq_mdio, mii),
-                       .get_tbipa = get_gfar_tbipa,
+                       .get_tbipa = get_gfar_tbipa_from_mdio,
                },
        },
        {
@@ -445,6 +457,16 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
 
                        tbipa = data->get_tbipa(priv->map);
 
+                       /*
+                        * Add consistency check to make sure TBI is contained
+                        * within the mapped range (not because we would get a
+                        * segfault, rather to catch bugs in computing TBI
+                        * address). Print error message but continue anyway.
+                        */
+                       if ((void *)tbipa > priv->map + resource_size(&res) - 4)
+                               dev_err(&pdev->dev, "invalid register map (should be at least 0x%04x to contain TBI address)\n",
+                                       ((void *)tbipa - priv->map) + 4);
+
                        iowrite32be(be32_to_cpup(prop), tbipa);
                }
        }
index 62488a67149d1f0ac38279517427853ebbcec6fc..c0e943aecd1394262757e790b04a6ce1eccda72a 100644 (file)
@@ -386,7 +386,6 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
 
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
-       hw->aq.asq.count = hw->aq.num_asq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_asq_ring(hw);
@@ -404,6 +403,7 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
@@ -445,7 +445,6 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
-       hw->aq.arq.count = hw->aq.num_arq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_arq_ring(hw);
@@ -463,6 +462,7 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
index 2fdf978ae6a5d10a6751f3ec702ef3636fca543f..dd44fafd8798613be8c440c36c2366233d0958d0 100644 (file)
@@ -8389,6 +8389,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
        netdev->hw_enc_features |= NETIF_F_IP_CSUM       |
                                  NETIF_F_GSO_UDP_TUNNEL |
+                                 NETIF_F_GSO_GRE        |
                                  NETIF_F_TSO;
 
        netdev->features = NETIF_F_SG                  |
@@ -8396,6 +8397,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
                           NETIF_F_SCTP_CSUM           |
                           NETIF_F_HIGHDMA             |
                           NETIF_F_GSO_UDP_TUNNEL      |
+                          NETIF_F_GSO_GRE             |
                           NETIF_F_HW_VLAN_CTAG_TX     |
                           NETIF_F_HW_VLAN_CTAG_RX     |
                           NETIF_F_HW_VLAN_CTAG_FILTER |
index 929d47152bf271b1ddba3d8dc284d1941131261a..a23ebfd5cd254014cd0632979aa441a2a6f6eadf 100644 (file)
@@ -373,7 +373,6 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
 
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
-       hw->aq.asq.count = hw->aq.num_asq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_asq_ring(hw);
@@ -391,6 +390,7 @@ static i40e_status i40e_init_asq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.asq.count = hw->aq.num_asq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
@@ -432,7 +432,6 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
-       hw->aq.arq.count = hw->aq.num_arq_entries;
 
        /* allocate the ring memory */
        ret_code = i40e_alloc_adminq_arq_ring(hw);
@@ -450,6 +449,7 @@ static i40e_status i40e_init_arq(struct i40e_hw *hw)
                goto init_adminq_free_rings;
 
        /* success! */
+       hw->aq.arq.count = hw->aq.num_arq_entries;
        goto init_adminq_exit;
 
 init_adminq_free_rings:
index 8e81e53c370e7d54e6367c012212cccc73ee26fd..c3448847936570582ace12e6baec0f51604f1072 100644 (file)
@@ -1364,6 +1364,10 @@ int mlx4_test_interrupts(struct mlx4_dev *dev)
         * and performing a NOP command
         */
        for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
+               /* Make sure request_irq was called */
+               if (!priv->eq_table.eq[i].have_irq)
+                       continue;
+
                /* Temporary use polling for command completions */
                mlx4_cmd_use_polling(dev);
 
index 006757f80988bcb71cfc352542305b61310ef40f..cc3a9897574c542ee368ab067c109128ce89b290 100644 (file)
@@ -2669,14 +2669,11 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
 
        if (msi_x) {
                int nreq = dev->caps.num_ports * num_online_cpus() + 1;
-               bool shared_ports = false;
 
                nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
                             nreq);
-               if (nreq > MAX_MSIX) {
+               if (nreq > MAX_MSIX)
                        nreq = MAX_MSIX;
-                       shared_ports = true;
-               }
 
                entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
                if (!entries)
@@ -2699,9 +2696,6 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
                bitmap_zero(priv->eq_table.eq[MLX4_EQ_ASYNC].actv_ports.ports,
                            dev->caps.num_ports);
 
-               if (MLX4_IS_LEGACY_EQ_MODE(dev->caps))
-                       shared_ports = true;
-
                for (i = 0; i < dev->caps.num_comp_vectors + 1; i++) {
                        if (i == MLX4_EQ_ASYNC)
                                continue;
@@ -2709,7 +2703,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
                        priv->eq_table.eq[i].irq =
                                entries[i + 1 - !!(i > MLX4_EQ_ASYNC)].vector;
 
-                       if (shared_ports) {
+                       if (MLX4_IS_LEGACY_EQ_MODE(dev->caps)) {
                                bitmap_fill(priv->eq_table.eq[i].actv_ports.ports,
                                            dev->caps.num_ports);
                                /* We don't set affinity hint when there
index e71563ce05d1bc34123fd4aa63348d569adf4c57..22d603f7827333e2dce6eab7be6ed6acd5a14cdb 100644 (file)
@@ -598,6 +598,8 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
                return;
 
        priv->vlan.filter_disabled = false;
+       if (priv->netdev->flags & IFF_PROMISC)
+               return;
        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
 }
 
@@ -607,6 +609,8 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
                return;
 
        priv->vlan.filter_disabled = true;
+       if (priv->netdev->flags & IFF_PROMISC)
+               return;
        mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
 }
 
@@ -717,8 +721,12 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
        bool enable_broadcast  = !ea->broadcast_enabled &&  broadcast_enabled;
        bool disable_broadcast =  ea->broadcast_enabled && !broadcast_enabled;
 
-       if (enable_promisc)
+       if (enable_promisc) {
                mlx5e_add_eth_addr_rule(priv, &ea->promisc, MLX5E_PROMISC);
+               if (!priv->vlan.filter_disabled)
+                       mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
+                                           0);
+       }
        if (enable_allmulti)
                mlx5e_add_eth_addr_rule(priv, &ea->allmulti, MLX5E_ALLMULTI);
        if (enable_broadcast)
@@ -730,8 +738,12 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->broadcast);
        if (disable_allmulti)
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->allmulti);
-       if (disable_promisc)
+       if (disable_promisc) {
+               if (!priv->vlan.filter_disabled)
+                       mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
+                                           0);
                mlx5e_del_eth_addr_from_flow_table(priv, &ea->promisc);
+       }
 
        ea->promisc_enabled   = promisc_enabled;
        ea->allmulti_enabled  = allmulti_enabled;
index 821caaab9bfb04697fb0424cb8498bdc9eacabed..3b9480fa3403dee018931c16b678f5ec6c98e913 100644 (file)
@@ -311,7 +311,7 @@ static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
        int err;
 
        memset(in, 0, sizeof(in));
-       MLX5_SET(ptys_reg, in, local_port, local_port);
+       MLX5_SET(pvlc_reg, in, local_port, local_port);
 
        err = mlx5_core_access_reg(dev, in, sizeof(in), pvlc,
                                   pvlc_size, MLX5_REG_PVLC, 0, 0);
index dbcaf5df8967e828f85648de4edce281860f2a61..28c19cc1a17c5f44a7b15103ce168651502843d8 100644 (file)
@@ -374,26 +374,31 @@ static int __mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core,
        int err;
        int ret;
 
+       mlxsw_core->emad.trans_active = true;
+
        err = mlxsw_core_skb_transmit(mlxsw_core->driver_priv, skb, tx_info);
        if (err) {
                dev_err(mlxsw_core->bus_info->dev, "Failed to transmit EMAD (tid=%llx)\n",
                        mlxsw_core->emad.tid);
                dev_kfree_skb(skb);
-               return err;
+               goto trans_inactive_out;
        }
 
-       mlxsw_core->emad.trans_active = true;
        ret = wait_event_timeout(mlxsw_core->emad.wait,
                                 !(mlxsw_core->emad.trans_active),
                                 msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_MS));
        if (!ret) {
                dev_warn(mlxsw_core->bus_info->dev, "EMAD timed-out (tid=%llx)\n",
                         mlxsw_core->emad.tid);
-               mlxsw_core->emad.trans_active = false;
-               return -EIO;
+               err = -EIO;
+               goto trans_inactive_out;
        }
 
        return 0;
+
+trans_inactive_out:
+       mlxsw_core->emad.trans_active = false;
+       return err;
 }
 
 static int mlxsw_emad_process_status(struct mlxsw_core *mlxsw_core,
index ffd55d030ce28dbf902f6990a0dfb7f96b08a766..36fb1cec53c98e9c7dad0cb7b9b59051d7e0c352 100644 (file)
@@ -187,6 +187,7 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
 {
        u16 max_index, be_index;
        u16 offset;             /* byte offset inside the array */
+       u8 in_byte_index;
 
        BUG_ON(index && !item->element_size);
        if (item->offset % sizeof(u32) != 0 ||
@@ -199,7 +200,8 @@ __mlxsw_item_bit_array_offset(struct mlxsw_item *item, u16 index, u8 *shift)
        max_index = (item->size.bytes << 3) / item->element_size - 1;
        be_index = max_index - index;
        offset = be_index * item->element_size >> 3;
-       *shift = index % (BITS_PER_BYTE / item->element_size) << 1;
+       in_byte_index  = index % (BITS_PER_BYTE / item->element_size);
+       *shift = in_byte_index * item->element_size;
 
        return item->offset + offset;
 }
index 462cea31ecbb7be6387512dc741286d7fb56658e..cef866c37648ca0c93d4f109eb9d4f3671fcd890 100644 (file)
@@ -1582,11 +1582,11 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 
        if (in_mbox)
                memcpy(mlxsw_pci->cmd.in_mbox.buf, in_mbox, in_mbox_size);
-       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, in_mapaddr >> 32);
-       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, in_mapaddr);
+       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, upper_32_bits(in_mapaddr));
+       mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, lower_32_bits(in_mapaddr));
 
-       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, out_mapaddr >> 32);
-       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, out_mapaddr);
+       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, upper_32_bits(out_mapaddr));
+       mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, lower_32_bits(out_mapaddr));
 
        mlxsw_pci_write32(mlxsw_pci, CIR_IN_MODIFIER, in_mod);
        mlxsw_pci_write32(mlxsw_pci, CIR_TOKEN, 0);
index 3e52ee93438c00188d0efe6482cfbd9f686b8ee9..62cbbd1ada8da6a5d8343beb394b67dc5af6a81c 100644 (file)
@@ -1069,9 +1069,9 @@ static int mlxsw_sx_port_create(struct mlxsw_sx *mlxsw_sx, u8 local_port)
        return 0;
 
 err_register_netdev:
-err_port_admin_status_set:
 err_port_mac_learning_mode_set:
 err_port_stp_state_set:
+err_port_admin_status_set:
 err_port_mtu_set:
 err_port_speed_set:
 err_port_swid_set:
index 66fd868152e579a4ba3483fd4726f0e9d9662436..b159ef8303cc3e65d1e374367d19ca590d934901 100644 (file)
@@ -476,13 +476,12 @@ static void __lpc_get_mac(struct netdata_local *pldat, u8 *mac)
        mac[5] = tmp >> 8;
 }
 
-static void __lpc_eth_clock_enable(struct netdata_local *pldat,
-                                  bool enable)
+static void __lpc_eth_clock_enable(struct netdata_local *pldat, bool enable)
 {
        if (enable)
-               clk_enable(pldat->clk);
+               clk_prepare_enable(pldat->clk);
        else
-               clk_disable(pldat->clk);
+               clk_disable_unprepare(pldat->clk);
 }
 
 static void __lpc_params_setup(struct netdata_local *pldat)
@@ -1494,7 +1493,7 @@ err_out_free_irq:
 err_out_iounmap:
        iounmap(pldat->net_base);
 err_out_disable_clocks:
-       clk_disable(pldat->clk);
+       clk_disable_unprepare(pldat->clk);
        clk_put(pldat->clk);
 err_out_free_dev:
        free_netdev(ndev);
@@ -1519,7 +1518,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
        iounmap(pldat->net_base);
        mdiobus_unregister(pldat->mii_bus);
        mdiobus_free(pldat->mii_bus);
-       clk_disable(pldat->clk);
+       clk_disable_unprepare(pldat->clk);
        clk_put(pldat->clk);
        free_netdev(ndev);
 
@@ -1540,7 +1539,7 @@ static int lpc_eth_drv_suspend(struct platform_device *pdev,
                if (netif_running(ndev)) {
                        netif_device_detach(ndev);
                        __lpc_eth_shutdown(pldat);
-                       clk_disable(pldat->clk);
+                       clk_disable_unprepare(pldat->clk);
 
                        /*
                         * Reset again now clock is disable to be sure
index a83263743665411eacb0ca845e23f52db612866c..2b7550c43f7800fe36e54fafacabfcd921c408f4 100644 (file)
@@ -2134,10 +2134,11 @@ static int rhine_rx(struct net_device *dev, int limit)
                        }
 
                        skb_put(skb, pkt_len);
-                       skb->protocol = eth_type_trans(skb, dev);
 
                        rhine_rx_vlan_tag(skb, desc, data_size);
 
+                       skb->protocol = eth_type_trans(skb, dev);
+
                        netif_receive_skb(skb);
 
                        u64_stats_update_begin(&rp->rx_stats.syncp);
index 8f5c02eed47de09883b43b8b587717993064ef0b..cde29f8a37bfebe036273f3a76bbc24b0e034fff 100644 (file)
@@ -870,14 +870,14 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
        __be16 dst_port = htons(GENEVE_UDP_PORT);
        __u8 ttl = 0, tos = 0;
        bool metadata = false;
-       __be32 rem_addr;
-       __u32 vni;
+       __be32 rem_addr = 0;
+       __u32 vni = 0;
 
-       if (!data[IFLA_GENEVE_ID] || !data[IFLA_GENEVE_REMOTE])
-               return -EINVAL;
+       if (data[IFLA_GENEVE_ID])
+               vni = nla_get_u32(data[IFLA_GENEVE_ID]);
 
-       vni = nla_get_u32(data[IFLA_GENEVE_ID]);
-       rem_addr = nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
+       if (data[IFLA_GENEVE_REMOTE])
+               rem_addr = nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
 
        if (data[IFLA_GENEVE_TTL])
                ttl = nla_get_u8(data[IFLA_GENEVE_TTL]);
index c5ad98ace5d0abeff5d6ef8f3f028e537b241a8e..11e3975485c1eaa377b7ee82a3d3eef5a3b00ffe 100644 (file)
@@ -168,8 +168,6 @@ config MDIO_OCTEON
          busses. It is required by the Octeon and ThunderX ethernet device
          drivers.
 
-         If in doubt, say Y.
-
 config MDIO_SUN4I
        tristate "Allwinner sun4i MDIO interface support"
        depends on ARCH_SUNXI
index 3837ae344f63b9d69a5dd958d0e7b7dc202ff316..2ed75060da50abe74a7f303010aad8c937a31b73 100644 (file)
@@ -313,7 +313,6 @@ static void pppoe_flush_dev(struct net_device *dev)
                        if (po->pppoe_dev == dev &&
                            sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
                                pppox_unbind_sock(sk);
-                               sk->sk_state = PPPOX_ZOMBIE;
                                sk->sk_state_change(sk);
                                po->pppoe_dev = NULL;
                                dev_put(dev);
index fbb9325d1f6e539421f2ad592d718bcede68acea..e66805eeffb45f014a9c61d20e0bd6f3b473098b 100644 (file)
@@ -164,6 +164,7 @@ config USB_NET_AX8817X
            * Aten UC210T
            * ASIX AX88172
            * Billionton Systems, USB2AR
+           * Billionton Systems, GUSB2AM-1G-B
            * Buffalo LUA-U2-KTX
            * Corega FEther USB2-TX
            * D-Link DUB-E100
index 75d6f26729a30e34cdaaf8334a9cc0aaa2a01c82..079069a060a62fdb42cb9dff9acbcd55148277b8 100644 (file)
@@ -91,8 +91,10 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
                        }
                        rx->ax_skb = netdev_alloc_skb_ip_align(dev->net,
                                                               rx->size);
-                       if (!rx->ax_skb)
+                       if (!rx->ax_skb) {
+                               rx->size = 0;
                                return 0;
+                       }
                }
 
                if (rx->size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) {
index 1173a24feda38c3af236c84acaf8982f39c0e0b1..5cabefc2349438f26cddde0022d52acf6e967116 100644 (file)
@@ -958,6 +958,10 @@ static const struct usb_device_id  products [] = {
        // Billionton Systems, USB2AR
        USB_DEVICE (0x08dd, 0x90ff),
        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Billionton Systems, GUSB2AM-1G-B
+       USB_DEVICE(0x08dd, 0x0114),
+       .driver_info =  (unsigned long) &ax88178_info,
 }, {
        // ATEN UC210T
        USB_DEVICE (0x0557, 0x2009),
index bbac1d35ed4e37450a3282b4b7f9dc41dabcd4e8..afdc65fd5bc57c9101c9ffcb4aeac7cfe2431a63 100644 (file)
@@ -2745,11 +2745,10 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
        struct vxlan_config conf;
        int err;
 
-       if (!data[IFLA_VXLAN_ID])
-               return -EINVAL;
-
        memset(&conf, 0, sizeof(conf));
-       conf.vni = nla_get_u32(data[IFLA_VXLAN_ID]);
+
+       if (data[IFLA_VXLAN_ID])
+               conf.vni = nla_get_u32(data[IFLA_VXLAN_ID]);
 
        if (data[IFLA_VXLAN_GROUP]) {
                conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
index 23afcda2de967637d73c7039d0f2cdb5f3b777ff..678d72af4a9df73976b7513d9af17888bc1ef7d1 100644 (file)
@@ -337,7 +337,7 @@ enum ath10k_hw_rate_cck {
 #define TARGET_10X_MAX_FRAG_ENTRIES            0
 
 /* 10.2 parameters */
-#define TARGET_10_2_DMA_BURST_SIZE             1
+#define TARGET_10_2_DMA_BURST_SIZE             0
 
 /* Target specific defines for WMI-TLV firmware */
 #define TARGET_TLV_NUM_VDEVS                   4
@@ -391,7 +391,7 @@ enum ath10k_hw_rate_cck {
 
 #define TARGET_10_4_TX_DBG_LOG_SIZE            1024
 #define TARGET_10_4_NUM_WDS_ENTRIES            32
-#define TARGET_10_4_DMA_BURST_SIZE             1
+#define TARGET_10_4_DMA_BURST_SIZE             0
 #define TARGET_10_4_MAC_AGGR_DELIM             0
 #define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
 #define TARGET_10_4_VOW_CONFIG                 0
index 57f95f2dca5b072ac294b2c76122ec1b952a2a80..90eb75012e4f4818a03481d98cb9b137a89393fa 100644 (file)
@@ -880,6 +880,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->max_rate_tries = 10;
        hw->sta_data_size = sizeof(struct ath_node);
        hw->vif_data_size = sizeof(struct ath_vif);
+       hw->extra_tx_headroom = 4;
 
        hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
        hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
index 28490702124a0da53bb2834f1ca880a452d6523b..71d3e9adbf3c02b4d5ff50843a2b4b06cd96b6a5 100644 (file)
@@ -120,6 +120,7 @@ MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if over
 #ifdef CONFIG_B43_BCMA
 static const struct bcma_device_id b43_bcma_tbl[] = {
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
+       BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x15, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
index ab45819c1fbbf6d0080813c26090bb095082672d..e18629a16fb0260dff9b3486c572f4bfd2166fcd 100644 (file)
@@ -1020,7 +1020,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
                        u8 *pn = seq.ccmp.pn;
 
                        ieee80211_get_key_rx_seq(key, i, &seq);
-                       aes_sc->pn = cpu_to_le64(
+                       aes_sc[i].pn = cpu_to_le64(
                                        (u64)pn[5] |
                                        ((u64)pn[4] << 8) |
                                        ((u64)pn[3] << 16) |
index 6951aba620eb74a13f6fc2c2da36a043272d8a43..3fb327d5a911aeba53e4ac71ad6bb2ad419d06b0 100644 (file)
@@ -348,6 +348,6 @@ const struct iwl_cfg iwl7265d_n_cfg = {
 };
 
 MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
-MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
+MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
 MODULE_FIRMWARE(IWL7265D_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
index 04264e417c1c644e2b362e9bf29760489cfcae4f..576187611e614adc3a92ca50c4e1f2ab3a7bb7e1 100644 (file)
@@ -274,18 +274,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                break;
        case WLAN_CIPHER_SUITE_CCMP:
                if (sta) {
-                       u8 *pn = seq.ccmp.pn;
+                       u64 pn64;
 
                        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
                        aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
 
-                       ieee80211_get_key_tx_seq(key, &seq);
-                       aes_tx_sc->pn = cpu_to_le64((u64)pn[5] |
-                                                   ((u64)pn[4] << 8) |
-                                                   ((u64)pn[3] << 16) |
-                                                   ((u64)pn[2] << 24) |
-                                                   ((u64)pn[1] << 32) |
-                                                   ((u64)pn[0] << 40));
+                       pn64 = atomic64_read(&key->tx_pn);
+                       aes_tx_sc->pn = cpu_to_le64(pn64);
                } else {
                        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
                }
@@ -298,12 +293,12 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                        u8 *pn = seq.ccmp.pn;
 
                        ieee80211_get_key_rx_seq(key, i, &seq);
-                       aes_sc->pn = cpu_to_le64((u64)pn[5] |
-                                                ((u64)pn[4] << 8) |
-                                                ((u64)pn[3] << 16) |
-                                                ((u64)pn[2] << 24) |
-                                                ((u64)pn[1] << 32) |
-                                                ((u64)pn[0] << 40));
+                       aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
+                                                  ((u64)pn[4] << 8) |
+                                                  ((u64)pn[3] << 16) |
+                                                  ((u64)pn[2] << 24) |
+                                                  ((u64)pn[1] << 32) |
+                                                  ((u64)pn[0] << 40));
                }
                data->use_rsc_tsc = true;
                break;
@@ -1453,15 +1448,15 @@ static void iwl_mvm_d3_update_gtks(struct ieee80211_hw *hw,
 
                switch (key->cipher) {
                case WLAN_CIPHER_SUITE_CCMP:
-                       iwl_mvm_aes_sc_to_seq(&sc->aes.tsc, &seq);
                        iwl_mvm_set_aes_rx_seq(sc->aes.unicast_rsc, key);
+                       atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn));
                        break;
                case WLAN_CIPHER_SUITE_TKIP:
                        iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
                        iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
+                       ieee80211_set_key_tx_seq(key, &seq);
                        break;
                }
-               ieee80211_set_key_tx_seq(key, &seq);
 
                /* that's it for this key */
                return;
index 4a0ce83315bdd212d1714956af8900ea271f62b6..5c7f7cc9ffcc2aa1d81cbf1ff5b2d33f46133727 100644 (file)
@@ -703,7 +703,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
         * abort after reading the nvm in case RF Kill is on, we will complete
         * the init seq later when RF kill will switch to off
         */
-       if (iwl_mvm_is_radio_killed(mvm)) {
+       if (iwl_mvm_is_radio_hw_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm,
                                  "jump over all phy activities due to RF kill\n");
                iwl_remove_notification(&mvm->notif_wait, &calib_wait);
@@ -736,7 +736,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
        ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
                        MVM_UCODE_CALIB_TIMEOUT);
 
-       if (ret && iwl_mvm_is_radio_killed(mvm)) {
+       if (ret && iwl_mvm_is_radio_hw_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
                ret = 1;
        }
index aa8c2b7f23c73862f0526f109ad647cc0c80a259..7c2944a72470b92acdca39a6f7c13b845b34842a 100644 (file)
@@ -2388,6 +2388,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
                iwl_mvm_remove_time_event(mvm, mvmvif,
                                          &mvmvif->time_event_data);
                RCU_INIT_POINTER(mvm->csa_vif, NULL);
+               mvmvif->csa_countdown = false;
        }
 
        if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
index b95a07ec9e362bf031f960dee35dc52c97221ed0..c754051a4ceacf138d4e6399c9cc679d8a9979c0 100644 (file)
@@ -860,6 +860,11 @@ static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
               test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
 }
 
+static inline bool iwl_mvm_is_radio_hw_killed(struct iwl_mvm *mvm)
+{
+       return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
+}
+
 /* Must be called with rcu_read_lock() held and it can only be
  * released when mvmsta is not needed anymore.
  */
index a37de3f410a01e0b594f41d43bfda4360273e324..f0cb092f980ec26b26e9ca3c6cadf813f39de853 100644 (file)
@@ -590,6 +590,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        ieee80211_unregister_hw(mvm->hw);
        iwl_mvm_leds_exit(mvm);
  out_free:
+       flush_delayed_work(&mvm->fw_dump_wk);
        iwl_phy_db_free(mvm->phy_db);
        kfree(mvm->scan_cmd);
        if (!cfg->no_power_up_nic_in_init || !mvm->nvm_file_name)
index b0825c402c732c0514637b3b21b26288a7275444..644b58bc5226c52b3cdee0a24b9a392c25e8ac02 100644 (file)
@@ -414,6 +414,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5F10, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5212, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
 
 /* 8000 Series */
        {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
index 5932306084fd305a6f45ccf03d8957b771eaaa13..bf9afbf46c1bbbc1220bad06e429d2622a1f9f58 100644 (file)
@@ -1114,6 +1114,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x0db0, 0x871c) },
        { USB_DEVICE(0x0db0, 0x899a) },
        /* Ovislink */
+       { USB_DEVICE(0x1b75, 0x3070) },
        { USB_DEVICE(0x1b75, 0x3071) },
        { USB_DEVICE(0x1b75, 0x3072) },
        { USB_DEVICE(0x1b75, 0xa200) },
index d4567d12e07ebd13f17f0097baeec41a25702d31..5da6703942d9dd08017d896070404fdbe29a96e4 100644 (file)
@@ -247,6 +247,8 @@ struct rtl_pci {
        /* MSI support */
        bool msi_support;
        bool using_msi;
+       /* interrupt clear before set */
+       bool int_clear;
 };
 
 struct mp_adapter {
index b7f18e2155eb18358cf4d4f9f3f82774f9b6f522..6e9418ed90c289bee5b7f2dfc478f847dfc7ca68 100644 (file)
@@ -2253,11 +2253,28 @@ void rtl8821ae_set_qos(struct ieee80211_hw *hw, int aci)
        }
 }
 
+static void rtl8821ae_clear_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 tmp = rtl_read_dword(rtlpriv, REG_HISR);
+
+       rtl_write_dword(rtlpriv, REG_HISR, tmp);
+
+       tmp = rtl_read_dword(rtlpriv, REG_HISRE);
+       rtl_write_dword(rtlpriv, REG_HISRE, tmp);
+
+       tmp = rtl_read_dword(rtlpriv, REG_HSISR);
+       rtl_write_dword(rtlpriv, REG_HSISR, tmp);
+}
+
 void rtl8821ae_enable_interrupt(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
+       if (!rtlpci->int_clear)
+               rtl8821ae_clear_interrupt(hw);/*clear it here first*/
+
        rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
        rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
        rtlpci->irq_enabled = true;
index a4988121e1ab6a20bad5ad9b5934c166a41f36d6..8ee141a55bc5cc6b566e79dde58cdb05583e7fdf 100644 (file)
@@ -96,6 +96,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
 
        rtl8821ae_bt_reg_init(hw);
        rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+       rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
        rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
 
        rtlpriv->dm.dm_initialgain_enable = 1;
@@ -167,6 +168,7 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
        rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
        rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+       rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
        if (rtlpriv->cfg->mod_params->disable_watchdog)
                pr_info("watchdog disabled\n");
        rtlpriv->psc.reg_fwctrl_lps = 3;
@@ -308,6 +310,7 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
        .swctrl_lps = false,
        .fwctrl_lps = true,
        .msi_support = true,
+       .int_clear = true,
        .debug = DBG_EMERG,
        .disable_watchdog = 0,
 };
@@ -437,6 +440,7 @@ module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
 module_param_named(msi, rtl8821ae_mod_params.msi_support, bool, 0444);
 module_param_named(disable_watchdog, rtl8821ae_mod_params.disable_watchdog,
                   bool, 0444);
+module_param_named(int_clear, rtl8821ae_mod_params.int_clear, bool, 0444);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
@@ -444,6 +448,7 @@ MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
 MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
+MODULE_PARM_DESC(int_clear, "Set to 1 to disable interrupt clear before set (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index b90ca618b123209a1724bc808c4fdfe8ea330a69..4544752a2ba83ca173f7cb4f14abc72538b73beb 100644 (file)
@@ -2249,6 +2249,9 @@ struct rtl_mod_params {
 
        /* default 0: 1 means disable */
        bool disable_watchdog;
+
+       /* default 0: 1 means do not disable interrupts */
+       bool int_clear;
 };
 
 struct rtl_hal_usbint_cfg {
index 929a6e7e5ecfe9249569c0059516e531fb0b79eb..56ebd8267386e6a91cabf506962e15f5d83531ec 100644 (file)
@@ -788,6 +788,12 @@ static void connect(struct backend_info *be)
        /* Use the number of queues requested by the frontend */
        be->vif->queues = vzalloc(requested_num_queues *
                                  sizeof(struct xenvif_queue));
+       if (!be->vif->queues) {
+               xenbus_dev_fatal(dev, -ENOMEM,
+                                "allocating queues");
+               return;
+       }
+
        be->vif->num_queues = requested_num_queues;
        be->vif->stalled_queues = requested_num_queues;
 
index cb1b9bbda332116b6e2173b011ff9fd58f83f431..b36d837c701ec9fe94280a91df3cf1e359ad50af 100644 (file)
@@ -64,7 +64,7 @@ struct unix_sock {
        struct socket_wq        peer_wq;
 };
 
-static inline struct unix_sock *unix_sk(struct sock *sk)
+static inline struct unix_sock *unix_sk(const struct sock *sk)
 {
        return (struct unix_sock *)sk;
 }
index 186f3a1e1b1f6ddd898d0f5871cb46222ae6b80d..fc19376986259de8faf9c2be4c5c3376780e54ff 100644 (file)
@@ -113,12 +113,12 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
 void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo,
                          bool rearm);
 
-static void inline inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo)
+static inline void inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo)
 {
        __inet_twsk_schedule(tw, timeo, false);
 }
 
-static void inline inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo)
+static inline void inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo)
 {
        __inet_twsk_schedule(tw, timeo, true);
 }
index 7aa78440559a47db8e5ccc8ea69a34f87b90c125..e23717013a4e6cb1ef84e6b8ba6654b011ee8670 100644 (file)
@@ -828,6 +828,14 @@ static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *s
        if (sk_rcvqueues_full(sk, limit))
                return -ENOBUFS;
 
+       /*
+        * If the skb was allocated from pfmemalloc reserves, only
+        * allow SOCK_MEMALLOC sockets to use it as this socket is
+        * helping free memory
+        */
+       if (skb_pfmemalloc(skb) && !sock_flag(sk, SOCK_MEMALLOC))
+               return -ENOMEM;
+
        __sk_add_backlog(sk, skb);
        sk->sk_backlog.len += skb->truesize;
        return 0;
index 32e07d8cbaf47cf80841adf0e872d85c26c8c708..036f73bc54cd692763dc04954151d45a28f5e98d 100644 (file)
@@ -323,10 +323,10 @@ enum ovs_key_attr {
        OVS_KEY_ATTR_MPLS,      /* array of struct ovs_key_mpls.
                                 * The implementation may restrict
                                 * the accepted length of the array. */
-       OVS_KEY_ATTR_CT_STATE,  /* u8 bitmask of OVS_CS_F_* */
+       OVS_KEY_ATTR_CT_STATE,  /* u32 bitmask of OVS_CS_F_* */
        OVS_KEY_ATTR_CT_ZONE,   /* u16 connection tracking zone. */
        OVS_KEY_ATTR_CT_MARK,   /* u32 connection tracking mark */
-       OVS_KEY_ATTR_CT_LABEL /* 16-octet connection tracking label */
+       OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */
 
 #ifdef __KERNEL__
        OVS_KEY_ATTR_TUNNEL_INFO,  /* struct ip_tunnel_info */
@@ -439,9 +439,9 @@ struct ovs_key_nd {
        __u8    nd_tll[ETH_ALEN];
 };
 
-#define OVS_CT_LABEL_LEN       16
-struct ovs_key_ct_label {
-       __u8    ct_label[OVS_CT_LABEL_LEN];
+#define OVS_CT_LABELS_LEN      16
+struct ovs_key_ct_labels {
+       __u8    ct_labels[OVS_CT_LABELS_LEN];
 };
 
 /* OVS_KEY_ATTR_CT_STATE flags */
@@ -449,9 +449,9 @@ struct ovs_key_ct_label {
 #define OVS_CS_F_ESTABLISHED       0x02 /* Part of an existing connection. */
 #define OVS_CS_F_RELATED           0x04 /* Related to an established
                                         * connection. */
-#define OVS_CS_F_INVALID           0x20 /* Could not track connection. */
-#define OVS_CS_F_REPLY_DIR         0x40 /* Flow is in the reply direction. */
-#define OVS_CS_F_TRACKED           0x80 /* Conntrack has occurred. */
+#define OVS_CS_F_REPLY_DIR         0x08 /* Flow is in the reply direction. */
+#define OVS_CS_F_INVALID           0x10 /* Could not track connection. */
+#define OVS_CS_F_TRACKED           0x20 /* Conntrack has occurred. */
 
 /**
  * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
@@ -618,22 +618,24 @@ struct ovs_action_hash {
 
 /**
  * enum ovs_ct_attr - Attributes for %OVS_ACTION_ATTR_CT action.
- * @OVS_CT_ATTR_FLAGS: u32 connection tracking flags.
+ * @OVS_CT_ATTR_COMMIT: If present, commits the connection to the conntrack
+ * table. This allows future packets for the same connection to be identified
+ * as 'established' or 'related'.
  * @OVS_CT_ATTR_ZONE: u16 connection tracking zone.
  * @OVS_CT_ATTR_MARK: u32 value followed by u32 mask. For each bit set in the
  * mask, the corresponding bit in the value is copied to the connection
  * tracking mark field in the connection.
- * @OVS_CT_ATTR_LABEL: %OVS_CT_LABEL_LEN value followed by %OVS_CT_LABEL_LEN
+ * @OVS_CT_ATTR_LABEL: %OVS_CT_LABELS_LEN value followed by %OVS_CT_LABELS_LEN
  * mask. For each bit set in the mask, the corresponding bit in the value is
  * copied to the connection tracking label field in the connection.
  * @OVS_CT_ATTR_HELPER: variable length string defining conntrack ALG.
  */
 enum ovs_ct_attr {
        OVS_CT_ATTR_UNSPEC,
-       OVS_CT_ATTR_FLAGS,      /* u8 bitmask of OVS_CT_F_*. */
+       OVS_CT_ATTR_COMMIT,     /* No argument, commits connection. */
        OVS_CT_ATTR_ZONE,       /* u16 zone id. */
        OVS_CT_ATTR_MARK,       /* mark to associate with this connection. */
-       OVS_CT_ATTR_LABEL,      /* label to associate with this connection. */
+       OVS_CT_ATTR_LABELS,     /* labels to associate with this connection. */
        OVS_CT_ATTR_HELPER,     /* netlink helper to assist detection of
                                   related connections. */
        __OVS_CT_ATTR_MAX
@@ -641,14 +643,6 @@ enum ovs_ct_attr {
 
 #define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1)
 
-/*
- * OVS_CT_ATTR_FLAGS flags - bitmask of %OVS_CT_F_*
- * @OVS_CT_F_COMMIT: Commits the flow to the conntrack table. This allows
- * future packets for the same connection to be identified as 'established'
- * or 'related'.
- */
-#define OVS_CT_F_COMMIT                0x01
-
 /**
  * enum ovs_action_attr - Action types.
  *
@@ -705,7 +699,7 @@ enum ovs_action_attr {
                                       * data immediately followed by a mask.
                                       * The data must be zero for the unmasked
                                       * bits. */
-       OVS_ACTION_ATTR_CT,           /* One nested OVS_CT_ATTR_* . */
+       OVS_ACTION_ATTR_CT,           /* Nested OVS_CT_ATTR_* . */
 
        __OVS_ACTION_ATTR_MAX,        /* Nothing past this will be accepted
                                       * from userspace. */
index 702024769c74bc39f1e9f8400b23ec5bbd7a8ffb..9d8f5d10c1e553122be08d3407434ea24d19c136 100644 (file)
@@ -160,7 +160,7 @@ struct rtattr {
 
 /* Macros to handle rtattributes */
 
-#define RTA_ALIGNTO    4
+#define RTA_ALIGNTO    4U
 #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
 #define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
                         (rta)->rta_len >= sizeof(struct rtattr) && \
index b4548c739a6475446d643bd5b01ab8627ef1f08e..2dda439c8cb83b7fa72b238dcf93023088762001 100644 (file)
@@ -91,10 +91,50 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
         * autoconnect action, remove them completely. If they are, just unmark
         * them as waiting for connection, by clearing explicit_connect field.
         */
-       if (params->auto_connect == HCI_AUTO_CONN_EXPLICIT)
+       params->explicit_connect = false;
+
+       list_del_init(&params->action);
+
+       switch (params->auto_connect) {
+       case HCI_AUTO_CONN_EXPLICIT:
                hci_conn_params_del(conn->hdev, bdaddr, bdaddr_type);
-       else
-               params->explicit_connect = false;
+               /* return instead of break to avoid duplicate scan update */
+               return;
+       case HCI_AUTO_CONN_DIRECT:
+       case HCI_AUTO_CONN_ALWAYS:
+               list_add(&params->action, &conn->hdev->pend_le_conns);
+               break;
+       case HCI_AUTO_CONN_REPORT:
+               list_add(&params->action, &conn->hdev->pend_le_reports);
+               break;
+       default:
+               break;
+       }
+
+       hci_update_background_scan(conn->hdev);
+}
+
+static void hci_conn_cleanup(struct hci_conn *conn)
+{
+       struct hci_dev *hdev = conn->hdev;
+
+       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
+               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
+
+       hci_chan_list_flush(conn);
+
+       hci_conn_hash_del(hdev, conn);
+
+       if (hdev->notify)
+               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
+
+       hci_conn_del_sysfs(conn);
+
+       debugfs_remove_recursive(conn->debugfs);
+
+       hci_dev_put(hdev);
+
+       hci_conn_put(conn);
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -102,8 +142,13 @@ static void hci_connect_le_scan_remove(struct hci_conn *conn)
 {
        hci_connect_le_scan_cleanup(conn);
 
-       hci_conn_hash_del(conn->hdev, conn);
-       hci_update_background_scan(conn->hdev);
+       /* We can't call hci_conn_del here since that would deadlock
+        * with trying to call cancel_delayed_work_sync(&conn->disc_work).
+        * Instead, call just hci_conn_cleanup() which contains the bare
+        * minimum cleanup operations needed for a connection in this
+        * state.
+        */
+       hci_conn_cleanup(conn);
 }
 
 static void hci_acl_create_connection(struct hci_conn *conn)
@@ -581,27 +626,17 @@ int hci_conn_del(struct hci_conn *conn)
                }
        }
 
-       hci_chan_list_flush(conn);
-
        if (conn->amp_mgr)
                amp_mgr_put(conn->amp_mgr);
 
-       hci_conn_hash_del(hdev, conn);
-       if (hdev->notify)
-               hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
-
        skb_queue_purge(&conn->data_q);
 
-       hci_conn_del_sysfs(conn);
-
-       debugfs_remove_recursive(conn->debugfs);
-
-       if (test_bit(HCI_CONN_PARAM_REMOVAL_PEND, &conn->flags))
-               hci_conn_params_del(conn->hdev, &conn->dst, conn->dst_type);
-
-       hci_dev_put(hdev);
-
-       hci_conn_put(conn);
+       /* Remove the connection from the list and cleanup its remaining
+        * state. This is a separate function since for some cases like
+        * BT_CONNECT_SCAN we *only* want the cleanup part without the
+        * rest of hci_conn_del.
+        */
+       hci_conn_cleanup(conn);
 
        return 0;
 }
@@ -973,15 +1008,23 @@ static int hci_explicit_conn_params_set(struct hci_request *req,
        if (is_connected(hdev, addr, addr_type))
                return -EISCONN;
 
-       params = hci_conn_params_add(hdev, addr, addr_type);
-       if (!params)
-               return -EIO;
+       params = hci_conn_params_lookup(hdev, addr, addr_type);
+       if (!params) {
+               params = hci_conn_params_add(hdev, addr, addr_type);
+               if (!params)
+                       return -ENOMEM;
 
-       /* If we created new params, or existing params were marked as disabled,
-        * mark them to be used just once to connect.
-        */
-       if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+               /* If we created new params, mark them to be deleted in
+                * hci_connect_le_scan_cleanup. It's different case than
+                * existing disabled params, those will stay after cleanup.
+                */
                params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+       }
+
+       /* We're trying to connect, so make sure params are at pend_le_conns */
+       if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+           params->auto_connect == HCI_AUTO_CONN_REPORT ||
+           params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
                list_del_init(&params->action);
                list_add(&params->action, &hdev->pend_le_conns);
        }
index adcbc74c243268e8330bf760c39fa792a1c2a3a8..e837539452fb0e2880d8335da7769752a3b08110 100644 (file)
@@ -2861,13 +2861,6 @@ struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev,
                        return param;
        }
 
-       list_for_each_entry(param, &hdev->pend_le_reports, action) {
-               if (bacmp(&param->addr, addr) == 0 &&
-                   param->addr_type == addr_type &&
-                   param->explicit_connect)
-                       return param;
-       }
-
        return NULL;
 }
 
index 186041866315a4e107de086df52142f39d6c6ee3..bc31099d3b5bd113a8496b2ccad9e3e40364187f 100644 (file)
@@ -55,7 +55,12 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
        wake_up_bit(&hdev->flags, HCI_INQUIRY);
 
        hci_dev_lock(hdev);
-       hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+       /* Set discovery state to stopped if we're not doing LE active
+        * scanning.
+        */
+       if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
+           hdev->le_scan_type != LE_SCAN_ACTIVE)
+               hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
        hci_dev_unlock(hdev);
 
        hci_conn_check_pending(hdev);
@@ -4648,8 +4653,8 @@ static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
        /* If we're not connectable only connect devices that we have in
         * our pend_le_conns list.
         */
-       params = hci_explicit_connect_lookup(hdev, addr, addr_type);
-
+       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
+                                          addr_type);
        if (!params)
                return NULL;
 
index ccaf5a436d8f7a70799729a04ffc17583d11913f..c4fe2fee753fcfaa4233a4bb6675bbbdd29fc9d5 100644 (file)
@@ -3545,6 +3545,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                                       auth_type);
        } else {
                u8 addr_type;
+               struct hci_conn_params *p;
 
                /* Convert from L2CAP channel address type to HCI address type
                 */
@@ -3562,7 +3563,10 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                 * If connection parameters already exist, then they
                 * will be kept and this function does nothing.
                 */
-               hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+               p = hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
+
+               if (p->auto_connect == HCI_AUTO_CONN_EXPLICIT)
+                       p->auto_connect = HCI_AUTO_CONN_DISABLED;
 
                conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr,
                                           addr_type, sec_level,
@@ -6117,14 +6121,21 @@ static int hci_conn_params_set(struct hci_request *req, bdaddr_t *addr,
                __hci_update_background_scan(req);
                break;
        case HCI_AUTO_CONN_REPORT:
-               list_add(&params->action, &hdev->pend_le_reports);
+               if (params->explicit_connect)
+                       list_add(&params->action, &hdev->pend_le_conns);
+               else
+                       list_add(&params->action, &hdev->pend_le_reports);
                __hci_update_background_scan(req);
                break;
        case HCI_AUTO_CONN_DIRECT:
        case HCI_AUTO_CONN_ALWAYS:
                if (!is_connected(hdev, addr, addr_type)) {
                        list_add(&params->action, &hdev->pend_le_conns);
-                       __hci_update_background_scan(req);
+                       /* If we are in scan phase of connecting, we were
+                        * already added to pend_le_conns and scanning.
+                        */
+                       if (params->auto_connect != HCI_AUTO_CONN_EXPLICIT)
+                               __hci_update_background_scan(req);
                }
                break;
        }
@@ -6379,7 +6390,8 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
                        goto unlock;
                }
 
-               if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
+               if (params->auto_connect == HCI_AUTO_CONN_DISABLED ||
+                   params->auto_connect == HCI_AUTO_CONN_EXPLICIT) {
                        err = cmd->cmd_complete(cmd,
                                                MGMT_STATUS_INVALID_PARAMS);
                        mgmt_pending_remove(cmd);
@@ -6415,6 +6427,10 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
                        if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
                                continue;
                        device_removed(sk, hdev, &p->addr, p->addr_type);
+                       if (p->explicit_connect) {
+                               p->auto_connect = HCI_AUTO_CONN_EXPLICIT;
+                               continue;
+                       }
                        list_del(&p->action);
                        list_del(&p->list);
                        kfree(p);
index b495ab1797fae303d12a3251f09b141052c1ff55..29edf74846fc9cfef49f3fc35b4ba41de6c254af 100644 (file)
@@ -1284,7 +1284,7 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
 
        gstrings.len = ret;
 
-       data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
+       data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
        if (!data)
                return -ENOMEM;
 
index 05a04ea871728d2c18f68571321e9435df1f3b18..bb18c368000129ebea752a0a78785524848eaab8 100644 (file)
@@ -1415,6 +1415,7 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5)
                return dev_forward_skb(dev, skb2);
 
        skb2->dev = dev;
+       skb_sender_cpu_clear(skb2);
        return dev_queue_xmit(skb2);
 }
 
@@ -1854,9 +1855,13 @@ int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
                goto out;
 
        /* We're copying the filter that has been originally attached,
-        * so no conversion/decode needed anymore.
+        * so no conversion/decode needed anymore. eBPF programs that
+        * have no original program cannot be dumped through this.
         */
+       ret = -EACCES;
        fprog = filter->prog->orig_prog;
+       if (!fprog)
+               goto out;
 
        ret = fprog->len;
        if (!len)
index c59fa5d9c22c449b4bfa9f058575d44324cfd7f9..adb5325f49348412efb50f0eeee5a5f0fa1e50ed 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_net.h>
 #include <linux/sysfs.h>
+#include <linux/phy_fixed.h>
 #include "dsa_priv.h"
 
 char dsa_driver_version[] = "0.1";
@@ -305,7 +306,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
        if (ret < 0)
                goto out;
 
-       ds->slave_mii_bus = mdiobus_alloc();
+       ds->slave_mii_bus = devm_mdiobus_alloc(parent);
        if (ds->slave_mii_bus == NULL) {
                ret = -ENOMEM;
                goto out;
@@ -314,7 +315,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 
        ret = mdiobus_register(ds->slave_mii_bus);
        if (ret < 0)
-               goto out_free;
+               goto out;
 
 
        /*
@@ -367,10 +368,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent)
 
        return ret;
 
-out_free:
-       mdiobus_free(ds->slave_mii_bus);
 out:
-       kfree(ds);
        return ret;
 }
 
@@ -400,7 +398,7 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
        /*
         * Allocate and initialise switch state.
         */
-       ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);
+       ds = devm_kzalloc(parent, sizeof(*ds) + drv->priv_size, GFP_KERNEL);
        if (ds == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -420,10 +418,47 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 
 static void dsa_switch_destroy(struct dsa_switch *ds)
 {
+       struct device_node *port_dn;
+       struct phy_device *phydev;
+       struct dsa_chip_data *cd = ds->pd;
+       int port;
+
 #ifdef CONFIG_NET_DSA_HWMON
        if (ds->hwmon_dev)
                hwmon_device_unregister(ds->hwmon_dev);
 #endif
+
+       /* Disable configuration of the CPU and DSA ports */
+       for (port = 0; port < DSA_MAX_PORTS; port++) {
+               if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
+                       continue;
+
+               port_dn = cd->port_dn[port];
+               if (of_phy_is_fixed_link(port_dn)) {
+                       phydev = of_phy_find_device(port_dn);
+                       if (phydev) {
+                               int addr = phydev->addr;
+
+                               phy_device_free(phydev);
+                               of_node_put(port_dn);
+                               fixed_phy_del(addr);
+                       }
+               }
+       }
+
+       /* Destroy network devices for physical switch ports. */
+       for (port = 0; port < DSA_MAX_PORTS; port++) {
+               if (!(ds->phys_port_mask & (1 << port)))
+                       continue;
+
+               if (!ds->ports[port])
+                       continue;
+
+               unregister_netdev(ds->ports[port]);
+               free_netdev(ds->ports[port]);
+       }
+
+       mdiobus_unregister(ds->slave_mii_bus);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -802,10 +837,11 @@ static inline void dsa_of_remove(struct device *dev)
 }
 #endif
 
-static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
-                         struct device *parent, struct dsa_platform_data *pd)
+static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
+                        struct device *parent, struct dsa_platform_data *pd)
 {
        int i;
+       unsigned configured = 0;
 
        dst->pd = pd;
        dst->master_netdev = dev;
@@ -825,8 +861,16 @@ static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
                dst->ds[i] = ds;
                if (ds->drv->poll_link != NULL)
                        dst->link_poll_needed = 1;
+
+               ++configured;
        }
 
+       /*
+        * If no switch was found, exit cleanly
+        */
+       if (!configured)
+               return -EPROBE_DEFER;
+
        /*
         * If we use a tagging format that doesn't have an ethertype
         * field, make sure that all packets from this point on get
@@ -843,6 +887,8 @@ static void dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
                dst->link_poll_timer.expires = round_jiffies(jiffies + HZ);
                add_timer(&dst->link_poll_timer);
        }
+
+       return 0;
 }
 
 static int dsa_probe(struct platform_device *pdev)
@@ -883,7 +929,7 @@ static int dsa_probe(struct platform_device *pdev)
                goto out;
        }
 
-       dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+       dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
        if (dst == NULL) {
                dev_put(dev);
                ret = -ENOMEM;
@@ -892,7 +938,9 @@ static int dsa_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dst);
 
-       dsa_setup_dst(dst, dev, &pdev->dev, pd);
+       ret = dsa_setup_dst(dst, dev, &pdev->dev, pd);
+       if (ret)
+               goto out;
 
        return 0;
 
@@ -914,7 +962,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
        for (i = 0; i < dst->pd->nr_chips; i++) {
                struct dsa_switch *ds = dst->ds[i];
 
-               if (ds != NULL)
+               if (ds)
                        dsa_switch_destroy(ds);
        }
 }
index f03db8b7abee68806468c104470da4054a8bf755..0c9c3482e41997a671c23be7dc0387edb1403916 100644 (file)
@@ -312,7 +312,7 @@ static void arp_send_dst(int type, int ptype, __be32 dest_ip,
        if (!skb)
                return;
 
-       skb_dst_set(skb, dst);
+       skb_dst_set(skb, dst_clone(dst));
        arp_xmit(skb);
 }
 
@@ -384,7 +384,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
        }
 
        if (skb && !(dev->priv_flags & IFF_XMIT_DST_RELEASE))
-               dst = dst_clone(skb_dst(skb));
+               dst = skb_dst(skb);
        arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
                     dst_hw, dev->dev_addr, NULL, dst);
 }
@@ -811,7 +811,7 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
                                } else {
                                        pneigh_enqueue(&arp_tbl,
                                                       in_dev->arp_parms, skb);
-                                       return 0;
+                                       goto out_free_dst;
                                }
                                goto out;
                        }
@@ -865,6 +865,8 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
 
 out:
        consume_skb(skb);
+out_free_dst:
+       dst_release(reply_dst);
        return 0;
 }
 
index 7bb9c39e0a4d1a6a30b7aece9d3b0c17e447c20a..61b45a17fc738e17146a5e1f1cf97774f338179e 100644 (file)
@@ -577,21 +577,22 @@ EXPORT_SYMBOL(inet_rtx_syn_ack);
 static bool reqsk_queue_unlink(struct request_sock_queue *queue,
                               struct request_sock *req)
 {
-       struct listen_sock *lopt = queue->listen_opt;
        struct request_sock **prev;
+       struct listen_sock *lopt;
        bool found = false;
 
        spin_lock(&queue->syn_wait_lock);
-
-       for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
-            prev = &(*prev)->dl_next) {
-               if (*prev == req) {
-                       *prev = req->dl_next;
-                       found = true;
-                       break;
+       lopt = queue->listen_opt;
+       if (lopt) {
+               for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
+                    prev = &(*prev)->dl_next) {
+                       if (*prev == req) {
+                               *prev = req->dl_next;
+                               found = true;
+                               break;
+                       }
                }
        }
-
        spin_unlock(&queue->syn_wait_lock);
        if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer))
                reqsk_put(req);
index 900113376d4e0e528dc5a5d349687ae908ca08d6..36b85bd05ac8a320b1b910c7d3454da1139ecd3c 100644 (file)
@@ -3119,6 +3119,8 @@ static void addrconf_gre_config(struct net_device *dev)
        }
 
        addrconf_addr_gen(idev, true);
+       if (dev->flags & IFF_POINTOPOINT)
+               addrconf_add_mroute(dev);
 }
 #endif
 
index 92b1aa38f121507b662e2c964423952bf995b81e..61d403ee1031caa5536d9298abd4604606dff6f5 100644 (file)
@@ -376,6 +376,9 @@ int ip6_forward(struct sk_buff *skb)
        if (skb->pkt_type != PACKET_HOST)
                goto drop;
 
+       if (unlikely(skb->sk))
+               goto drop;
+
        if (skb_warn_if_lro(skb))
                goto drop;
 
index cb32ce250db0c0fd8cdc19a066f3956a893f2fba..968f31c01f89e8ccc6a4a13c056f8be3dcc0b7c6 100644 (file)
@@ -142,6 +142,9 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
        struct net_device *loopback_dev = net->loopback_dev;
        int cpu;
 
+       if (dev == loopback_dev)
+               return;
+
        for_each_possible_cpu(cpu) {
                struct uncached_list *ul = per_cpu_ptr(&rt6_uncached_list, cpu);
                struct rt6_info *rt;
@@ -151,14 +154,12 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev)
                        struct inet6_dev *rt_idev = rt->rt6i_idev;
                        struct net_device *rt_dev = rt->dst.dev;
 
-                       if (rt_idev && (rt_idev->dev == dev || !dev) &&
-                           rt_idev->dev != loopback_dev) {
+                       if (rt_idev->dev == dev) {
                                rt->rt6i_idev = in6_dev_get(loopback_dev);
                                in6_dev_put(rt_idev);
                        }
 
-                       if (rt_dev && (rt_dev == dev || !dev) &&
-                           rt_dev != loopback_dev) {
+                       if (rt_dev == dev) {
                                rt->dst.dev = loopback_dev;
                                dev_hold(rt->dst.dev);
                                dev_put(rt_dev);
@@ -247,12 +248,6 @@ static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
 {
 }
 
-static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
-                                        unsigned long old)
-{
-       return NULL;
-}
-
 static struct dst_ops ip6_dst_blackhole_ops = {
        .family                 =       AF_INET6,
        .destroy                =       ip6_dst_destroy,
@@ -261,7 +256,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .default_advmss         =       ip6_default_advmss,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
        .redirect               =       ip6_rt_blackhole_redirect,
-       .cow_metrics            =       ip6_rt_blackhole_cow_metrics,
+       .cow_metrics            =       dst_cow_metrics_generic,
        .neigh_lookup           =       ip6_neigh_lookup,
 };
 
@@ -318,6 +313,15 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
 
 #endif
 
+static void rt6_info_init(struct rt6_info *rt)
+{
+       struct dst_entry *dst = &rt->dst;
+
+       memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
+       INIT_LIST_HEAD(&rt->rt6i_siblings);
+       INIT_LIST_HEAD(&rt->rt6i_uncached);
+}
+
 /* allocate dst with ip6_dst_ops */
 static struct rt6_info *__ip6_dst_alloc(struct net *net,
                                        struct net_device *dev,
@@ -326,13 +330,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net,
        struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
                                        0, DST_OBSOLETE_FORCE_CHK, flags);
 
-       if (rt) {
-               struct dst_entry *dst = &rt->dst;
+       if (rt)
+               rt6_info_init(rt);
 
-               memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
-               INIT_LIST_HEAD(&rt->rt6i_siblings);
-               INIT_LIST_HEAD(&rt->rt6i_uncached);
-       }
        return rt;
 }
 
@@ -1213,24 +1213,20 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
 
        rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
        if (rt) {
-               new = &rt->dst;
-
-               memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
+               rt6_info_init(rt);
 
+               new = &rt->dst;
                new->__use = 1;
                new->input = dst_discard;
                new->output = dst_discard_sk;
 
-               if (dst_metrics_read_only(&ort->dst))
-                       new->_metrics = ort->dst._metrics;
-               else
-                       dst_copy_metrics(new, &ort->dst);
+               dst_copy_metrics(new, &ort->dst);
                rt->rt6i_idev = ort->rt6i_idev;
                if (rt->rt6i_idev)
                        in6_dev_hold(rt->rt6i_idev);
 
                rt->rt6i_gateway = ort->rt6i_gateway;
-               rt->rt6i_flags = ort->rt6i_flags;
+               rt->rt6i_flags = ort->rt6i_flags & ~RTF_PCPU;
                rt->rt6i_metric = 0;
 
                memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -2622,7 +2618,8 @@ void rt6_ifdown(struct net *net, struct net_device *dev)
 
        fib6_clean_all(net, fib6_ifdown, &adn);
        icmp6_clean_all(fib6_ifdown, &adn);
-       rt6_uncached_list_flush_dev(net, dev);
+       if (dev)
+               rt6_uncached_list_flush_dev(net, dev);
 }
 
 struct rt6_mtu_change_arg {
index 30caa289c5dbf589270768ce90d15f2990341231..5cedfda4b241045e92fe89971836e549b88f5074 100644 (file)
@@ -37,6 +37,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
 
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
+       fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
        memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
        if (saddr)
                memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
index ced6bf3be8d6cf5d3d9fc80b6c46f48c4e567aef..1560c8482bcb9fd587d1e278a499f99fd9958803 100644 (file)
@@ -149,7 +149,7 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
 
        for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
                if (test_bit(i, local->hw.flags))
-                       pos += scnprintf(pos, end - pos, "%s",
+                       pos += scnprintf(pos, end - pos, "%s\n",
                                         hw_flag_names[i]);
        }
 
index 8ba5832435095f10e94f782e07d92a4f742cad3a..3ed7ddfbf8e840d4c910b0e9452c06843031c91d 100644 (file)
@@ -101,6 +101,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
         * when it wakes up for the next time.
         */
        set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT);
+       ieee80211_clear_fast_xmit(sta);
 
        /*
         * This code races in the following way:
index 84e0e8c7fb236952dfc1cfcb23204623e80d7867..7892eb8ed4c8b1fa416ebcb297fab9f1cce91743 100644 (file)
@@ -1218,8 +1218,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 
        if (!tx->sta)
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
+       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+               ieee80211_check_fast_xmit(tx->sta);
+       }
 
        info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
 
@@ -2451,7 +2453,8 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
 
        if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
            test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
-           test_sta_flag(sta, WLAN_STA_PS_DELIVER))
+           test_sta_flag(sta, WLAN_STA_PS_DELIVER) ||
+           test_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT))
                goto out;
 
        if (sdata->noack_map)
index 8f060d7f9a0e107a410d3ffe71722f49059f7bc8..0a49a8c7c56432989de924e01563f692cf10e545 100644 (file)
@@ -2785,6 +2785,7 @@ static int netlink_dump(struct sock *sk)
        struct sk_buff *skb = NULL;
        struct nlmsghdr *nlh;
        int len, err = -ENOBUFS;
+       int alloc_min_size;
        int alloc_size;
 
        mutex_lock(nlk->cb_mutex);
@@ -2793,9 +2794,6 @@ static int netlink_dump(struct sock *sk)
                goto errout_skb;
        }
 
-       cb = &nlk->cb;
-       alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
-
        if (!netlink_rx_is_mmaped(sk) &&
            atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
                goto errout_skb;
@@ -2805,23 +2803,35 @@ static int netlink_dump(struct sock *sk)
         * to reduce number of system calls on dump operations, if user
         * ever provided a big enough buffer.
         */
-       if (alloc_size < nlk->max_recvmsg_len) {
-               skb = netlink_alloc_skb(sk,
-                                       nlk->max_recvmsg_len,
-                                       nlk->portid,
+       cb = &nlk->cb;
+       alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
+
+       if (alloc_min_size < nlk->max_recvmsg_len) {
+               alloc_size = nlk->max_recvmsg_len;
+               skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
                                        GFP_KERNEL |
                                        __GFP_NOWARN |
                                        __GFP_NORETRY);
-               /* available room should be exact amount to avoid MSG_TRUNC */
-               if (skb)
-                       skb_reserve(skb, skb_tailroom(skb) -
-                                        nlk->max_recvmsg_len);
        }
-       if (!skb)
+       if (!skb) {
+               alloc_size = alloc_min_size;
                skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
                                        GFP_KERNEL);
+       }
        if (!skb)
                goto errout_skb;
+
+       /* Trim skb to allocated size. User is expected to provide buffer as
+        * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at
+        * netlink_recvmsg())). dump will pack as many smaller messages as
+        * could fit within the allocated skb. skb is typically allocated
+        * with larger space than required (could be as much as near 2x the
+        * requested size with align to next power of 2 approach). Allowing
+        * dump to use the excess space makes it difficult for a user to have a
+        * reasonable static buffer based on the expected largest dump of a
+        * single netdev. The outcome is MSG_TRUNC error.
+        */
+       skb_reserve(skb, skb_tailroom(skb) - alloc_size);
        netlink_skb_set_owner_r(skb, sk);
 
        len = cb->dump(skb, cb);
index 315f5330b6e5400eaf28ce7d0290038b7113a6fd..c6a39bf2c3b954481a7217fa2b0f95778a2376b8 100644 (file)
@@ -684,7 +684,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
 {
        if (skb_network_offset(skb) > MAX_L2_LEN) {
                OVS_NLERR(1, "L2 header too long to fragment");
-               return;
+               goto err;
        }
 
        if (ethertype == htons(ETH_P_IP)) {
@@ -708,8 +708,7 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
                struct rt6_info ovs_rt;
 
                if (!v6ops) {
-                       kfree_skb(skb);
-                       return;
+                       goto err;
                }
 
                prepare_frag(vport, skb);
@@ -728,8 +727,12 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
                WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.",
                          ovs_vport_name(vport), ntohs(ethertype), mru,
                          vport->dev->mtu);
-               kfree_skb(skb);
+               goto err;
        }
+
+       return;
+err:
+       kfree_skb(skb);
 }
 
 static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
@@ -968,7 +971,7 @@ static int execute_masked_set_action(struct sk_buff *skb,
        case OVS_KEY_ATTR_CT_STATE:
        case OVS_KEY_ATTR_CT_ZONE:
        case OVS_KEY_ATTR_CT_MARK:
-       case OVS_KEY_ATTR_CT_LABEL:
+       case OVS_KEY_ATTR_CT_LABELS:
                err = -EINVAL;
                break;
        }
@@ -1099,6 +1102,12 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
                        break;
 
                case OVS_ACTION_ATTR_CT:
+                       if (!is_flow_key_valid(key)) {
+                               err = ovs_flow_key_update(skb, key);
+                               if (err)
+                                       return err;
+                       }
+
                        err = ovs_ct_execute(ovs_dp_get_net(dp), skb, key,
                                             nla_data(a));
 
index 002a755fa07ea8c6c71c762716a5be8700c0a36c..80bf702715bb3e8875ded486dbff63d86d7797f8 100644 (file)
@@ -37,9 +37,9 @@ struct md_mark {
 };
 
 /* Metadata label for masked write to conntrack label. */
-struct md_label {
-       struct ovs_key_ct_label value;
-       struct ovs_key_ct_label mask;
+struct md_labels {
+       struct ovs_key_ct_labels value;
+       struct ovs_key_ct_labels mask;
 };
 
 /* Conntrack action context for execution. */
@@ -47,10 +47,10 @@ struct ovs_conntrack_info {
        struct nf_conntrack_helper *helper;
        struct nf_conntrack_zone zone;
        struct nf_conn *ct;
-       u32 flags;
+       u8 commit : 1;
        u16 family;
        struct md_mark mark;
-       struct md_label label;
+       struct md_labels labels;
 };
 
 static u16 key_to_nfproto(const struct sw_flow_key *key)
@@ -109,21 +109,21 @@ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
 #endif
 }
 
-static void ovs_ct_get_label(const struct nf_conn *ct,
-                            struct ovs_key_ct_label *label)
+static void ovs_ct_get_labels(const struct nf_conn *ct,
+                             struct ovs_key_ct_labels *labels)
 {
        struct nf_conn_labels *cl = ct ? nf_ct_labels_find(ct) : NULL;
 
        if (cl) {
                size_t len = cl->words * sizeof(long);
 
-               if (len > OVS_CT_LABEL_LEN)
-                       len = OVS_CT_LABEL_LEN;
-               else if (len < OVS_CT_LABEL_LEN)
-                       memset(label, 0, OVS_CT_LABEL_LEN);
-               memcpy(label, cl->bits, len);
+               if (len > OVS_CT_LABELS_LEN)
+                       len = OVS_CT_LABELS_LEN;
+               else if (len < OVS_CT_LABELS_LEN)
+                       memset(labels, 0, OVS_CT_LABELS_LEN);
+               memcpy(labels, cl->bits, len);
        } else {
-               memset(label, 0, OVS_CT_LABEL_LEN);
+               memset(labels, 0, OVS_CT_LABELS_LEN);
        }
 }
 
@@ -134,7 +134,7 @@ static void __ovs_ct_update_key(struct sw_flow_key *key, u8 state,
        key->ct.state = state;
        key->ct.zone = zone->id;
        key->ct.mark = ovs_ct_get_mark(ct);
-       ovs_ct_get_label(ct, &key->ct.label);
+       ovs_ct_get_labels(ct, &key->ct.labels);
 }
 
 /* Update 'key' based on skb->nfct. If 'post_ct' is true, then OVS has
@@ -167,7 +167,7 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
 
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
 {
-       if (nla_put_u8(skb, OVS_KEY_ATTR_CT_STATE, key->ct.state))
+       if (nla_put_u32(skb, OVS_KEY_ATTR_CT_STATE, key->ct.state))
                return -EMSGSIZE;
 
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
@@ -179,8 +179,8 @@ int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb)
                return -EMSGSIZE;
 
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           nla_put(skb, OVS_KEY_ATTR_CT_LABEL, sizeof(key->ct.label),
-                   &key->ct.label))
+           nla_put(skb, OVS_KEY_ATTR_CT_LABELS, sizeof(key->ct.labels),
+                   &key->ct.labels))
                return -EMSGSIZE;
 
        return 0;
@@ -213,9 +213,9 @@ static int ovs_ct_set_mark(struct sk_buff *skb, struct sw_flow_key *key,
 #endif
 }
 
-static int ovs_ct_set_label(struct sk_buff *skb, struct sw_flow_key *key,
-                           const struct ovs_key_ct_label *label,
-                           const struct ovs_key_ct_label *mask)
+static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
+                            const struct ovs_key_ct_labels *labels,
+                            const struct ovs_key_ct_labels *mask)
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn_labels *cl;
@@ -235,15 +235,15 @@ static int ovs_ct_set_label(struct sk_buff *skb, struct sw_flow_key *key,
                nf_ct_labels_ext_add(ct);
                cl = nf_ct_labels_find(ct);
        }
-       if (!cl || cl->words * sizeof(long) < OVS_CT_LABEL_LEN)
+       if (!cl || cl->words * sizeof(long) < OVS_CT_LABELS_LEN)
                return -ENOSPC;
 
-       err = nf_connlabels_replace(ct, (u32 *)label, (u32 *)mask,
-                                   OVS_CT_LABEL_LEN / sizeof(u32));
+       err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
+                                   OVS_CT_LABELS_LEN / sizeof(u32));
        if (err)
                return err;
 
-       ovs_ct_get_label(ct, &key->ct.label);
+       ovs_ct_get_labels(ct, &key->ct.labels);
        return 0;
 }
 
@@ -465,12 +465,12 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
        return 0;
 }
 
-static bool label_nonzero(const struct ovs_key_ct_label *label)
+static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
 {
        size_t i;
 
-       for (i = 0; i < sizeof(*label); i++)
-               if (label->ct_label[i])
+       for (i = 0; i < sizeof(*labels); i++)
+               if (labels->ct_labels[i])
                        return true;
 
        return false;
@@ -493,7 +493,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                        return err;
        }
 
-       if (info->flags & OVS_CT_F_COMMIT)
+       if (info->commit)
                err = ovs_ct_commit(net, key, info, skb);
        else
                err = ovs_ct_lookup(net, key, info, skb);
@@ -506,9 +506,9 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
                if (err)
                        goto err;
        }
-       if (label_nonzero(&info->label.mask))
-               err = ovs_ct_set_label(skb, key, &info->label.value,
-                                      &info->label.mask);
+       if (labels_nonzero(&info->labels.mask))
+               err = ovs_ct_set_labels(skb, key, &info->labels.value,
+                                       &info->labels.mask);
 err:
        skb_push(skb, nh_ofs);
        return err;
@@ -539,14 +539,13 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
 }
 
 static const struct ovs_ct_len_tbl ovs_ct_attr_lens[OVS_CT_ATTR_MAX + 1] = {
-       [OVS_CT_ATTR_FLAGS]     = { .minlen = sizeof(u32),
-                                   .maxlen = sizeof(u32) },
+       [OVS_CT_ATTR_COMMIT]    = { .minlen = 0, .maxlen = 0 },
        [OVS_CT_ATTR_ZONE]      = { .minlen = sizeof(u16),
                                    .maxlen = sizeof(u16) },
        [OVS_CT_ATTR_MARK]      = { .minlen = sizeof(struct md_mark),
                                    .maxlen = sizeof(struct md_mark) },
-       [OVS_CT_ATTR_LABEL]     = { .minlen = sizeof(struct md_label),
-                                   .maxlen = sizeof(struct md_label) },
+       [OVS_CT_ATTR_LABELS]    = { .minlen = sizeof(struct md_labels),
+                                   .maxlen = sizeof(struct md_labels) },
        [OVS_CT_ATTR_HELPER]    = { .minlen = 1,
                                    .maxlen = NF_CT_HELPER_NAME_LEN }
 };
@@ -576,8 +575,8 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                }
 
                switch (type) {
-               case OVS_CT_ATTR_FLAGS:
-                       info->flags = nla_get_u32(a);
+               case OVS_CT_ATTR_COMMIT:
+                       info->commit = true;
                        break;
 #ifdef CONFIG_NF_CONNTRACK_ZONES
                case OVS_CT_ATTR_ZONE:
@@ -593,10 +592,10 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                }
 #endif
 #ifdef CONFIG_NF_CONNTRACK_LABELS
-               case OVS_CT_ATTR_LABEL: {
-                       struct md_label *label = nla_data(a);
+               case OVS_CT_ATTR_LABELS: {
+                       struct md_labels *labels = nla_data(a);
 
-                       info->label = *label;
+                       info->labels = *labels;
                        break;
                }
 #endif
@@ -633,7 +632,7 @@ bool ovs_ct_verify(struct net *net, enum ovs_key_attr attr)
            attr == OVS_KEY_ATTR_CT_MARK)
                return true;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           attr == OVS_KEY_ATTR_CT_LABEL) {
+           attr == OVS_KEY_ATTR_CT_LABELS) {
                struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
 
                return ovs_net->xt_label;
@@ -701,7 +700,7 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
        if (!start)
                return -EMSGSIZE;
 
-       if (nla_put_u32(skb, OVS_CT_ATTR_FLAGS, ct_info->flags))
+       if (ct_info->commit && nla_put_flag(skb, OVS_CT_ATTR_COMMIT))
                return -EMSGSIZE;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
            nla_put_u16(skb, OVS_CT_ATTR_ZONE, ct_info->zone.id))
@@ -711,8 +710,8 @@ int ovs_ct_action_to_attr(const struct ovs_conntrack_info *ct_info,
                    &ct_info->mark))
                return -EMSGSIZE;
        if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
-           nla_put(skb, OVS_CT_ATTR_LABEL, sizeof(ct_info->label),
-                   &ct_info->label))
+           nla_put(skb, OVS_CT_ATTR_LABELS, sizeof(ct_info->labels),
+                   &ct_info->labels))
                return -EMSGSIZE;
        if (ct_info->helper) {
                if (nla_put_string(skb, OVS_CT_ATTR_HELPER,
@@ -737,7 +736,7 @@ void ovs_ct_free_action(const struct nlattr *a)
 
 void ovs_ct_init(struct net *net)
 {
-       unsigned int n_bits = sizeof(struct ovs_key_ct_label) * BITS_PER_BYTE;
+       unsigned int n_bits = sizeof(struct ovs_key_ct_labels) * BITS_PER_BYTE;
        struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
 
        if (nf_connlabels_get(net, n_bits)) {
index 43f5dd7a55774414aeb7aad8c0560db3e0596035..da8714942c95f73803aa48a157484e898651bc8f 100644 (file)
@@ -34,6 +34,13 @@ int ovs_ct_execute(struct net *, struct sk_buff *, struct sw_flow_key *,
 void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key);
 int ovs_ct_put_key(const struct sw_flow_key *key, struct sk_buff *skb);
 void ovs_ct_free_action(const struct nlattr *a);
+
+static inline bool ovs_ct_state_supported(u32 state)
+{
+       return !(state & ~(OVS_CS_F_NEW | OVS_CS_F_ESTABLISHED |
+                        OVS_CS_F_RELATED | OVS_CS_F_REPLY_DIR |
+                        OVS_CS_F_INVALID | OVS_CS_F_TRACKED));
+}
 #else
 #include <linux/errno.h>
 
@@ -46,6 +53,11 @@ static inline bool ovs_ct_verify(struct net *net, int attr)
        return false;
 }
 
+static inline bool ovs_ct_state_supported(u32 state)
+{
+       return false;
+}
+
 static inline int ovs_ct_copy_action(struct net *net, const struct nlattr *nla,
                                     const struct sw_flow_key *key,
                                     struct sw_flow_actions **acts, bool log)
@@ -72,7 +84,7 @@ static inline void ovs_ct_fill_key(const struct sk_buff *skb,
        key->ct.state = 0;
        key->ct.zone = 0;
        key->ct.mark = 0;
-       memset(&key->ct.label, 0, sizeof(key->ct.label));
+       memset(&key->ct.labels, 0, sizeof(key->ct.labels));
 }
 
 static inline int ovs_ct_put_key(const struct sw_flow_key *key,
index fe527d2dd4b7ae9d6b31a7d9d92586d1cd276c26..8cfa15a08668804a2a74c0047662694f23acbb80 100644 (file)
@@ -116,7 +116,7 @@ struct sw_flow_key {
                u16 zone;
                u32 mark;
                u8 state;
-               struct ovs_key_ct_label label;
+               struct ovs_key_ct_labels labels;
        } ct;
 
 } __aligned(BITS_PER_LONG/8); /* Ensure that we can do comparisons as longs. */
index 5c030a4d73382f6123345f4a6b608ea1b1684ae0..171a691f1c3218ed1a63ac9151c95475ef7fcade 100644 (file)
@@ -291,10 +291,10 @@ size_t ovs_key_attr_size(void)
                + nla_total_size(4)   /* OVS_KEY_ATTR_SKB_MARK */
                + nla_total_size(4)   /* OVS_KEY_ATTR_DP_HASH */
                + nla_total_size(4)   /* OVS_KEY_ATTR_RECIRC_ID */
-               + nla_total_size(1)   /* OVS_KEY_ATTR_CT_STATE */
+               + nla_total_size(4)   /* OVS_KEY_ATTR_CT_STATE */
                + nla_total_size(2)   /* OVS_KEY_ATTR_CT_ZONE */
                + nla_total_size(4)   /* OVS_KEY_ATTR_CT_MARK */
-               + nla_total_size(16)  /* OVS_KEY_ATTR_CT_LABEL */
+               + nla_total_size(16)  /* OVS_KEY_ATTR_CT_LABELS */
                + nla_total_size(12)  /* OVS_KEY_ATTR_ETHERNET */
                + nla_total_size(2)   /* OVS_KEY_ATTR_ETHERTYPE */
                + nla_total_size(4)   /* OVS_KEY_ATTR_VLAN */
@@ -349,10 +349,10 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
        [OVS_KEY_ATTR_TUNNEL]    = { .len = OVS_ATTR_NESTED,
                                     .next = ovs_tunnel_key_lens, },
        [OVS_KEY_ATTR_MPLS]      = { .len = sizeof(struct ovs_key_mpls) },
-       [OVS_KEY_ATTR_CT_STATE]  = { .len = sizeof(u8) },
+       [OVS_KEY_ATTR_CT_STATE]  = { .len = sizeof(u32) },
        [OVS_KEY_ATTR_CT_ZONE]   = { .len = sizeof(u16) },
        [OVS_KEY_ATTR_CT_MARK]   = { .len = sizeof(u32) },
-       [OVS_KEY_ATTR_CT_LABEL]  = { .len = sizeof(struct ovs_key_ct_label) },
+       [OVS_KEY_ATTR_CT_LABELS] = { .len = sizeof(struct ovs_key_ct_labels) },
 };
 
 static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -814,7 +814,13 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 
        if (*attrs & (1 << OVS_KEY_ATTR_CT_STATE) &&
            ovs_ct_verify(net, OVS_KEY_ATTR_CT_STATE)) {
-               u8 ct_state = nla_get_u8(a[OVS_KEY_ATTR_CT_STATE]);
+               u32 ct_state = nla_get_u32(a[OVS_KEY_ATTR_CT_STATE]);
+
+               if (!is_mask && !ovs_ct_state_supported(ct_state)) {
+                       OVS_NLERR(log, "ct_state flags %08x unsupported",
+                                 ct_state);
+                       return -EINVAL;
+               }
 
                SW_FLOW_KEY_PUT(match, ct.state, ct_state, is_mask);
                *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE);
@@ -833,14 +839,14 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
                SW_FLOW_KEY_PUT(match, ct.mark, mark, is_mask);
                *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_MARK);
        }
-       if (*attrs & (1 << OVS_KEY_ATTR_CT_LABEL) &&
-           ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABEL)) {
-               const struct ovs_key_ct_label *cl;
+       if (*attrs & (1 << OVS_KEY_ATTR_CT_LABELS) &&
+           ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABELS)) {
+               const struct ovs_key_ct_labels *cl;
 
-               cl = nla_data(a[OVS_KEY_ATTR_CT_LABEL]);
-               SW_FLOW_KEY_MEMCPY(match, ct.label, cl->ct_label,
+               cl = nla_data(a[OVS_KEY_ATTR_CT_LABELS]);
+               SW_FLOW_KEY_MEMCPY(match, ct.labels, cl->ct_labels,
                                   sizeof(*cl), is_mask);
-               *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABEL);
+               *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABELS);
        }
        return 0;
 }
@@ -1973,7 +1979,7 @@ static int validate_set(const struct nlattr *a,
        case OVS_KEY_ATTR_PRIORITY:
        case OVS_KEY_ATTR_SKB_MARK:
        case OVS_KEY_ATTR_CT_MARK:
-       case OVS_KEY_ATTR_CT_LABEL:
+       case OVS_KEY_ATTR_CT_LABELS:
        case OVS_KEY_ATTR_ETHERNET:
                break;
 
index f2ea83ba47631d4f650aa3dcf2f9c66cf4fd1c6f..c7f74aab34b9ef7d2befcd571d44290b76fbfbc1 100644 (file)
@@ -93,7 +93,8 @@ struct sw_flow *ovs_flow_alloc(void)
 
        /* Initialize the default stat node. */
        stats = kmem_cache_alloc_node(flow_stats_cache,
-                                     GFP_KERNEL | __GFP_ZERO, 0);
+                                     GFP_KERNEL | __GFP_ZERO,
+                                     node_online(0) ? 0 : NUMA_NO_NODE);
        if (!stats)
                goto err;
 
index dc81dc619aa2344a5c7912def9d6852fcd37ebda..12a36ac21edaaeddf50442408a1ea27aca975fa0 100644 (file)
@@ -280,35 +280,19 @@ void ovs_vport_del(struct vport *vport)
  */
 void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
 {
-       struct net_device *dev = vport->dev;
-       int i;
-
-       memset(stats, 0, sizeof(*stats));
-       stats->rx_errors  = dev->stats.rx_errors;
-       stats->tx_errors  = dev->stats.tx_errors;
-       stats->tx_dropped = dev->stats.tx_dropped;
-       stats->rx_dropped = dev->stats.rx_dropped;
-
-       stats->rx_dropped += atomic_long_read(&dev->rx_dropped);
-       stats->tx_dropped += atomic_long_read(&dev->tx_dropped);
-
-       for_each_possible_cpu(i) {
-               const struct pcpu_sw_netstats *percpu_stats;
-               struct pcpu_sw_netstats local_stats;
-               unsigned int start;
-
-               percpu_stats = per_cpu_ptr(dev->tstats, i);
-
-               do {
-                       start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
-                       local_stats = *percpu_stats;
-               } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
-
-               stats->rx_bytes         += local_stats.rx_bytes;
-               stats->rx_packets       += local_stats.rx_packets;
-               stats->tx_bytes         += local_stats.tx_bytes;
-               stats->tx_packets       += local_stats.tx_packets;
-       }
+       const struct rtnl_link_stats64 *dev_stats;
+       struct rtnl_link_stats64 temp;
+
+       dev_stats = dev_get_stats(vport->dev, &temp);
+       stats->rx_errors  = dev_stats->rx_errors;
+       stats->tx_errors  = dev_stats->tx_errors;
+       stats->tx_dropped = dev_stats->tx_dropped;
+       stats->rx_dropped = dev_stats->rx_dropped;
+
+       stats->rx_bytes   = dev_stats->rx_bytes;
+       stats->rx_packets = dev_stats->rx_packets;
+       stats->tx_bytes   = dev_stats->tx_bytes;
+       stats->tx_packets = dev_stats->tx_packets;
 }
 
 /**
@@ -460,6 +444,15 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
 
        OVS_CB(skb)->input_vport = vport;
        OVS_CB(skb)->mru = 0;
+       if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
+               u32 mark;
+
+               mark = skb->mark;
+               skb_scrub_packet(skb, true);
+               skb->mark = mark;
+               tun_info = NULL;
+       }
+
        /* Extract flow from 'skb' into 'key'. */
        error = ovs_flow_key_extract(tun_info, skb, &key);
        if (unlikely(error)) {
index 2d1be4a760fdc4361f23d0aa93a861298eaafe45..32fcdecdb9e2074bad6f3e3002738e9c289317c3 100644 (file)
 
 #define MIRRED_TAB_MASK     7
 static LIST_HEAD(mirred_list);
+static DEFINE_SPINLOCK(mirred_list_lock);
 
 static void tcf_mirred_release(struct tc_action *a, int bind)
 {
        struct tcf_mirred *m = to_mirred(a);
        struct net_device *dev = rcu_dereference_protected(m->tcfm_dev, 1);
 
+       /* We could be called either in a RCU callback or with RTNL lock held. */
+       spin_lock_bh(&mirred_list_lock);
        list_del(&m->tcfm_list);
+       spin_unlock_bh(&mirred_list_lock);
        if (dev)
                dev_put(dev);
 }
@@ -103,10 +107,10 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        } else {
                if (bind)
                        return 0;
-               if (!ovr) {
-                       tcf_hash_release(a, bind);
+
+               tcf_hash_release(a, bind);
+               if (!ovr)
                        return -EEXIST;
-               }
        }
        m = to_mirred(a);
 
@@ -123,7 +127,9 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        }
 
        if (ret == ACT_P_CREATED) {
+               spin_lock_bh(&mirred_list_lock);
                list_add(&m->tcfm_list, &mirred_list);
+               spin_unlock_bh(&mirred_list_lock);
                tcf_hash_insert(a);
        }
 
@@ -173,6 +179,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
 
        skb2->skb_iif = skb->dev->ifindex;
        skb2->dev = dev;
+       skb_sender_cpu_clear(skb2);
        err = dev_queue_xmit(skb2);
 
        if (err) {
@@ -221,7 +228,8 @@ static int mirred_device_event(struct notifier_block *unused,
        struct tcf_mirred *m;
 
        ASSERT_RTNL();
-       if (event == NETDEV_UNREGISTER)
+       if (event == NETDEV_UNREGISTER) {
+               spin_lock_bh(&mirred_list_lock);
                list_for_each_entry(m, &mirred_list, tcfm_list) {
                        if (rcu_access_pointer(m->tcfm_dev) == dev) {
                                dev_put(dev);
@@ -231,6 +239,8 @@ static int mirred_device_event(struct notifier_block *unused,
                                RCU_INIT_POINTER(m->tcfm_dev, NULL);
                        }
                }
+               spin_unlock_bh(&mirred_list_lock);
+       }
 
        return NOTIFY_DONE;
 }
index 9d15cb6b8cb1f5e8424e96f6245e9dd206d92405..86b04e31e60b76027214b85ee0c4c0e0de1b04c4 100644 (file)
@@ -368,6 +368,15 @@ static unsigned int hhf_drop(struct Qdisc *sch)
        return bucket - q->buckets;
 }
 
+static unsigned int hhf_qdisc_drop(struct Qdisc *sch)
+{
+       unsigned int prev_backlog;
+
+       prev_backlog = sch->qstats.backlog;
+       hhf_drop(sch);
+       return prev_backlog - sch->qstats.backlog;
+}
+
 static int hhf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct hhf_sched_data *q = qdisc_priv(sch);
@@ -696,7 +705,7 @@ static struct Qdisc_ops hhf_qdisc_ops __read_mostly = {
        .enqueue        =       hhf_enqueue,
        .dequeue        =       hhf_dequeue,
        .peek           =       qdisc_peek_dequeued,
-       .drop           =       hhf_drop,
+       .drop           =       hhf_qdisc_drop,
        .init           =       hhf_init,
        .reset          =       hhf_reset,
        .destroy        =       hhf_destroy,
index fda38f830a10869713177220f8d2066c6076da0c..77f5d17e261230a6db4f261445311eafb37c7b06 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
 #include <net/ip_fib.h>
 #include <net/switchdev.h>
 
@@ -634,6 +635,8 @@ static int switchdev_port_br_afspec(struct net_device *dev,
                if (nla_len(attr) != sizeof(struct bridge_vlan_info))
                        return -EINVAL;
                vinfo = nla_data(attr);
+               if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
+                       return -EINVAL;
                vlan->flags = vinfo->flags;
                if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
                        if (vlan->vid_begin)
index a82c5848d4bc22129bd1e6ba7f677795febdc9e9..5351a3f97e8ecf17e545459344a8b315f522045a 100644 (file)
@@ -357,7 +357,7 @@ static inline u32 msg_importance(struct tipc_msg *m)
        if (likely((usr <= TIPC_CRITICAL_IMPORTANCE) && !msg_errcode(m)))
                return usr;
        if ((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER))
-               return msg_bits(m, 5, 13, 0x7);
+               return msg_bits(m, 9, 0, 0x7);
        return TIPC_SYSTEM_IMPORTANCE;
 }
 
@@ -366,7 +366,7 @@ static inline void msg_set_importance(struct tipc_msg *m, u32 i)
        int usr = msg_user(m);
 
        if (likely((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER)))
-               msg_set_bits(m, 5, 13, 0x7, i);
+               msg_set_bits(m, 9, 0, 0x7, i);
        else if (i < TIPC_SYSTEM_IMPORTANCE)
                msg_set_user(m, i);
        else
index 703875fd6cde204ddeaf630b9a6bd11daec6dbfa..2c32a83037a3614ef09fb4b29c8f3337dcdf0f45 100644 (file)
@@ -1116,7 +1116,7 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
        }
 
        /* Ignore duplicate packets */
-       if (less(oseqno, rcv_nxt))
+       if ((usr != LINK_PROTOCOL) && less(oseqno, rcv_nxt))
                return true;
 
        /* Initiate or update failover mode if applicable */
@@ -1146,8 +1146,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
        if (!pl || !tipc_link_is_up(pl))
                return true;
 
-       /* Initiate or update synch mode if applicable */
-       if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG)) {
+       /* Initiate synch mode if applicable */
+       if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) {
                syncpt = iseqno + exp_pkts - 1;
                if (!tipc_link_is_up(l)) {
                        tipc_link_fsm_evt(l, LINK_ESTABLISH_EVT);
index ef31b40ad55000a5fd029d7479b546483cc782b3..94f658235fb49a0c644a84867302cc00a75243d5 100644 (file)
@@ -2064,6 +2064,11 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state)
                goto out;
        }
 
+       if (flags & MSG_PEEK)
+               skip = sk_peek_offset(sk, flags);
+       else
+               skip = 0;
+
        do {
                int chunk;
                struct sk_buff *skb, *last;
@@ -2112,7 +2117,6 @@ unlock:
                        break;
                }
 
-               skip = sk_peek_offset(sk, flags);
                while (skip >= unix_skb_len(skb)) {
                        skip -= unix_skb_len(skb);
                        last = skb;
@@ -2179,14 +2183,12 @@ unlock:
                        if (UNIXCB(skb).fp)
                                scm.fp = scm_fp_dup(UNIXCB(skb).fp);
 
-                       if (skip) {
-                               sk_peek_offset_fwd(sk, chunk);
-                               skip -= chunk;
-                       }
+                       sk_peek_offset_fwd(sk, chunk);
 
                        if (UNIXCB(skb).fp)
                                break;
 
+                       skip = 0;
                        last = skb;
                        last_len = skb->len;
                        unix_state_lock(sk);