summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-23 11:36:06 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-23 11:36:06 -0800
commit190c3ee06a0f0660839785b7ad8a830e832d9481 (patch)
treecbdfaedfb2b5eca4869d796e4a7df722114934bd
parentaf17fe7a63db7e11d65f1296f0cbf156a89a2735 (diff)
parent9c4713701c01e4cef6e2315c2818abc919ffb0de (diff)
downloadlinux-190c3ee06a0f0660839785b7ad8a830e832d9481.tar.gz
linux-190c3ee06a0f0660839785b7ad8a830e832d9481.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Some 'const'ing in qlogic networking drivers, from Bhumika Goyal. 2) Fix scheduling while atomic in l2tp network namespace exit by deferring the work to the workqueue. From Ridge Kennedy. 3) Fix use after free in dccp timewait handling, from Andrey Ryabinin. 4) mlx5e CQE compression engine not initialized properly, from Tariq Toukan. 5) Some UAPI header fixes from Dmitry V. Levin. 6) Don't overwrite module parameter value in mlx4 driver, from Majd Dibbiny. 7) Fix divide by zero in xt_hashlimit netfilter module, from Alban Browaeys. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (35 commits) bpf: Fix bpf_xdp_event_output net/mlx4_en: Use __skb_fill_page_desc() net/mlx4_core: Use cq quota in SRIOV when creating completion EQs net/mlx4_core: Fix VF overwrite of module param which disables DMFS on new probed PFs net/mlx4: Spoofcheck and zero MAC can't coexist net/mlx4: Change ENOTSUPP to EOPNOTSUPP uapi: fix linux/rds.h userspace compilation errors uapi: fix linux/seg6.h and linux/seg6_iptunnel.h userspace compilation errors lib: Remove string from parman config selection forcedeth: Remove return from a void function bpf: fix spelling mistake: "proccessed" -> "processed" uapi: fix linux/llc.h userspace compilation error uapi: fix linux/ip6_tunnel.h userspace compilation errors net/mlx5e: Fix wrong CQE decompression net/mlx5e: Update MPWQE stride size when modifying CQE compress state net/mlx5e: Fix broken CQE compression initialization net/mlx5e: Do not reduce LRO WQE size when not using build_skb net/mlx5e: Register/unregister vport representors on interface attach/detach net/mlx5e: s390 system compilation fix tcp: account for ts offset only if tsecr not zero ...
-rw-r--r--drivers/net/ethernet/ibm/emac/Kconfig1
-rw-r--r--drivers/net/ethernet/ibm/emac/core.c254
-rw-r--r--drivers/net/ethernet/ibm/emac/core.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/intf.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c40
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c1
-rw-r--r--drivers/net/ethernet/nvidia/forcedeth.c2
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c16
-rw-r--r--include/linux/mlx4/cmd.h2
-rw-r--r--include/linux/mlx4/driver.h10
-rw-r--r--include/uapi/linux/if.h4
-rw-r--r--include/uapi/linux/ip6_tunnel.h2
-rw-r--r--include/uapi/linux/llc.h1
-rw-r--r--include/uapi/linux/netfilter/nf_conntrack_common.h4
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h2
-rw-r--r--include/uapi/linux/rds.h10
-rw-r--r--include/uapi/linux/seg6.h1
-rw-r--r--include/uapi/linux/seg6_iptunnel.h2
-rw-r--r--kernel/bpf/verifier.c2
-rw-r--r--lib/Kconfig2
-rw-r--r--net/core/filter.c4
-rw-r--r--net/dccp/ipv4.c6
-rw-r--r--net/dccp/ipv6.c6
-rw-r--r--net/ipv4/tcp_ipv4.c16
-rw-r--r--net/ipv4/tcp_minisocks.c3
-rw-r--r--net/ipv6/tcp_ipv6.c16
-rw-r--r--net/l2tp/l2tp_core.c4
-rw-r--r--net/netfilter/ipset/ip_set_hash_gen.h2
-rw-r--r--net/netfilter/ipset/ip_set_list_set.c9
-rw-r--r--net/netfilter/nf_conntrack_helper.c39
-rw-r--r--net/netfilter/nf_conntrack_netlink.c43
-rw-r--r--net/netfilter/nfnetlink.c2
-rw-r--r--net/netfilter/xt_hashlimit.c25
47 files changed, 489 insertions, 133 deletions
diff --git a/drivers/net/ethernet/ibm/emac/Kconfig b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30e0615..90d49191beb3 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -2,6 +2,7 @@ config IBM_EMAC
tristate "IBM EMAC Ethernet support"
depends on PPC_DCR
select CRC32
+ select PHYLIB
help
This driver supports the IBM EMAC family of Ethernet controllers
typically found on 4xx embedded PowerPC chips, but also on the
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 6ead2335a169..275c2e2349ad 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -42,6 +42,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_net.h>
+#include <linux/of_mdio.h>
#include <linux/slab.h>
#include <asm/processor.h>
@@ -2420,6 +2421,219 @@ static int emac_read_uint_prop(struct device_node *np, const char *name,
return 0;
}
+static void emac_adjust_link(struct net_device *ndev)
+{
+ struct emac_instance *dev = netdev_priv(ndev);
+ struct phy_device *phy = dev->phy_dev;
+
+ dev->phy.autoneg = phy->autoneg;
+ dev->phy.speed = phy->speed;
+ dev->phy.duplex = phy->duplex;
+ dev->phy.pause = phy->pause;
+ dev->phy.asym_pause = phy->asym_pause;
+ dev->phy.advertising = phy->advertising;
+}
+
+static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
+{
+ int ret = emac_mdio_read(bus->priv, addr, regnum);
+ /* This is a workaround for powered down ports/phys.
+ * In the wild, this was seen on the Cisco Meraki MX60(W).
+ * This hardware disables ports as part of the handoff
+ * procedure. Accessing the ports will lead to errors
+ * (-ETIMEDOUT, -EREMOTEIO) that do more harm than good.
+ */
+ return ret < 0 ? 0xffff : ret;
+}
+
+static int emac_mii_bus_write(struct mii_bus *bus, int addr,
+ int regnum, u16 val)
+{
+ emac_mdio_write(bus->priv, addr, regnum, val);
+ return 0;
+}
+
+static int emac_mii_bus_reset(struct mii_bus *bus)
+{
+ struct emac_instance *dev = netdev_priv(bus->priv);
+
+ return emac_reset(dev);
+}
+
+static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+ struct net_device *ndev = phy->dev;
+ struct emac_instance *dev = netdev_priv(ndev);
+
+ dev->phy.autoneg = AUTONEG_ENABLE;
+ dev->phy.speed = SPEED_1000;
+ dev->phy.duplex = DUPLEX_FULL;
+ dev->phy.advertising = advertise;
+ phy->autoneg = AUTONEG_ENABLE;
+ phy->speed = dev->phy.speed;
+ phy->duplex = dev->phy.duplex;
+ phy->advertising = advertise;
+ return phy_start_aneg(dev->phy_dev);
+}
+
+static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+ struct net_device *ndev = phy->dev;
+ struct emac_instance *dev = netdev_priv(ndev);
+
+ dev->phy.autoneg = AUTONEG_DISABLE;
+ dev->phy.speed = speed;
+ dev->phy.duplex = fd;
+ phy->autoneg = AUTONEG_DISABLE;
+ phy->speed = speed;
+ phy->duplex = fd;
+ return phy_start_aneg(dev->phy_dev);
+}
+
+static int emac_mdio_poll_link(struct mii_phy *phy)
+{
+ struct net_device *ndev = phy->dev;
+ struct emac_instance *dev = netdev_priv(ndev);
+ int res;
+
+ res = phy_read_status(dev->phy_dev);
+ if (res) {
+ dev_err(&dev->ofdev->dev, "link update failed (%d).", res);
+ return ethtool_op_get_link(ndev);
+ }
+
+ return dev->phy_dev->link;
+}
+
+static int emac_mdio_read_link(struct mii_phy *phy)
+{
+ struct net_device *ndev = phy->dev;
+ struct emac_instance *dev = netdev_priv(ndev);
+ int res;
+
+ res = phy_read_status(dev->phy_dev);
+ if (res)
+ return res;
+
+ dev->phy.speed = phy->speed;
+ dev->phy.duplex = phy->duplex;
+ dev->phy.pause = phy->pause;
+ dev->phy.asym_pause = phy->asym_pause;
+ return 0;
+}
+
+static int emac_mdio_init_phy(struct mii_phy *phy)
+{
+ struct net_device *ndev = phy->dev;
+ struct emac_instance *dev = netdev_priv(ndev);
+
+ phy_start(dev->phy_dev);
+ dev->phy.autoneg = phy->autoneg;
+ dev->phy.speed = phy->speed;
+ dev->phy.duplex = phy->duplex;
+ dev->phy.advertising = phy->advertising;
+ dev->phy.pause = phy->pause;
+ dev->phy.asym_pause = phy->asym_pause;
+
+ return phy_init_hw(dev->phy_dev);
+}
+
+static const struct mii_phy_ops emac_dt_mdio_phy_ops = {
+ .init = emac_mdio_init_phy,
+ .setup_aneg = emac_mdio_setup_aneg,
+ .setup_forced = emac_mdio_setup_forced,
+ .poll_link = emac_mdio_poll_link,
+ .read_link = emac_mdio_read_link,
+};
+
+static int emac_dt_mdio_probe(struct emac_instance *dev)
+{
+ struct device_node *mii_np;
+ int res;
+
+ mii_np = of_get_child_by_name(dev->ofdev->dev.of_node, "mdio");
+ if (!mii_np) {
+ dev_err(&dev->ofdev->dev, "no mdio definition found.");
+ return -ENODEV;
+ }
+
+ if (!of_device_is_available(mii_np)) {
+ res = -ENODEV;
+ goto put_node;
+ }
+
+ dev->mii_bus = devm_mdiobus_alloc(&dev->ofdev->dev);
+ if (!dev->mii_bus) {
+ res = -ENOMEM;
+ goto put_node;
+ }
+
+ dev->mii_bus->priv = dev->ndev;
+ dev->mii_bus->parent = dev->ndev->dev.parent;
+ dev->mii_bus->name = "emac_mdio";
+ dev->mii_bus->read = &emac_mii_bus_read;
+ dev->mii_bus->write = &emac_mii_bus_write;
+ dev->mii_bus->reset = &emac_mii_bus_reset;
+ snprintf(dev->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev->ofdev->name);
+ res = of_mdiobus_register(dev->mii_bus, mii_np);
+ if (res) {
+ dev_err(&dev->ofdev->dev, "cannot register MDIO bus %s (%d)",
+ dev->mii_bus->name, res);
+ }
+
+ put_node:
+ of_node_put(mii_np);
+ return res;
+}
+
+static int emac_dt_phy_connect(struct emac_instance *dev,
+ struct device_node *phy_handle)
+{
+ int res;
+
+ dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def),
+ GFP_KERNEL);
+ if (!dev->phy.def)
+ return -ENOMEM;
+
+ dev->phy_dev = of_phy_connect(dev->ndev, phy_handle, &emac_adjust_link,
+ 0, dev->phy_mode);
+ if (!dev->phy_dev) {
+ dev_err(&dev->ofdev->dev, "failed to connect to PHY.\n");
+ return -ENODEV;
+ }
+
+ dev->phy.def->phy_id = dev->phy_dev->drv->phy_id;
+ dev->phy.def->phy_id_mask = dev->phy_dev->drv->phy_id_mask;
+ dev->phy.def->name = dev->phy_dev->drv->name;
+ dev->phy.def->ops = &emac_dt_mdio_phy_ops;
+ dev->phy.features = dev->phy_dev->supported;
+ dev->phy.address = dev->phy_dev->mdio.addr;
+ dev->phy.mode = dev->phy_dev->interface;
+ return 0;
+}
+
+static int emac_dt_phy_probe(struct emac_instance *dev)
+{
+ struct device_node *np = dev->ofdev->dev.of_node;
+ struct device_node *phy_handle;
+ int res = 0;
+
+ phy_handle = of_parse_phandle(np, "phy-handle", 0);
+
+ if (phy_handle) {
+ res = emac_dt_mdio_probe(dev);
+ if (!res) {
+ res = emac_dt_phy_connect(dev, phy_handle);
+ if (res)
+ mdiobus_unregister(dev->mii_bus);
+ }
+ }
+
+ of_node_put(phy_handle);
+ return res;
+}
+
static int emac_init_phy(struct emac_instance *dev)
{
struct device_node *np = dev->ofdev->dev.of_node;
@@ -2430,15 +2644,12 @@ static int emac_init_phy(struct emac_instance *dev)
dev->phy.dev = ndev;
dev->phy.mode = dev->phy_mode;
- /* PHY-less configuration.
- * XXX I probably should move these settings to the dev tree
- */
- if (dev->phy_address == 0xffffffff && dev->phy_map == 0xffffffff) {
+ /* PHY-less configuration. */
+ if ((dev->phy_address == 0xffffffff && dev->phy_map == 0xffffffff) ||
+ of_phy_is_fixed_link(np)) {
emac_reset(dev);
- /* PHY-less configuration.
- * XXX I probably should move these settings to the dev tree
- */
+ /* PHY-less configuration. */
dev->phy.address = -1;
dev->phy.features = SUPPORTED_MII;
if (emac_phy_supports_gige(dev->phy_mode))
@@ -2447,6 +2658,16 @@ static int emac_init_phy(struct emac_instance *dev)
dev->phy.features |= SUPPORTED_100baseT_Full;
dev->phy.pause = 1;
+ if (of_phy_is_fixed_link(np)) {
+ int res = emac_dt_mdio_probe(dev);
+
+ if (!res) {
+ res = of_phy_register_fixed_link(np);
+ if (res)
+ mdiobus_unregister(dev->mii_bus);
+ }
+ return res;
+ }
return 0;
}
@@ -2490,6 +2711,18 @@ static int emac_init_phy(struct emac_instance *dev)
emac_configure(dev);
+ if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) {
+ int res = emac_dt_phy_probe(dev);
+
+ mutex_unlock(&emac_phy_map_lock);
+ if (!res)
+ goto init_phy;
+
+ dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n",
+ res);
+ return res;
+ }
+
if (dev->phy_address != 0xffffffff)
phy_map = ~(1 << dev->phy_address);
@@ -2517,6 +2750,7 @@ static int emac_init_phy(struct emac_instance *dev)
return -ENXIO;
}
+ init_phy:
/* Init PHY */
if (dev->phy.def->ops->init)
dev->phy.def->ops->init(&dev->phy);
@@ -2988,6 +3222,12 @@ static int emac_remove(struct platform_device *ofdev)
if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII))
zmii_detach(dev->zmii_dev, dev->zmii_port);
+ if (dev->phy_dev)
+ phy_disconnect(dev->phy_dev);
+
+ if (dev->mii_bus)
+ mdiobus_unregister(dev->mii_bus);
+
busy_phy_map &= ~(1 << dev->phy.address);
DBG(dev, "busy_phy_map now %#x" NL, busy_phy_map);
diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h
index 93ae11494810..0710a6685489 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -199,6 +199,10 @@ struct emac_instance {
struct emac_instance *mdio_instance;
struct mutex mdio_lock;
+ /* Device-tree based phy configuration */
+ struct mii_bus *mii_bus;
+ struct phy_device *phy_dev;
+
/* ZMII infos if any */
u32 zmii_ph;
u32 zmii_port;
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index a49072b4fa52..e8c105164931 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -43,6 +43,7 @@
#include <linux/semaphore.h>
#include <rdma/ib_smi.h>
#include <linux/delay.h>
+#include <linux/etherdevice.h>
#include <asm/io.h>
@@ -2955,7 +2956,7 @@ static bool mlx4_valid_vf_state_change(struct mlx4_dev *dev, int port,
return false;
}
-int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
+int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_vport_state *s_info;
@@ -2964,13 +2965,22 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac)
if (!mlx4_is_master(dev))
return -EPROTONOSUPPORT;
+ if (is_multicast_ether_addr(mac))
+ return -EINVAL;
+
slave = mlx4_get_slave_indx(dev, vf);
if (slave < 0)
return -EINVAL;
port = mlx4_slaves_closest_port(dev, slave, port);
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
- s_info->mac = mac;
+
+ if (s_info->spoofchk && is_zero_ether_addr(mac)) {
+ mlx4_info(dev, "MAC invalidation is not allowed when spoofchk is on\n");
+ return -EPERM;
+ }
+
+ s_info->mac = mlx4_mac_to_u64(mac);
mlx4_info(dev, "default mac on vf %d port %d to %llX will take effect only after vf restart\n",
vf, port, s_info->mac);
return 0;
@@ -3143,6 +3153,7 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_vport_state *s_info;
int slave;
+ u8 mac[ETH_ALEN];
if ((!mlx4_is_master(dev)) ||
!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FSM))
@@ -3154,6 +3165,13 @@ int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting)
port = mlx4_slaves_closest_port(dev, slave, port);
s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
+
+ mlx4_u64_to_mac(mac, s_info->mac);
+ if (setting && !is_valid_ether_addr(mac)) {
+ mlx4_info(dev, "Illegal MAC with spoofchk\n");
+ return -EPERM;
+ }
+
s_info->spoofchk = setting;
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
index b04760a5034b..1dae8e40fb25 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
@@ -319,7 +319,7 @@ static int mlx4_en_ets_validate(struct mlx4_en_priv *priv, struct ieee_ets *ets)
default:
en_err(priv, "TC[%d]: Not supported TSA: %d\n",
i, ets->tc_tsa[i]);
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index afe4444e5434..61420473fe5f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2485,12 +2485,8 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
{
struct mlx4_en_priv *en_priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = en_priv->mdev;
- u64 mac_u64 = mlx4_mac_to_u64(mac);
- if (is_multicast_ether_addr(mac))
- return -EINVAL;
-
- return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
+ return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac);
}
static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index d85e6446f9d9..867292880c07 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -604,10 +604,10 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
dma_sync_single_for_cpu(priv->ddev, dma, frag_info->frag_size,
DMA_FROM_DEVICE);
- /* Save page reference in skb */
- __skb_frag_set_page(&skb_frags_rx[nr], frags[nr].page);
- skb_frag_size_set(&skb_frags_rx[nr], frag_info->frag_size);
- skb_frags_rx[nr].page_offset = frags[nr].page_offset;
+ __skb_fill_page_desc(skb, nr, frags[nr].page,
+ frags[nr].page_offset,
+ frag_info->frag_size);
+
skb->truesize += frag_info->frag_stride;
frags[nr].page = NULL;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 39232b6a974f..07406cf2eacd 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1249,9 +1249,8 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
mlx4_warn(dev, "Failed adding irq rmap\n");
}
#endif
- err = mlx4_create_eq(dev, dev->caps.num_cqs -
- dev->caps.reserved_cqs +
- MLX4_NUM_SPARE_EQE,
+ err = mlx4_create_eq(dev, dev->quotas.cq +
+ MLX4_NUM_SPARE_EQE,
(dev->flags & MLX4_FLAG_MSI_X) ?
i + 1 - !!(i > MLX4_EQ_ASYNC) : 0,
eq);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 3fe885ce1902..37e84a59e751 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -2436,7 +2436,7 @@ int mlx4_config_dev_retrieval(struct mlx4_dev *dev,
#define CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET 4
if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CONFIG_DEV))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
err = mlx4_CONFIG_DEV_get(dev, &config_dev);
if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx4/intf.c b/drivers/net/ethernet/mellanox/mlx4/intf.c
index 8258d08acd8c..e00f627331cb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/intf.c
+++ b/drivers/net/ethernet/mellanox/mlx4/intf.c
@@ -136,7 +136,7 @@ int mlx4_do_bond(struct mlx4_dev *dev, bool enable)
LIST_HEAD(bond_list);
if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_REMAP))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
ret = mlx4_disable_rx_port_check(dev, enable);
if (ret) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 15ef787e71ba..21377c315083 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -841,8 +841,6 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
return -EINVAL;
}
- mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz;
-
dev->caps.hca_core_clock = hca_param.hca_core_clock;
memset(&dev_cap, 0, sizeof(dev_cap));
@@ -1447,7 +1445,7 @@ int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p)
int err;
if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_REMAP))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
mutex_lock(&priv->bond_mutex);
@@ -1884,7 +1882,7 @@ int mlx4_get_internal_clock_params(struct mlx4_dev *dev,
struct mlx4_priv *priv = mlx4_priv(dev);
if (mlx4_is_slave(dev))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
if (!params)
return -EINVAL;
@@ -2384,7 +2382,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
/* Query CONFIG_DEV parameters */
err = mlx4_config_dev_retrieval(dev, &params);
- if (err && err != -ENOTSUPP) {
+ if (err && err != -EOPNOTSUPP) {
mlx4_err(dev, "Failed to query CONFIG_DEV parameters\n");
} else if (!err) {
dev->caps.rx_checksum_flags_port[1] = params.rx_csum_flags_port_1;
@@ -3503,6 +3501,8 @@ slave_start:
goto err_disable_msix;
}
+ mlx4_init_quotas(dev);
+
err = mlx4_setup_hca(dev);
if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) &&
!mlx4_is_mfunc(dev)) {
@@ -3515,7 +3515,6 @@ slave_start:
if (err)
goto err_steer;
- mlx4_init_quotas(dev);
/* When PF resources are ready arm its comm channel to enable
* getting commands
*/
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 395b5463cfd9..db65f72879e9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -823,7 +823,7 @@ int mlx4_mw_alloc(struct mlx4_dev *dev, u32 pd, enum mlx4_mw_type type,
!(dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW)) ||
(type == MLX4_MW_TYPE_2 &&
!(dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN)))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
index = mlx4_mpt_reserve(dev);
if (index == -1)
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index d1cd9c32a9ae..2d6abd4662b1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -447,7 +447,7 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
& MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB)) {
mlx4_warn(dev,
"Trying to set src check LB, but it isn't supported\n");
- err = -ENOTSUPP;
+ err = -EOPNOTSUPP;
goto out;
}
pri_addr_path_mask |=
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 6fe9f76ae656..d8d5d161b8c7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -4297,7 +4297,7 @@ int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB)) {
mlx4_warn(dev, "Src check LB for slave %d isn't supported\n",
slave);
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
/* Just change the smac for the QP */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 95ca03c0d9f5..f6a6ded204f6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -816,6 +816,7 @@ int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
u8 cq_period_mode);
+void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type);
static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
struct mlx5_wqe_ctrl_seg *ctrl, int bf_sz)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index cc80522b5854..a004a5a1a4c2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1487,6 +1487,7 @@ static int set_pflag_rx_cqe_compress(struct net_device *netdev,
mlx5e_modify_rx_cqe_compression_locked(priv, enable);
priv->params.rx_cqe_compress_def = enable;
+ mlx5e_set_rq_type_params(priv, priv->params.rq_wq_type);
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 3cce6281e075..8ef64c4db2c2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -79,9 +79,10 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
MLX5_CAP_ETH(mdev, reg_umr_sq);
}
-static void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type)
+void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type)
{
priv->params.rq_wq_type = rq_type;
+ priv->params.lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
switch (priv->params.rq_wq_type) {
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
priv->params.log_rq_size = is_kdump_kernel() ?
@@ -98,6 +99,10 @@ static void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type)
priv->params.log_rq_size = is_kdump_kernel() ?
MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE :
MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
+
+ /* Extra room needed for build_skb */
+ priv->params.lro_wqe_sz -= MLX5_RX_HEADROOM +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
}
priv->params.min_rx_wqes = mlx5_min_rx_wqes(priv->params.rq_wq_type,
BIT(priv->params.log_rq_size));
@@ -3521,6 +3526,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
cqe_compress_heuristic(link_speed, pci_bw);
}
+ MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS,
+ priv->params.rx_cqe_compress_def);
+
mlx5e_set_rq_priv_params(priv);
if (priv->params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
priv->params.lro_en = true;
@@ -3547,16 +3555,9 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
mlx5e_build_default_indir_rqt(mdev, priv->params.indirection_rqt,
MLX5E_INDIR_RQT_SIZE, profile->max_nch(mdev));
- priv->params.lro_wqe_sz =
- MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ -
- /* Extra room needed for build_skb */
- MLX5_RX_HEADROOM -
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-
/* Initialize pflags */
MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_BASED_MODER,
priv->params.rx_cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
- MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, priv->params.rx_cqe_compress_def);
mutex_init(&priv->state_lock);
@@ -3970,6 +3971,19 @@ static void mlx5e_register_vport_rep(struct mlx5_core_dev *mdev)
}
}
+static void mlx5e_unregister_vport_rep(struct mlx5_core_dev *mdev)
+{
+ struct mlx5_eswitch *esw = mdev->priv.eswitch;
+ int total_vfs = MLX5_TOTAL_VPORTS(mdev);
+ int vport;
+
+ if (!MLX5_CAP_GEN(mdev, vport_group_manager))
+ return;
+
+ for (vport = 1; vport < total_vfs; vport++)
+ mlx5_eswitch_unregister_vport_rep(esw, vport);
+}
+
void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4016,6 +4030,7 @@ static int mlx5e_attach(struct mlx5_core_dev *mdev, void *vpriv)
return err;
}
+ mlx5e_register_vport_rep(mdev);
return 0;
}
@@ -4027,6 +4042,7 @@ static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv)
if (!netif_device_present(netdev))
return;
+ mlx5e_unregister_vport_rep(mdev);
mlx5e_detach_netdev(mdev, netdev);
mlx5e_destroy_mdev_resources(mdev);
}
@@ -4045,8 +4061,6 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
if (err)
return NULL;
- mlx5e_register_vport_rep(mdev);
-
if (MLX5_CAP_GEN(mdev, vport_group_manager))
ppriv = &esw->offloads.vport_reps[0];
@@ -4098,13 +4112,7 @@ void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv)
static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
{
- struct mlx5_eswitch *esw = mdev->priv.eswitch;
- int total_vfs = MLX5_TOTAL_VPORTS(mdev);
struct mlx5e_priv *priv = vpriv;
- int vport;
-
- for (vport = 1; vport < total_vfs; vport++)
- mlx5_eswitch_unregister_vport_rep(esw, vport);
unregister_netdev(priv->netdev);
mlx5e_detach(mdev, vpriv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index b039b87742a6..3d371688fbbb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -30,6 +30,7 @@
* SOFTWARE.
*/
+#include <linux/prefetch.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
@@ -93,19 +94,18 @@ static inline void mlx5e_cqes_update_owner(struct mlx5e_cq *cq, u32 cqcc, int n)
static inline void mlx5e_decompress_cqe(struct mlx5e_rq *rq,
struct mlx5e_cq *cq, u32 cqcc)
{
- u16 wqe_cnt_step;
-
cq->title.byte_cnt = cq->mini_arr[cq->mini_arr_idx].byte_cnt;
cq->title.check_sum = cq->mini_arr[cq->mini_arr_idx].checksum;
cq->title.op_own &= 0xf0;
cq->title.op_own |= 0x01 & (cqcc >> cq->wq.log_sz);
cq->title.wqe_counter = cpu_to_be16(cq->decmprs_wqe_counter);
- wqe_cnt_step =
- rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ?
- mpwrq_get_cqe_consumed_strides(&cq->title) : 1;
- cq->decmprs_wqe_counter =
- (cq->decmprs_wqe_counter + wqe_cnt_step) & rq->wq.sz_m1;
+ if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
+ cq->decmprs_wqe_counter +=
+ mpwrq_get_cqe_consumed_strides(&cq->title);
+ else
+ cq->decmprs_wqe_counter =
+ (cq->decmprs_wqe_counter + 1) & rq->wq.sz_m1;
}
static inline void mlx5e_decompress_cqe_no_hash(struct mlx5e_rq *rq,
@@ -171,6 +171,7 @@ void mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool val)
mlx5e_close_locked(priv->netdev);
MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, val);
+ mlx5e_set_rq_type_params(priv, priv->params.rq_wq_type);
if (was_opened)
mlx5e_open_locked(priv->netdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
index 65442c36a6e1..31e3cb7ee5fe 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
@@ -30,6 +30,7 @@
* SOFTWARE.
*/
+#include <linux/prefetch.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <net/udp.h>
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 92367a06491a..978d32944c80 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -3272,8 +3272,6 @@ static void nv_force_linkspeed(struct net_device *dev, int speed, int duplex)
pci_push(base);
writel(np->linkspeed, base + NvRegLinkSpeed);
pci_push(base);
-
- return;
}
/**
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 3b5d7cfa2321..827de838389f 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -3005,14 +3005,14 @@ static ssize_t netxen_sysfs_write_mem(struct file *filp, struct kobject *kobj,
}
-static struct bin_attribute bin_attr_crb = {
+static const struct bin_attribute bin_attr_crb = {
.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = netxen_sysfs_read_crb,
.write = netxen_sysfs_write_crb,
};
-static struct bin_attribute bin_attr_mem = {
+static const struct bin_attribute bin_attr_mem = {
.attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = netxen_sysfs_read_mem,
@@ -3141,7 +3141,7 @@ out:
}
-static struct bin_attribute bin_attr_dimm = {
+static const struct bin_attribute bin_attr_dimm = {
.attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) },
.size = sizeof(struct netxen_dimm_cfg),
.read = netxen_sysfs_read_dimm,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index ccbb04503b27..73027a6c06c7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -1192,56 +1192,56 @@ static struct device_attribute dev_attr_beacon = {
.store = qlcnic_store_beacon,
};
-static struct bin_attribute bin_attr_crb = {
+static const struct bin_attribute bin_attr_crb = {
.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_read_crb,
.write = qlcnic_sysfs_write_crb,
};
-static struct bin_attribute bin_attr_mem = {
+static const struct bin_attribute bin_attr_mem = {
.attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_read_mem,
.write = qlcnic_sysfs_write_mem,
};
-static struct bin_attribute bin_attr_npar_config = {
+static const struct bin_attribute bin_attr_npar_config = {
.attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_read_npar_config,
.write = qlcnic_sysfs_write_npar_config,
};
-static struct bin_attribute bin_attr_pci_config = {
+static const struct bin_attribute bin_attr_pci_config = {
.attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_read_pci_config,
.write = NULL,
};
-static struct bin_attribute bin_attr_port_stats = {
+static const struct bin_attribute bin_attr_port_stats = {
.attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_get_port_stats,
.write = qlcnic_sysfs_clear_port_stats,
};
-static struct bin_attribute bin_attr_esw_stats = {
+static const struct bin_attribute bin_attr_esw_stats = {
.attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_get_esw_stats,
.write = qlcnic_sysfs_clear_esw_stats,
};
-static struct bin_attribute bin_attr_esw_config = {
+static const struct bin_attribute bin_attr_esw_config = {
.attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_read_esw_config,
.write = qlcnic_sysfs_write_esw_config,
};
-static struct bin_attribute bin_attr_pm_config = {
+static const struct bin_attribute bin_attr_pm_config = {
.attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)},
.size = 0,
.read = qlcnic_sysfs_read_pm_config,
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 1f3568694a57..7b74afcbbab2 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -308,7 +308,7 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
struct ifla_vf_stats *vf_stats);
u32 mlx4_comm_get_version(void);
-int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
+int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u8 *mac);
int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan,
u8 qos, __be16 proto);
int mlx4_set_vf_rate(struct mlx4_dev *dev, int port, int vf, int min_tx_rate,
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h
index bd0e7075ea6d..e965e5090d96 100644
--- a/include/linux/mlx4/driver.h
+++ b/include/linux/mlx4/driver.h
@@ -104,4 +104,14 @@ static inline u64 mlx4_mac_to_u64(u8 *addr)
return mac;
}
+static inline void mlx4_u64_to_mac(u8 *addr, u64 mac)
+{
+ int i;
+
+ for (i = ETH_ALEN; i > 0; i--) {
+ addr[i - 1] = mac && 0xFF;
+ mac >>= 8;
+ }
+}
+
#endif /* MLX4_DRIVER_H */
diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
index 1158a043342a..259617a551f2 100644
--- a/include/uapi/linux/if.h
+++ b/include/uapi/linux/if.h
@@ -24,6 +24,10 @@
#include <linux/socket.h> /* for "struct sockaddr" et al */
#include <linux/compiler.h> /* for "__user" et al */
+#ifndef __KERNEL__
+#include <sys/socket.h> /* for struct sockaddr. */
+#endif
+
#if __UAPI_DEF_IF_IFNAMSIZ
#define IFNAMSIZ 16
#endif /* __UAPI_DEF_IF_IFNAMSIZ */
diff --git a/include/uapi/linux/ip6_tunnel.h b/include/uapi/linux/ip6_tunnel.h
index 48af63c9a48d..425926c467d7 100644
--- a/include/uapi/linux/ip6_tunnel.h
+++ b/include/uapi/linux/ip6_tunnel.h
@@ -2,6 +2,8 @@
#define _IP6_TUNNEL_H
#include <linux/types.h>
+#include <linux/if.h> /* For IFNAMSIZ. */
+#include <linux/in6.h> /* For struct in6_addr. */
#define IPV6_TLV_TNL_ENCAP_LIMIT 4
#define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4
diff --git a/include/uapi/linux/llc.h b/include/uapi/linux/llc.h
index 9c987a402473..a6c17f66ee94 100644
--- a/include/uapi/linux/llc.h
+++ b/include/uapi/linux/llc.h
@@ -14,6 +14,7 @@
#define _UAPI__LINUX_LLC_H
#include <linux/socket.h>
+#include <linux/if.h> /* For IFHWADDRLEN. */
#define __LLC_SOCK_SIZE__ 16 /* sizeof(sockaddr_llc), word align. */
struct sockaddr_llc {
diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h
index 6d074d14ee27..6a8e33dd4ecb 100644
--- a/include/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/include/uapi/linux/netfilter/nf_conntrack_common.h
@@ -82,6 +82,10 @@ enum ip_conntrack_status {
IPS_DYING_BIT = 9,
IPS_DYING = (1 << IPS_DYING_BIT),
+ /* Bits that cannot be altered from userland. */
+ IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK |
+ IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING),
+
/* Connection has fixed timeout. */
IPS_FIXED_TIMEOUT_BIT = 10,
IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index ae30841ff94e..d42f0396fe30 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -36,7 +36,7 @@ enum nfqnl_vlan_attr {
NFQA_VLAN_TCI, /* __be16 skb htons(vlan_tci) */
__NFQA_VLAN_MAX,
};
-#define NFQA_VLAN_MAX (__NFQA_VLAN_MAX + 1)
+#define NFQA_VLAN_MAX (__NFQA_VLAN_MAX - 1)
enum nfqnl_attr_type {
NFQA_UNSPEC,
diff --git a/include/uapi/linux/rds.h b/include/uapi/linux/rds.h
index 47c03ca5c404..198892b95f09 100644
--- a/include/uapi/linux/rds.h
+++ b/include/uapi/linux/rds.h
@@ -195,14 +195,14 @@ enum rds_message_rxpath_latency {
};
struct rds_rx_trace_so {
- u8 rx_traces;
- u8 rx_trace_pos[RDS_MSG_RX_DGRAM_TRACE_MAX];
+ __u8 rx_traces;
+ __u8 rx_trace_pos[RDS_MSG_RX_DGRAM_TRACE_MAX];
};
struct rds_cmsg_rx_trace {
- u8 rx_traces;
- u8 rx_trace_pos[RDS_MSG_RX_DGRAM_TRACE_MAX];
- u64 rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX];
+ __u8 rx_traces;
+ __u8 rx_trace_pos[RDS_MSG_RX_DGRAM_TRACE_MAX];
+ __u64 rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX];
};
/*
diff --git a/include/uapi/linux/seg6.h b/include/uapi/linux/seg6.h
index 61df8d392f41..7278511d339e 100644
--- a/include/uapi/linux/seg6.h
+++ b/include/uapi/linux/seg6.h
@@ -15,6 +15,7 @@
#define _UAPI_LINUX_SEG6_H
#include <linux/types.h>
+#include <linux/in6.h> /* For struct in6_addr. */
/*
* SRH
diff --git a/include/uapi/linux/seg6_iptunnel.h b/include/uapi/linux/seg6_iptunnel.h
index 7a7183d4062a..b6e5a0a1afd7 100644
--- a/include/uapi/linux/seg6_iptunnel.h
+++ b/include/uapi/linux/seg6_iptunnel.h
@@ -14,6 +14,8 @@
#ifndef _UAPI_LINUX_SEG6_IPTUNNEL_H
#define _UAPI_LINUX_SEG6_IPTUNNEL_H
+#include <linux/seg6.h> /* For struct ipv6_sr_hdr. */
+
enum {
SEG6_IPTUNNEL_UNSPEC,
SEG6_IPTUNNEL_SRH,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d2bded2b250c..3fc6e39b223e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2776,7 +2776,7 @@ static int do_check(struct bpf_verifier_env *env)
class = BPF_CLASS(insn->code);
if (++insn_processed > BPF_COMPLEXITY_LIMIT_INSNS) {
- verbose("BPF program is too large. Proccessed %d insn\n",
+ verbose("BPF program is too large. Processed %d insn\n",
insn_processed);
return -E2BIG;
}
diff --git a/lib/Kconfig b/lib/Kconfig
index 5d644f180fe5..f3552604e47a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -551,6 +551,6 @@ config SBITMAP
bool
config PARMAN
- tristate "parman"
+ tristate
endmenu
diff --git a/net/core/filter.c b/net/core/filter.c
index e466e0040137..ebaeaf2e46e8 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2584,8 +2584,8 @@ BPF_CALL_5(bpf_xdp_event_output, struct xdp_buff *, xdp, struct bpf_map *, map,
if (unlikely(xdp_size > (unsigned long)(xdp->data_end - xdp->data)))
return -EFAULT;
- return bpf_event_output(map, flags, meta, meta_size, xdp, xdp_size,
- bpf_xdp_copy);
+ return bpf_event_output(map, flags, meta, meta_size, xdp->data,
+ xdp_size, bpf_xdp_copy);
}
static const struct bpf_func_proto bpf_xdp_event_output_proto = {
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b043ec833785..409d0cfd3447 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1017,9 +1017,15 @@ static void __net_exit dccp_v4_exit_net(struct net *net)
inet_ctl_sock_destroy(net->dccp.v4_ctl_sk);
}
+static void __net_exit dccp_v4_exit_batch(struct list_head *net_exit_list)
+{
+ inet_twsk_purge(&dccp_hashinfo, AF_INET);
+}
+
static struct pernet_operations dccp_v4_ops = {
.init = dccp_v4_init_net,
.exit = dccp_v4_exit_net,
+ .exit_batch = dccp_v4_exit_batch,
};
static int __init dccp_v4_init(void)
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index cef60a4a2803..233b57367758 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1075,9 +1075,15 @@ static void __net_exit dccp_v6_exit_net(struct net *net)
inet_ctl_sock_destroy(net->dccp.v6_ctl_sk);
}
+static void __net_exit dccp_v6_exit_batch(struct list_head *net_exit_list)
+{
+ inet_twsk_purge(&dccp_hashinfo, AF_INET6);
+}
+
static struct pernet_operations dccp_v6_ops = {
.init = dccp_v6_init_net,
.exit = dccp_v6_exit_net,
+ .exit_batch = dccp_v6_exit_batch,
};
static int __init dccp_v6_init(void)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 8c124d4ef4b7..9a89b8deafae 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -145,6 +145,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct flowi4 *fl4;
struct rtable *rt;
int err;
+ u32 seq;
struct ip_options_rcu *inet_opt;
struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row;
@@ -234,12 +235,15 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
sk_setup_caps(sk, &rt->dst);
rt = NULL;
- if (!tp->write_seq && likely(!tp->repair))
- tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr,
- inet->inet_daddr,
- inet->inet_sport,
- usin->sin_port,
- &tp->tsoffset);
+ if (likely(!tp->repair)) {
+ seq = secure_tcp_sequence_number(inet->inet_saddr,
+ inet->inet_daddr,
+ inet->inet_sport,
+ usin->sin_port,
+ &tp->tsoffset);
+ if (!tp->write_seq)
+ tp->write_seq = seq;
+ }
inet->inet_id = tp->write_seq ^ jiffies;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index dff7d2aaf861..7e16243cdb58 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -101,7 +101,8 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
tcp_parse_options(skb, &tmp_opt, 0, NULL);
if (tmp_opt.saw_tstamp) {
- tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset;
+ if (tmp_opt.rcv_tsecr)
+ tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset;
tmp_opt.ts_recent = tcptw->tw_ts_recent;
tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
paws_reject = tcp_paws_reject(&tmp_opt, th->rst);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 21c719965b6b..60a5295a7de6 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -122,6 +122,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct flowi6 fl6;
struct dst_entry *dst;
int addr_type;
+ u32 seq;
int err;
struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row;
@@ -285,12 +286,15 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
sk_set_txhash(sk);
- if (!tp->write_seq && likely(!tp->repair))
- tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
- sk->sk_v6_daddr.s6_addr32,
- inet->inet_sport,
- inet->inet_dport,
- &tp->tsoffset);
+ if (likely(!tp->repair)) {
+ seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
+ sk->sk_v6_daddr.s6_addr32,
+ inet->inet_sport,
+ inet->inet_dport,
+ &tp->tsoffset);
+ if (!tp->write_seq)
+ tp->write_seq = seq;
+ }
if (tcp_fastopen_defer_connect(sk, &err))
return err;
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 85948c69b236..b58000efee73 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1317,6 +1317,9 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
struct sock *sk = NULL;
tunnel = container_of(work, struct l2tp_tunnel, del_work);
+
+ l2tp_tunnel_closeall(tunnel);
+
sk = l2tp_tunnel_sock_lookup(tunnel);
if (!sk)
goto out;
@@ -1639,7 +1642,6 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
{
l2tp_tunnel_inc_refcount(tunnel);
- l2tp_tunnel_closeall(tunnel);
if (false == queue_work(l2tp_wq, &tunnel->del_work)) {
l2tp_tunnel_dec_refcount(tunnel);
return 1;
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index 1b05d4a7d5a1..f236c0bc7b3f 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -897,7 +897,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
continue;
data = ahash_data(n, j, dsize);
memcpy(tmp->value + k * dsize, data, dsize);
- set_bit(j, tmp->used);
+ set_bit(k, tmp->used);
k++;
}
tmp->pos = k;
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 51077c53d76b..178d4eba013b 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -260,11 +260,14 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
else
prev = e;
}
+
+ /* If before/after is used on an empty set */
+ if ((d->before > 0 && !next) ||
+ (d->before < 0 && !prev))
+ return -IPSET_ERR_REF_EXIST;
+
/* Re-add already existing element */
if (n) {
- if ((d->before > 0 && !next) ||
- (d->before < 0 && !prev))
- return -IPSET_ERR_REF_EXIST;
if (!flag_exist)
return -IPSET_ERR_EXIST;
/* Update extensions */
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 7341adf7059d..6dc44d9b4190 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -188,6 +188,26 @@ nf_ct_helper_ext_add(struct nf_conn *ct,
}
EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
+static struct nf_conntrack_helper *
+nf_ct_lookup_helper(struct nf_conn *ct, struct net *net)
+{
+ if (!net->ct.sysctl_auto_assign_helper) {
+ if (net->ct.auto_assign_helper_warned)
+ return NULL;
+ if (!__nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple))
+ return NULL;
+ pr_info("nf_conntrack: default automatic helper assignment "
+ "has been turned off for security reasons and CT-based "
+ " firewall rule not found. Use the iptables CT target "
+ "to attach helpers instead.\n");
+ net->ct.auto_assign_helper_warned = 1;
+ return NULL;
+ }
+
+ return __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+}
+
+
int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
gfp_t flags)
{
@@ -213,21 +233,14 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
}
help = nfct_help(ct);
- if (net->ct.sysctl_auto_assign_helper && helper == NULL) {
- helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
- if (unlikely(!net->ct.auto_assign_helper_warned && helper)) {
- pr_info("nf_conntrack: automatic helper "
- "assignment is deprecated and it will "
- "be removed soon. Use the iptables CT target "
- "to attach helpers instead.\n");
- net->ct.auto_assign_helper_warned = true;
- }
- }
if (helper == NULL) {
- if (help)
- RCU_INIT_POINTER(help->helper, NULL);
- return 0;
+ helper = nf_ct_lookup_helper(ct, net);
+ if (helper == NULL) {
+ if (help)
+ RCU_INIT_POINTER(help->helper, NULL);
+ return 0;
+ }
}
if (help == NULL) {
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 27540455dc62..6806b5e73567 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1478,14 +1478,23 @@ static int ctnetlink_change_helper(struct nf_conn *ct,
struct nlattr *helpinfo = NULL;
int err;
- /* don't change helper of sibling connections */
- if (ct->master)
- return -EBUSY;
-
err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
if (err < 0)
return err;
+ /* don't change helper of sibling connections */
+ if (ct->master) {
+ /* If we try to change the helper to the same thing twice,
+ * treat the second attempt as a no-op instead of returning
+ * an error.
+ */
+ if (help && help->helper &&
+ !strcmp(help->helper->name, helpname))
+ return 0;
+ else
+ return -EBUSY;
+ }
+
if (!strcmp(helpname, "")) {
if (help && help->helper) {
/* we had a helper before ... */
@@ -2270,6 +2279,30 @@ nla_put_failure:
}
static int
+ctnetlink_update_status(struct nf_conn *ct, const struct nlattr * const cda[])
+{
+ unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
+ unsigned long d = ct->status ^ status;
+
+ if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
+ /* SEEN_REPLY bit can only be set */
+ return -EBUSY;
+
+ if (d & IPS_ASSURED && !(status & IPS_ASSURED))
+ /* ASSURED bit can only be set */
+ return -EBUSY;
+
+ /* This check is less strict than ctnetlink_change_status()
+ * because callers often flip IPS_EXPECTED bits when sending
+ * an NFQA_CT attribute to the kernel. So ignore the
+ * unchangeable bits but do not error out.
+ */
+ ct->status = (status & ~IPS_UNCHANGEABLE_MASK) |
+ (ct->status & IPS_UNCHANGEABLE_MASK);
+ return 0;
+}
+
+static int
ctnetlink_glue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
{
int err;
@@ -2280,7 +2313,7 @@ ctnetlink_glue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
return err;
}
if (cda[CTA_STATUS]) {
- err = ctnetlink_change_status(ct, cda);
+ err = ctnetlink_update_status(ct, cda);
if (err < 0)
return err;
}
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index a2148d0bc50e..68eda920160e 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -279,7 +279,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net *net = sock_net(skb->sk);
const struct nfnetlink_subsystem *ss;
const struct nfnl_callback *nc;
- static LIST_HEAD(err_list);
+ LIST_HEAD(err_list);
u32 status;
int err;
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 26ef70c50e3b..2a6dfe8b74d3 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -463,23 +463,16 @@ static u32 xt_hashlimit_len_to_chunks(u32 len)
/* Precision saver. */
static u64 user2credits(u64 user, int revision)
{
- if (revision == 1) {
- /* If multiplying would overflow... */
- if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY_v1))
- /* Divide first. */
- return div64_u64(user, XT_HASHLIMIT_SCALE)
- * HZ * CREDITS_PER_JIFFY_v1;
-
- return div64_u64(user * HZ * CREDITS_PER_JIFFY_v1,
- XT_HASHLIMIT_SCALE);
- } else {
- if (user > 0xFFFFFFFFFFFFFFFFULL / (HZ*CREDITS_PER_JIFFY))
- return div64_u64(user, XT_HASHLIMIT_SCALE_v2)
- * HZ * CREDITS_PER_JIFFY;
+ u64 scale = (revision == 1) ?
+ XT_HASHLIMIT_SCALE : XT_HASHLIMIT_SCALE_v2;
+ u64 cpj = (revision == 1) ?
+ CREDITS_PER_JIFFY_v1 : CREDITS_PER_JIFFY;
- return div64_u64(user * HZ * CREDITS_PER_JIFFY,
- XT_HASHLIMIT_SCALE_v2);
- }
+ /* Avoid overflow: divide the constant operands first */
+ if (scale >= HZ * cpj)
+ return div64_u64(user, div64_u64(scale, HZ * cpj));
+
+ return user * div64_u64(HZ * cpj, scale);
}
static u32 user2credits_byte(u32 user)