1
0
Fork 0

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

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
  ...
hifive-unleashed-5.1
Linus Torvalds 2015-10-19 09:55:40 -07:00
commit 1099f86044
83 changed files with 666 additions and 343 deletions

View 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

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

View 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,},

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

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

View 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);
}

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

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

View 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 {

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

View 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);
}
}

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

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

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

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

View 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

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

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

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

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

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

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

View 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

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

View 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]);

View 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

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

View 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

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

View 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),

View 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]);

View 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

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

View 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),

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

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

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

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

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

View 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.
*/

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

View 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)},

View 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) },

View 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 {

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

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

View 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 {

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

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

View 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);
}

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

View 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. */

View 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) && \

View 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);
}

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

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

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

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

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

View 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);
}
}

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

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

View 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

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

View 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) {
rt6_info_init(rt);
new = &rt->dst;
memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
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 {

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

View 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]);
}

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

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

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

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

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

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

View 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. */

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

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

View 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;
const struct rtnl_link_stats64 *dev_stats;
struct rtnl_link_stats64 temp;
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;
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_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;
}
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)) {

View File

@ -31,13 +31,17 @@
#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;
}

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

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

View 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

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

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