mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 07:35:36 -05:00
Merge tag 'net-6.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"Including fixes from netfilter and CAN.
Current release - regressions:
- netfilter: nf_conncount: fix leaked ct in error paths
- sched: act_mirred: fix loop detection
- sctp: fix potential deadlock in sctp_clone_sock()
- can: fix build dependency
- eth: mlx5e: do not update BQL of old txqs during channel
reconfiguration
Previous releases - regressions:
- sched: ets: always remove class from active list before deleting it
- inet: frags: flush pending skbs in fqdir_pre_exit()
- netfilter: nf_nat: remove bogus direction check
- mptcp:
- schedule rtx timer only after pushing data
- avoid deadlock on fallback while reinjecting
- can: gs_usb: fix error handling
- eth:
- mlx5e:
- avoid unregistering PSP twice
- fix double unregister of HCA_PORTS component
- bnxt_en: fix XDP_TX path
- mlxsw: fix use-after-free when updating multicast route stats
Previous releases - always broken:
- ethtool: avoid overflowing userspace buffer on stats query
- openvswitch: fix middle attribute validation in push_nsh() action
- eth:
- mlx5: fw_tracer, validate format string parameters
- mlxsw: spectrum_router: fix neighbour use-after-free
- ipvlan: ignore PACKET_LOOPBACK in handle_mode_l2()
Misc:
- Jozsef Kadlecsik retires from maintaining netfilter
- tools: ynl: fix build on systems with old kernel headers"
* tag 'net-6.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits)
net: hns3: add VLAN id validation before using
net: hns3: using the num_tqps to check whether tqp_index is out of range when vf get ring info from mbx
net: hns3: using the num_tqps in the vf driver to apply for resources
net: enetc: do not transmit redirected XDP frames when the link is down
selftests/tc-testing: Test case exercising potential mirred redirect deadlock
net/sched: act_mirred: fix loop detection
sctp: Clear inet_opt in sctp_v6_copy_ip_options().
sctp: Fetch inet6_sk() after setting ->pinet6 in sctp_clone_sock().
net/handshake: duplicate handshake cancellations leak socket
net/mlx5e: Don't include PSP in the hard MTU calculations
net/mlx5e: Do not update BQL of old txqs during channel reconfiguration
net/mlx5e: Trigger neighbor resolution for unresolved destinations
net/mlx5e: Use ip6_dst_lookup instead of ipv6_dst_lookup_flow for MAC init
net/mlx5: Serialize firmware reset with devlink
net/mlx5: fw_tracer, Handle escaped percent properly
net/mlx5: fw_tracer, Validate format string parameters
net/mlx5: Drain firmware reset in shutdown callback
net/mlx5: fw reset, clear reset requested on drain_fw_reset
net: dsa: mxl-gsw1xx: manually clear RANEG bit
net: dsa: mxl-gsw1xx: fix .shutdown driver operation
...
This commit is contained in:
1
CREDITS
1
CREDITS
@@ -1987,6 +1987,7 @@ D: netfilter: TCP window tracking code
|
||||
D: netfilter: raw table
|
||||
D: netfilter: iprange match
|
||||
D: netfilter: new logging interfaces
|
||||
D: netfilter: ipset
|
||||
D: netfilter: various other hacks
|
||||
S: Tata
|
||||
S: Hungary
|
||||
|
||||
@@ -18028,7 +18028,6 @@ F: drivers/net/ethernet/neterion/
|
||||
|
||||
NETFILTER
|
||||
M: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
M: Jozsef Kadlecsik <kadlec@netfilter.org>
|
||||
M: Florian Westphal <fw@strlen.de>
|
||||
R: Phil Sutter <phil@nwl.cc>
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
menuconfig CAN_DEV
|
||||
tristate "CAN Device Drivers"
|
||||
bool "CAN Device Drivers"
|
||||
default y
|
||||
depends on CAN
|
||||
help
|
||||
@@ -17,10 +17,7 @@ menuconfig CAN_DEV
|
||||
virtual ones. If you own such devices or plan to use the virtual CAN
|
||||
interfaces to develop applications, say Y here.
|
||||
|
||||
To compile as a module, choose M here: the module will be called
|
||||
can-dev.
|
||||
|
||||
if CAN_DEV
|
||||
if CAN_DEV && CAN
|
||||
|
||||
config CAN_VCAN
|
||||
tristate "Virtual Local CAN Interface (vcan)"
|
||||
|
||||
@@ -7,7 +7,7 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o
|
||||
obj-$(CONFIG_CAN_VXCAN) += vxcan.o
|
||||
obj-$(CONFIG_CAN_SLCAN) += slcan/
|
||||
|
||||
obj-y += dev/
|
||||
obj-$(CONFIG_CAN_DEV) += dev/
|
||||
obj-y += esd/
|
||||
obj-y += rcar/
|
||||
obj-y += rockchip/
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_CAN_DEV) += can-dev.o
|
||||
|
||||
can-dev-y += skb.o
|
||||
obj-$(CONFIG_CAN) += can-dev.o
|
||||
|
||||
can-dev-$(CONFIG_CAN_DEV) += skb.o
|
||||
can-dev-$(CONFIG_CAN_CALC_BITTIMING) += calc_bittiming.o
|
||||
can-dev-$(CONFIG_CAN_NETLINK) += bittiming.o
|
||||
can-dev-$(CONFIG_CAN_NETLINK) += dev.o
|
||||
|
||||
@@ -1074,7 +1074,7 @@ static int gs_can_open(struct net_device *netdev)
|
||||
usb_free_urb(urb);
|
||||
out_usb_kill_anchored_urbs:
|
||||
if (!parent->active_channels) {
|
||||
usb_kill_anchored_urbs(&dev->tx_submitted);
|
||||
usb_kill_anchored_urbs(&parent->rx_submitted);
|
||||
|
||||
if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
|
||||
gs_usb_timestamp_stop(parent);
|
||||
|
||||
@@ -444,9 +444,6 @@ static void gswip_remove(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
/* disable the switch */
|
||||
gswip_disable_switch(priv);
|
||||
|
||||
dsa_unregister_switch(priv->ds);
|
||||
|
||||
for (i = 0; i < priv->num_gphy_fw; i++)
|
||||
|
||||
@@ -294,8 +294,6 @@ struct gswip_priv {
|
||||
u16 version;
|
||||
};
|
||||
|
||||
void gswip_disable_switch(struct gswip_priv *priv);
|
||||
|
||||
int gswip_probe_common(struct gswip_priv *priv, u32 version);
|
||||
|
||||
#endif /* __LANTIQ_GSWIP_H */
|
||||
|
||||
@@ -752,6 +752,13 @@ static int gswip_setup(struct dsa_switch *ds)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gswip_teardown(struct dsa_switch *ds)
|
||||
{
|
||||
struct gswip_priv *priv = ds->priv;
|
||||
|
||||
regmap_clear_bits(priv->mdio, GSWIP_MDIO_GLOB, GSWIP_MDIO_GLOB_ENABLE);
|
||||
}
|
||||
|
||||
static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,
|
||||
int port,
|
||||
enum dsa_tag_protocol mp)
|
||||
@@ -1629,6 +1636,7 @@ static const struct phylink_mac_ops gswip_phylink_mac_ops = {
|
||||
static const struct dsa_switch_ops gswip_switch_ops = {
|
||||
.get_tag_protocol = gswip_get_tag_protocol,
|
||||
.setup = gswip_setup,
|
||||
.teardown = gswip_teardown,
|
||||
.port_setup = gswip_port_setup,
|
||||
.port_enable = gswip_port_enable,
|
||||
.port_disable = gswip_port_disable,
|
||||
@@ -1656,12 +1664,6 @@ static const struct dsa_switch_ops gswip_switch_ops = {
|
||||
.port_hsr_leave = dsa_port_simple_hsr_leave,
|
||||
};
|
||||
|
||||
void gswip_disable_switch(struct gswip_priv *priv)
|
||||
{
|
||||
regmap_clear_bits(priv->mdio, GSWIP_MDIO_GLOB, GSWIP_MDIO_GLOB_ENABLE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gswip_disable_switch);
|
||||
|
||||
static int gswip_validate_cpu_port(struct dsa_switch *ds)
|
||||
{
|
||||
struct gswip_priv *priv = ds->priv;
|
||||
@@ -1718,15 +1720,14 @@ int gswip_probe_common(struct gswip_priv *priv, u32 version)
|
||||
|
||||
err = gswip_validate_cpu_port(priv->ds);
|
||||
if (err)
|
||||
goto disable_switch;
|
||||
goto unregister_switch;
|
||||
|
||||
dev_info(priv->dev, "probed GSWIP version %lx mod %lx\n",
|
||||
GSWIP_VERSION_REV(version), GSWIP_VERSION_MOD(version));
|
||||
|
||||
return 0;
|
||||
|
||||
disable_switch:
|
||||
gswip_disable_switch(priv);
|
||||
unregister_switch:
|
||||
dsa_unregister_switch(priv->ds);
|
||||
|
||||
return err;
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/dsa.h>
|
||||
|
||||
#include "lantiq_gswip.h"
|
||||
@@ -29,6 +31,7 @@ struct gsw1xx_priv {
|
||||
struct regmap *clk;
|
||||
struct regmap *shell;
|
||||
struct phylink_pcs pcs;
|
||||
struct delayed_work clear_raneg;
|
||||
phy_interface_t tbi_interface;
|
||||
struct gswip_priv gswip;
|
||||
};
|
||||
@@ -145,7 +148,9 @@ static void gsw1xx_pcs_disable(struct phylink_pcs *pcs)
|
||||
{
|
||||
struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
|
||||
|
||||
/* Assert SGMII shell reset */
|
||||
cancel_delayed_work_sync(&priv->clear_raneg);
|
||||
|
||||
/* Assert SGMII shell reset (will also clear RANEG bit) */
|
||||
regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
|
||||
GSW1XX_RST_REQ_SGMII_SHELL);
|
||||
|
||||
@@ -255,10 +260,16 @@ static int gsw1xx_pcs_reset(struct gsw1xx_priv *priv)
|
||||
FIELD_PREP(GSW1XX_SGMII_PHY_RX0_CFG2_FILT_CNT,
|
||||
GSW1XX_SGMII_PHY_RX0_CFG2_FILT_CNT_DEF);
|
||||
|
||||
/* TODO: Take care of inverted RX pair once generic property is
|
||||
/* RX lane seems to be inverted internally, so bit
|
||||
* GSW1XX_SGMII_PHY_RX0_CFG2_INVERT needs to be set for normal
|
||||
* (ie. non-inverted) operation.
|
||||
*
|
||||
* TODO: Take care of inverted RX pair once generic property is
|
||||
* available
|
||||
*/
|
||||
|
||||
val |= GSW1XX_SGMII_PHY_RX0_CFG2_INVERT;
|
||||
|
||||
ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_RX0_CFG2, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -422,12 +433,29 @@ static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gsw1xx_pcs_clear_raneg(struct work_struct *work)
|
||||
{
|
||||
struct gsw1xx_priv *priv =
|
||||
container_of(work, struct gsw1xx_priv, clear_raneg.work);
|
||||
|
||||
regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL,
|
||||
GSW1XX_SGMII_TBI_ANEGCTL_RANEG);
|
||||
}
|
||||
|
||||
static void gsw1xx_pcs_an_restart(struct phylink_pcs *pcs)
|
||||
{
|
||||
struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
|
||||
|
||||
cancel_delayed_work_sync(&priv->clear_raneg);
|
||||
|
||||
regmap_set_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL,
|
||||
GSW1XX_SGMII_TBI_ANEGCTL_RANEG);
|
||||
|
||||
/* despite being documented as self-clearing, the RANEG bit
|
||||
* sometimes remains set, preventing auto-negotiation from happening.
|
||||
* MaxLinear advises to manually clear the bit after 10ms.
|
||||
*/
|
||||
schedule_delayed_work(&priv->clear_raneg, msecs_to_jiffies(10));
|
||||
}
|
||||
|
||||
static void gsw1xx_pcs_link_up(struct phylink_pcs *pcs,
|
||||
@@ -630,6 +658,8 @@ static int gsw1xx_probe(struct mdio_device *mdiodev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
INIT_DELAYED_WORK(&priv->clear_raneg, gsw1xx_pcs_clear_raneg);
|
||||
|
||||
ret = gswip_probe_common(&priv->gswip, version);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -642,25 +672,31 @@ static int gsw1xx_probe(struct mdio_device *mdiodev)
|
||||
static void gsw1xx_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
struct gsw1xx_priv *gsw1xx_priv;
|
||||
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
gswip_disable_switch(priv);
|
||||
|
||||
dsa_unregister_switch(priv->ds);
|
||||
|
||||
gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip);
|
||||
cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
|
||||
}
|
||||
|
||||
static void gsw1xx_shutdown(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
struct gsw1xx_priv *gsw1xx_priv;
|
||||
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
dsa_switch_shutdown(priv->ds);
|
||||
|
||||
dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
|
||||
gswip_disable_switch(priv);
|
||||
gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip);
|
||||
cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
|
||||
}
|
||||
|
||||
static const struct gswip_hw_info gsw12x_data = {
|
||||
|
||||
@@ -1790,6 +1790,9 @@ static int b44_nway_reset(struct net_device *dev)
|
||||
u32 bmcr;
|
||||
int r;
|
||||
|
||||
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
|
||||
return phy_ethtool_nway_reset(dev);
|
||||
|
||||
spin_lock_irq(&bp->lock);
|
||||
b44_readphy(bp, MII_BMCR, &bmcr);
|
||||
b44_readphy(bp, MII_BMCR, &bmcr);
|
||||
|
||||
@@ -268,13 +268,11 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
case XDP_TX:
|
||||
rx_buf = &rxr->rx_buf_ring[cons];
|
||||
mapping = rx_buf->mapping - bp->rx_dma_offset;
|
||||
*event &= BNXT_TX_CMP_EVENT;
|
||||
|
||||
if (unlikely(xdp_buff_has_frags(xdp))) {
|
||||
struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
|
||||
|
||||
tx_needed += sinfo->nr_frags;
|
||||
*event = BNXT_AGG_EVENT;
|
||||
}
|
||||
|
||||
if (tx_avail < tx_needed) {
|
||||
@@ -287,6 +285,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
|
||||
dma_sync_single_for_device(&pdev->dev, mapping + offset, *len,
|
||||
bp->rx_dir);
|
||||
|
||||
*event &= ~BNXT_RX_EVENT;
|
||||
*event |= BNXT_TX_EVENT;
|
||||
__bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
|
||||
NEXT_RX(rxr->rx_prod), xdp);
|
||||
|
||||
@@ -1787,7 +1787,8 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
|
||||
int xdp_tx_bd_cnt, i, k;
|
||||
int xdp_tx_frm_cnt = 0;
|
||||
|
||||
if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags)))
|
||||
if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags) ||
|
||||
!netif_carrier_ok(ndev)))
|
||||
return -ENETDOWN;
|
||||
|
||||
enetc_lock_mdio();
|
||||
|
||||
@@ -3933,6 +3933,11 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
|
||||
txq->bd.cur = bdp;
|
||||
|
||||
/* Trigger transmission start */
|
||||
if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
|
||||
!readl(txq->bd.reg_desc_active) ||
|
||||
!readl(txq->bd.reg_desc_active) ||
|
||||
!readl(txq->bd.reg_desc_active) ||
|
||||
!readl(txq->bd.reg_desc_active))
|
||||
writel(0, txq->bd.reg_desc_active);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -647,12 +647,9 @@ static int gve_setup_device_resources(struct gve_priv *priv)
|
||||
err = gve_alloc_counter_array(priv);
|
||||
if (err)
|
||||
goto abort_with_rss_config_cache;
|
||||
err = gve_init_clock(priv);
|
||||
if (err)
|
||||
goto abort_with_counter;
|
||||
err = gve_alloc_notify_blocks(priv);
|
||||
if (err)
|
||||
goto abort_with_clock;
|
||||
goto abort_with_counter;
|
||||
err = gve_alloc_stats_report(priv);
|
||||
if (err)
|
||||
goto abort_with_ntfy_blocks;
|
||||
@@ -683,10 +680,16 @@ static int gve_setup_device_resources(struct gve_priv *priv)
|
||||
}
|
||||
}
|
||||
|
||||
err = gve_init_clock(priv);
|
||||
if (err) {
|
||||
dev_err(&priv->pdev->dev, "Failed to init clock");
|
||||
goto abort_with_ptype_lut;
|
||||
}
|
||||
|
||||
err = gve_init_rss_config(priv, priv->rx_cfg.num_queues);
|
||||
if (err) {
|
||||
dev_err(&priv->pdev->dev, "Failed to init RSS config");
|
||||
goto abort_with_ptype_lut;
|
||||
goto abort_with_clock;
|
||||
}
|
||||
|
||||
err = gve_adminq_report_stats(priv, priv->stats_report_len,
|
||||
@@ -698,6 +701,8 @@ static int gve_setup_device_resources(struct gve_priv *priv)
|
||||
gve_set_device_resources_ok(priv);
|
||||
return 0;
|
||||
|
||||
abort_with_clock:
|
||||
gve_teardown_clock(priv);
|
||||
abort_with_ptype_lut:
|
||||
kvfree(priv->ptype_lut_dqo);
|
||||
priv->ptype_lut_dqo = NULL;
|
||||
@@ -705,8 +710,6 @@ static int gve_setup_device_resources(struct gve_priv *priv)
|
||||
gve_free_stats_report(priv);
|
||||
abort_with_ntfy_blocks:
|
||||
gve_free_notify_blocks(priv);
|
||||
abort_with_clock:
|
||||
gve_teardown_clock(priv);
|
||||
abort_with_counter:
|
||||
gve_free_counter_array(priv);
|
||||
abort_with_rss_config_cache:
|
||||
|
||||
@@ -10555,6 +10555,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
|
||||
bool writen_to_tbl = false;
|
||||
int ret = 0;
|
||||
|
||||
if (vlan_id >= VLAN_N_VID)
|
||||
return -EINVAL;
|
||||
|
||||
/* When device is resetting or reset failed, firmware is unable to
|
||||
* handle mailbox. Just record the vlan id, and remove it after
|
||||
* reset finished.
|
||||
|
||||
@@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx(
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ring_num; i++) {
|
||||
if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
|
||||
if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) {
|
||||
dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n",
|
||||
req->msg.param[i].tqp_index,
|
||||
vport->nic.kinfo.rss_size - 1U);
|
||||
vport->nic.kinfo.num_tqps - 1U);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,12 +368,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev)
|
||||
new_tqps = kinfo->rss_size * num_tc;
|
||||
kinfo->num_tqps = min(new_tqps, hdev->num_tqps);
|
||||
|
||||
kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps,
|
||||
kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps,
|
||||
sizeof(struct hnae3_queue *), GFP_KERNEL);
|
||||
if (!kinfo->tqp)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < kinfo->num_tqps; i++) {
|
||||
for (i = 0; i < hdev->num_tqps; i++) {
|
||||
hdev->htqp[i].q.handle = &hdev->nic;
|
||||
hdev->htqp[i].q.tqp_index = i;
|
||||
kinfo->tqp[i] = &hdev->htqp[i].q;
|
||||
|
||||
@@ -197,6 +197,11 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
|
||||
struct pci_dev *pdev = dev->pdev;
|
||||
int ret = 0;
|
||||
|
||||
if (mlx5_fw_reset_in_progress(dev)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Can't reload during firmware reset");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (mlx5_dev_is_lightweight(dev)) {
|
||||
if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "lib/eq.h"
|
||||
#include "fw_tracer.h"
|
||||
#include "fw_tracer_tracepoint.h"
|
||||
#include <linux/ctype.h>
|
||||
|
||||
static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer)
|
||||
{
|
||||
@@ -358,6 +359,47 @@ static const char *VAL_PARM = "%llx";
|
||||
static const char *REPLACE_64_VAL_PARM = "%x%x";
|
||||
static const char *PARAM_CHAR = "%";
|
||||
|
||||
static bool mlx5_is_valid_spec(const char *str)
|
||||
{
|
||||
/* Parse format specifiers to find the actual type.
|
||||
* Structure: %[flags][width][.precision][length]type
|
||||
* Skip flags, width, precision & length.
|
||||
*/
|
||||
while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l')
|
||||
str++;
|
||||
|
||||
/* Check if it's a valid integer/hex specifier or %%:
|
||||
* Valid formats: %x, %d, %i, %u, etc.
|
||||
*/
|
||||
if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' &&
|
||||
*str != 'u' && *str != 'c' && *str != '%')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mlx5_tracer_validate_params(const char *str)
|
||||
{
|
||||
const char *substr = str;
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
substr = strstr(substr, PARAM_CHAR);
|
||||
while (substr) {
|
||||
if (!mlx5_is_valid_spec(substr + 1))
|
||||
return false;
|
||||
|
||||
if (*(substr + 1) == '%')
|
||||
substr = strstr(substr + 2, PARAM_CHAR);
|
||||
else
|
||||
substr = strstr(substr + 1, PARAM_CHAR);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int mlx5_tracer_message_hash(u32 message_id)
|
||||
{
|
||||
return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1);
|
||||
@@ -419,6 +461,10 @@ static int mlx5_tracer_get_num_of_params(char *str)
|
||||
char *substr, *pstr = str;
|
||||
int num_of_params = 0;
|
||||
|
||||
/* Validate that all parameters are valid before processing */
|
||||
if (!mlx5_tracer_validate_params(str))
|
||||
return -EINVAL;
|
||||
|
||||
/* replace %llx with %x%x */
|
||||
substr = strstr(pstr, VAL_PARM);
|
||||
while (substr) {
|
||||
@@ -427,11 +473,15 @@ static int mlx5_tracer_get_num_of_params(char *str)
|
||||
substr = strstr(pstr, VAL_PARM);
|
||||
}
|
||||
|
||||
/* count all the % characters */
|
||||
/* count all the % characters, but skip %% (escaped percent) */
|
||||
substr = strstr(str, PARAM_CHAR);
|
||||
while (substr) {
|
||||
if (*(substr + 1) != '%') {
|
||||
num_of_params += 1;
|
||||
str = substr + 1;
|
||||
} else {
|
||||
str = substr + 2;
|
||||
}
|
||||
substr = strstr(str, PARAM_CHAR);
|
||||
}
|
||||
|
||||
@@ -570,6 +620,9 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt,
|
||||
{
|
||||
char tmp[512];
|
||||
|
||||
if (str_frmt->invalid_string)
|
||||
snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string);
|
||||
else
|
||||
snprintf(tmp, sizeof(tmp), str_frmt->string,
|
||||
str_frmt->params[0],
|
||||
str_frmt->params[1],
|
||||
@@ -609,6 +662,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer,
|
||||
struct tracer_string_format *cur_string)
|
||||
{
|
||||
cur_string->invalid_string = true;
|
||||
list_add_tail(&cur_string->list, &tracer->ready_strings_list);
|
||||
}
|
||||
|
||||
static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
|
||||
struct tracer_event *tracer_event)
|
||||
{
|
||||
@@ -619,12 +679,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
|
||||
if (!cur_string)
|
||||
return mlx5_tracer_handle_raw_string(tracer, tracer_event);
|
||||
|
||||
cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
|
||||
cur_string->last_param_num = 0;
|
||||
cur_string->event_id = tracer_event->event_id;
|
||||
cur_string->tmsn = tracer_event->string_event.tmsn;
|
||||
cur_string->timestamp = tracer_event->string_event.timestamp;
|
||||
cur_string->lost = tracer_event->lost_event;
|
||||
cur_string->last_param_num = 0;
|
||||
cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string);
|
||||
if (cur_string->num_of_params < 0) {
|
||||
pr_debug("%s Invalid format string parameters\n",
|
||||
__func__);
|
||||
mlx5_tracer_handle_bad_format_string(tracer, cur_string);
|
||||
return 0;
|
||||
}
|
||||
if (cur_string->num_of_params == 0) /* trace with no params */
|
||||
list_add_tail(&cur_string->list, &tracer->ready_strings_list);
|
||||
} else {
|
||||
@@ -634,6 +700,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer,
|
||||
__func__, tracer_event->string_event.tmsn);
|
||||
return mlx5_tracer_handle_raw_string(tracer, tracer_event);
|
||||
}
|
||||
if (cur_string->num_of_params < 0) {
|
||||
pr_debug("%s string parameter of invalid string, dumping\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
cur_string->last_param_num += 1;
|
||||
if (cur_string->last_param_num > TRACER_MAX_PARAMS) {
|
||||
pr_debug("%s Number of params exceeds the max (%d)\n",
|
||||
|
||||
@@ -125,6 +125,7 @@ struct tracer_string_format {
|
||||
struct list_head list;
|
||||
u32 timestamp;
|
||||
bool lost;
|
||||
bool invalid_string;
|
||||
};
|
||||
|
||||
enum mlx5_fw_tracer_ownership_state {
|
||||
|
||||
@@ -69,7 +69,7 @@ struct page_pool;
|
||||
#define MLX5E_METADATA_ETHER_TYPE (0x8CE4)
|
||||
#define MLX5E_METADATA_ETHER_LEN 8
|
||||
|
||||
#define MLX5E_ETH_HARD_MTU (ETH_HLEN + PSP_ENCAP_HLEN + PSP_TRL_SIZE + VLAN_HLEN + ETH_FCS_LEN)
|
||||
#define MLX5E_ETH_HARD_MTU (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
|
||||
|
||||
#define MLX5E_HW2SW_MTU(params, hwmtu) ((hwmtu) - ((params)->hard_mtu))
|
||||
#define MLX5E_SW2HW_MTU(params, swmtu) ((swmtu) + ((params)->hard_mtu))
|
||||
|
||||
@@ -342,9 +342,8 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||
rt_dst_entry = &rt->dst;
|
||||
break;
|
||||
case AF_INET6:
|
||||
rt_dst_entry = ipv6_stub->ipv6_dst_lookup_flow(
|
||||
dev_net(netdev), NULL, &fl6, NULL);
|
||||
if (IS_ERR(rt_dst_entry))
|
||||
if (!IS_ENABLED(CONFIG_IPV6) ||
|
||||
ip6_dst_lookup(dev_net(netdev), NULL, &rt_dst_entry, &fl6))
|
||||
goto neigh;
|
||||
break;
|
||||
default:
|
||||
@@ -359,6 +358,9 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||
|
||||
neigh_ha_snapshot(addr, n, netdev);
|
||||
ether_addr_copy(dst, addr);
|
||||
if (attrs->dir == XFRM_DEV_OFFLOAD_OUT &&
|
||||
is_zero_ether_addr(addr))
|
||||
neigh_event_send(n, NULL);
|
||||
dst_release(rt_dst_entry);
|
||||
neigh_release(n);
|
||||
return;
|
||||
|
||||
@@ -6825,7 +6825,6 @@ static void _mlx5e_remove(struct auxiliary_device *adev)
|
||||
* is already unregistered before changing to NIC profile.
|
||||
*/
|
||||
if (priv->netdev->reg_state == NETREG_REGISTERED) {
|
||||
mlx5e_psp_unregister(priv);
|
||||
unregister_netdev(priv->netdev);
|
||||
_mlx5e_suspend(adev, false);
|
||||
} else {
|
||||
|
||||
@@ -939,6 +939,10 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq)
|
||||
sq->dma_fifo_cc = dma_fifo_cc;
|
||||
sq->cc = sqcc;
|
||||
|
||||
/* Do not update BQL for TXQs that got replaced by new active ones, as
|
||||
* netdev_tx_reset_queue() is called for them in mlx5e_activate_txqsq().
|
||||
*/
|
||||
if (sq == sq->priv->txq2sq[sq->txq_ix])
|
||||
netdev_tx_completed_queue(sq->txq, npkts, nbytes);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "devlink.h"
|
||||
#include "lag/lag.h"
|
||||
#include "en/tc/post_meter.h"
|
||||
#include "fw_reset.h"
|
||||
|
||||
/* There are two match-all miss flows, one for unicast dst mac and
|
||||
* one for multicast.
|
||||
@@ -3991,6 +3992,11 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
|
||||
if (IS_ERR(esw))
|
||||
return PTR_ERR(esw);
|
||||
|
||||
if (mlx5_fw_reset_in_progress(esw->dev)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Can't change eswitch mode during firmware reset");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (esw_mode_from_devlink(mode, &mlx5_mode))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ enum {
|
||||
MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
|
||||
MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
|
||||
MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
|
||||
MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS,
|
||||
};
|
||||
|
||||
struct mlx5_fw_reset {
|
||||
@@ -128,6 +129,16 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
|
||||
return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
|
||||
}
|
||||
|
||||
bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
|
||||
|
||||
if (!fw_reset)
|
||||
return false;
|
||||
|
||||
return test_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
|
||||
}
|
||||
|
||||
static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
|
||||
u8 *reset_method)
|
||||
{
|
||||
@@ -243,6 +254,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
|
||||
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
|
||||
devl_unlock(devlink);
|
||||
}
|
||||
|
||||
clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
|
||||
}
|
||||
|
||||
static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev)
|
||||
@@ -462,27 +475,48 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
|
||||
struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
|
||||
reset_request_work);
|
||||
struct mlx5_core_dev *dev = fw_reset->dev;
|
||||
bool nack_request = false;
|
||||
struct devlink *devlink;
|
||||
int err;
|
||||
|
||||
err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
|
||||
if (err)
|
||||
if (err) {
|
||||
nack_request = true;
|
||||
mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
|
||||
} else if (!mlx5_is_reset_now_capable(dev, fw_reset->reset_method) ||
|
||||
test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
|
||||
&fw_reset->reset_flags)) {
|
||||
nack_request = true;
|
||||
}
|
||||
|
||||
if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
|
||||
!mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) {
|
||||
devlink = priv_to_devlink(dev);
|
||||
/* For external resets, try to acquire devl_lock. Skip if devlink reset is
|
||||
* pending (lock already held)
|
||||
*/
|
||||
if (nack_request ||
|
||||
(!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP,
|
||||
&fw_reset->reset_flags) &&
|
||||
!devl_trylock(devlink))) {
|
||||
err = mlx5_fw_reset_set_reset_sync_nack(dev);
|
||||
mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
|
||||
err ? "Failed" : "Sent");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mlx5_sync_reset_set_reset_requested(dev))
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
set_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
|
||||
|
||||
err = mlx5_fw_reset_set_reset_sync_ack(dev);
|
||||
if (err)
|
||||
mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err);
|
||||
else
|
||||
mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
|
||||
|
||||
unlock:
|
||||
if (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
|
||||
devl_unlock(devlink);
|
||||
}
|
||||
|
||||
static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
|
||||
@@ -722,6 +756,8 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work)
|
||||
|
||||
if (mlx5_sync_reset_clear_reset_requested(dev, true))
|
||||
return;
|
||||
|
||||
clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
|
||||
mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n");
|
||||
}
|
||||
|
||||
@@ -758,6 +794,7 @@ static void mlx5_sync_reset_timeout_work(struct work_struct *work)
|
||||
|
||||
if (mlx5_sync_reset_clear_reset_requested(dev, true))
|
||||
return;
|
||||
clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags);
|
||||
mlx5_core_warn(dev, "PCI Sync FW Update Reset Timeout.\n");
|
||||
}
|
||||
|
||||
@@ -844,7 +881,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev)
|
||||
cancel_work_sync(&fw_reset->reset_reload_work);
|
||||
cancel_work_sync(&fw_reset->reset_now_work);
|
||||
cancel_work_sync(&fw_reset->reset_abort_work);
|
||||
cancel_delayed_work(&fw_reset->reset_timeout_work);
|
||||
if (test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags))
|
||||
mlx5_sync_reset_clear_reset_requested(dev, true);
|
||||
}
|
||||
|
||||
static const struct devlink_param mlx5_fw_reset_devlink_params[] = {
|
||||
|
||||
@@ -10,6 +10,7 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty
|
||||
int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
|
||||
struct netlink_ext_ack *extack);
|
||||
int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
|
||||
bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev);
|
||||
|
||||
int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
|
||||
void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
|
||||
|
||||
@@ -1413,6 +1413,7 @@ static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
|
||||
static void mlx5_lag_unregister_hca_devcom_comp(struct mlx5_core_dev *dev)
|
||||
{
|
||||
mlx5_devcom_unregister_component(dev->priv.hca_devcom_comp);
|
||||
dev->priv.hca_devcom_comp = NULL;
|
||||
}
|
||||
|
||||
static int mlx5_lag_register_hca_devcom_comp(struct mlx5_core_dev *dev)
|
||||
|
||||
@@ -67,12 +67,19 @@ static int mlx5_mpesw_metadata_set(struct mlx5_lag *ldev)
|
||||
|
||||
static int enable_mpesw(struct mlx5_lag *ldev)
|
||||
{
|
||||
int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
struct mlx5_core_dev *dev0;
|
||||
int err;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (idx < 0 || ldev->mode != MLX5_LAG_MODE_NONE)
|
||||
if (ldev->mode == MLX5_LAG_MODE_MPESW)
|
||||
return 0;
|
||||
|
||||
if (ldev->mode != MLX5_LAG_MODE_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
if (idx < 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev0 = ldev->pf[idx].dev;
|
||||
|
||||
@@ -2231,6 +2231,7 @@ static void shutdown(struct pci_dev *pdev)
|
||||
|
||||
mlx5_core_info(dev, "Shutdown was called\n");
|
||||
set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
|
||||
mlx5_drain_fw_reset(dev);
|
||||
mlx5_drain_health_wq(dev);
|
||||
err = mlx5_try_fast_unload(dev);
|
||||
if (err)
|
||||
|
||||
@@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table,
|
||||
rhashtable_remove_fast(&mr_table->route_ht,
|
||||
&mr_orig_route->ht_node,
|
||||
mlxsw_sp_mr_route_ht_params);
|
||||
mutex_lock(&mr_table->route_list_lock);
|
||||
list_del(&mr_orig_route->node);
|
||||
mutex_unlock(&mr_table->route_list_lock);
|
||||
mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route);
|
||||
}
|
||||
|
||||
|
||||
@@ -2265,6 +2265,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
|
||||
if (!neigh_entry)
|
||||
return NULL;
|
||||
|
||||
neigh_hold(n);
|
||||
neigh_entry->key.n = n;
|
||||
neigh_entry->rif = rif;
|
||||
INIT_LIST_HEAD(&neigh_entry->nexthop_list);
|
||||
@@ -2274,6 +2275,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
|
||||
|
||||
static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
|
||||
{
|
||||
neigh_release(neigh_entry->key.n);
|
||||
kfree(neigh_entry);
|
||||
}
|
||||
|
||||
@@ -2858,6 +2860,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
|
||||
if (!net_work)
|
||||
return NOTIFY_BAD;
|
||||
|
||||
/* Take a reference to ensure the neighbour won't be destructed until
|
||||
* we drop the reference in the work item.
|
||||
*/
|
||||
neigh_clone(n);
|
||||
|
||||
INIT_WORK(&net_work->work, cb);
|
||||
net_work->mlxsw_sp = router->mlxsw_sp;
|
||||
net_work->n = n;
|
||||
@@ -2881,11 +2888,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router,
|
||||
struct net *net;
|
||||
|
||||
net = neigh_parms_net(n->parms);
|
||||
|
||||
/* Take a reference to ensure the neighbour won't be destructed until we
|
||||
* drop the reference in delayed work.
|
||||
*/
|
||||
neigh_clone(n);
|
||||
return mlxsw_sp_router_schedule_work(net, router, n,
|
||||
mlxsw_sp_router_neigh_event_work);
|
||||
}
|
||||
@@ -4320,6 +4322,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
if (err)
|
||||
goto err_neigh_entry_insert;
|
||||
|
||||
neigh_release(old_n);
|
||||
|
||||
read_lock_bh(&n->lock);
|
||||
nud_state = n->nud_state;
|
||||
dead = n->dead;
|
||||
@@ -4328,14 +4332,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
|
||||
|
||||
list_for_each_entry(nh, &neigh_entry->nexthop_list,
|
||||
neigh_list_node) {
|
||||
neigh_release(old_n);
|
||||
neigh_clone(n);
|
||||
__mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
|
||||
mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
|
||||
}
|
||||
|
||||
neigh_release(n);
|
||||
|
||||
return 0;
|
||||
|
||||
err_neigh_entry_insert:
|
||||
@@ -4428,6 +4428,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the reference taken by neigh_lookup() / neigh_create() since
|
||||
* neigh_entry already holds one.
|
||||
*/
|
||||
neigh_release(n);
|
||||
|
||||
/* If that is the first nexthop connected to that neigh, add to
|
||||
* nexthop_neighs_list
|
||||
*/
|
||||
@@ -4454,11 +4459,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_nexthop *nh)
|
||||
{
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
|
||||
struct neighbour *n;
|
||||
|
||||
if (!neigh_entry)
|
||||
return;
|
||||
n = neigh_entry->key.n;
|
||||
|
||||
__mlxsw_sp_nexthop_neigh_update(nh, true);
|
||||
list_del(&nh->neigh_list_node);
|
||||
@@ -4472,8 +4475,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
|
||||
|
||||
if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
|
||||
mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
|
||||
|
||||
neigh_release(n);
|
||||
}
|
||||
|
||||
static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
|
||||
|
||||
@@ -2655,9 +2655,6 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp)
|
||||
|
||||
static void rtl_prepare_power_down(struct rtl8169_private *tp)
|
||||
{
|
||||
if (tp->dash_enabled)
|
||||
return;
|
||||
|
||||
if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
|
||||
tp->mac_version == RTL_GIGA_MAC_VER_33)
|
||||
rtl_ephy_write(tp, 0x19, 0xff64);
|
||||
@@ -4812,7 +4809,7 @@ static void rtl8169_down(struct rtl8169_private *tp)
|
||||
rtl_disable_exit_l1(tp);
|
||||
rtl_prepare_power_down(tp);
|
||||
|
||||
if (tp->dash_type != RTL_DASH_NONE)
|
||||
if (tp->dash_type != RTL_DASH_NONE && !tp->saved_wolopts)
|
||||
rtl8168_driver_stop(tp);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ config TI_ICSSG_PRUETH_SR1
|
||||
depends on PRU_REMOTEPROC
|
||||
depends on NET_SWITCHDEV
|
||||
depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
help
|
||||
Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem.
|
||||
This subsystem is available on the AM65 SR1.0 platform.
|
||||
@@ -234,7 +235,7 @@ config TI_PRUETH
|
||||
depends on PRU_REMOTEPROC
|
||||
depends on NET_SWITCHDEV
|
||||
select TI_ICSS_IEP
|
||||
imply PTP_1588_CLOCK
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
help
|
||||
Some TI SoCs has Programmable Realtime Unit (PRU) cores which can
|
||||
support Single or Dual Ethernet ports with the help of firmware code
|
||||
|
||||
@@ -737,6 +737,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
|
||||
struct ethhdr *eth = eth_hdr(skb);
|
||||
rx_handler_result_t ret = RX_HANDLER_PASS;
|
||||
|
||||
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
|
||||
return RX_HANDLER_PASS;
|
||||
|
||||
if (is_multicast_ether_addr(eth->h_dest)) {
|
||||
if (ipvlan_external_frame(skb, port)) {
|
||||
struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
|
||||
@@ -698,7 +698,7 @@ static int mv88q2xxx_hwmon_write(struct device *dev,
|
||||
|
||||
switch (attr) {
|
||||
case hwmon_temp_max:
|
||||
clamp_val(val, -75000, 180000);
|
||||
val = clamp(val, -75000, 180000);
|
||||
val = (val / 1000) + 75;
|
||||
val = FIELD_PREP(MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
|
||||
val);
|
||||
|
||||
@@ -691,10 +691,6 @@ static int rtl8211f_config_aldps(struct phy_device *phydev)
|
||||
|
||||
static int rtl8211f_config_phy_eee(struct phy_device *phydev)
|
||||
{
|
||||
/* RTL8211FVD has no PHYCR2 register */
|
||||
if (phydev->drv->phy_id == RTL_8211FVD_PHYID)
|
||||
return 0;
|
||||
|
||||
/* Disable PHY-mode EEE so LPI is passed to the MAC */
|
||||
return phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2,
|
||||
RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0);
|
||||
|
||||
@@ -497,6 +497,8 @@ static const struct sfp_quirk sfp_quirks[] = {
|
||||
SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex,
|
||||
sfp_fixup_nokia),
|
||||
|
||||
SFP_QUIRK_F("BIDB", "X-ONU-SFPP", sfp_fixup_potron),
|
||||
|
||||
// FLYPRO SFP-10GT-CS-30M uses Rollball protocol to talk to the PHY.
|
||||
SFP_QUIRK_F("FLYPRO", "SFP-10GT-CS-30M", sfp_fixup_rollball),
|
||||
|
||||
|
||||
@@ -406,7 +406,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
|
||||
if (rc || (transferred != sizeof(cmd))) {
|
||||
nfc_err(&phy->udev->dev,
|
||||
"Reader power on cmd error %d\n", rc);
|
||||
return rc;
|
||||
return rc ?: -EINVAL;
|
||||
}
|
||||
|
||||
rc = usb_submit_urb(phy->in_urb, GFP_KERNEL);
|
||||
|
||||
@@ -123,26 +123,14 @@ void inet_frags_fini(struct inet_frags *);
|
||||
|
||||
int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net);
|
||||
|
||||
static inline void fqdir_pre_exit(struct fqdir *fqdir)
|
||||
{
|
||||
/* Prevent creation of new frags.
|
||||
* Pairs with READ_ONCE() in inet_frag_find().
|
||||
*/
|
||||
WRITE_ONCE(fqdir->high_thresh, 0);
|
||||
|
||||
/* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
|
||||
* and ip6frag_expire_frag_queue().
|
||||
*/
|
||||
WRITE_ONCE(fqdir->dead, true);
|
||||
}
|
||||
void fqdir_pre_exit(struct fqdir *fqdir);
|
||||
void fqdir_exit(struct fqdir *fqdir);
|
||||
|
||||
void inet_frag_kill(struct inet_frag_queue *q, int *refs);
|
||||
void inet_frag_destroy(struct inet_frag_queue *q);
|
||||
struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key);
|
||||
|
||||
/* Free all skbs in the queue; return the sum of their truesizes. */
|
||||
unsigned int inet_frag_rbtree_purge(struct rb_root *root,
|
||||
void inet_frag_queue_flush(struct inet_frag_queue *q,
|
||||
enum skb_drop_reason reason);
|
||||
|
||||
static inline void inet_frag_putn(struct inet_frag_queue *q, int refs)
|
||||
|
||||
@@ -69,9 +69,6 @@ ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq)
|
||||
int refs = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
/* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */
|
||||
if (READ_ONCE(fq->q.fqdir->dead))
|
||||
goto out_rcu_unlock;
|
||||
spin_lock(&fq->q.lock);
|
||||
|
||||
if (fq->q.flags & INET_FRAG_COMPLETE)
|
||||
@@ -80,6 +77,12 @@ ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq)
|
||||
fq->q.flags |= INET_FRAG_DROP;
|
||||
inet_frag_kill(&fq->q, &refs);
|
||||
|
||||
/* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */
|
||||
if (READ_ONCE(fq->q.fqdir->dead)) {
|
||||
inet_frag_queue_flush(&fq->q, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = dev_get_by_index_rcu(net, fq->iif);
|
||||
if (!dev)
|
||||
goto out;
|
||||
|
||||
@@ -1091,6 +1091,29 @@ struct nft_rule_blob {
|
||||
__attribute__((aligned(__alignof__(struct nft_rule_dp))));
|
||||
};
|
||||
|
||||
enum nft_chain_types {
|
||||
NFT_CHAIN_T_DEFAULT = 0,
|
||||
NFT_CHAIN_T_ROUTE,
|
||||
NFT_CHAIN_T_NAT,
|
||||
NFT_CHAIN_T_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nft_chain_validate_state - validation state
|
||||
*
|
||||
* If a chain is encountered again during table validation it is
|
||||
* possible to avoid revalidation provided the calling context is
|
||||
* compatible. This structure stores relevant calling context of
|
||||
* previous validations.
|
||||
*
|
||||
* @hook_mask: the hook numbers and locations the chain is linked to
|
||||
* @depth: the deepest call chain level the chain is linked to
|
||||
*/
|
||||
struct nft_chain_validate_state {
|
||||
u8 hook_mask[NFT_CHAIN_T_MAX];
|
||||
u8 depth;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nft_chain - nf_tables chain
|
||||
*
|
||||
@@ -1109,6 +1132,7 @@ struct nft_rule_blob {
|
||||
* @udlen: user data length
|
||||
* @udata: user data in the chain
|
||||
* @blob_next: rule blob pointer to the next in the chain
|
||||
* @vstate: validation state
|
||||
*/
|
||||
struct nft_chain {
|
||||
struct nft_rule_blob __rcu *blob_gen_0;
|
||||
@@ -1128,9 +1152,10 @@ struct nft_chain {
|
||||
|
||||
/* Only used during control plane commit phase: */
|
||||
struct nft_rule_blob *blob_next;
|
||||
struct nft_chain_validate_state vstate;
|
||||
};
|
||||
|
||||
int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain);
|
||||
int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain);
|
||||
int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
struct nft_elem_priv *elem_priv);
|
||||
@@ -1138,13 +1163,6 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set);
|
||||
int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain);
|
||||
void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain);
|
||||
|
||||
enum nft_chain_types {
|
||||
NFT_CHAIN_T_DEFAULT = 0,
|
||||
NFT_CHAIN_T_ROUTE,
|
||||
NFT_CHAIN_T_NAT,
|
||||
NFT_CHAIN_T_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nft_chain_type - nf_tables chain type info
|
||||
*
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/em.yaml */
|
||||
/* YNL-GEN uapi header */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
#ifndef _UAPI_LINUX_ENERGY_MODEL_H
|
||||
#define _UAPI_LINUX_ENERGY_MODEL_H
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define MPTCP_PM_ADDR_FLAG_FULLMESH _BITUL(3)
|
||||
#define MPTCP_PM_ADDR_FLAG_IMPLICIT _BITUL(4)
|
||||
#define MPTCP_PM_ADDR_FLAG_LAMINAR _BITUL(5)
|
||||
#define MPTCP_PM_ADDR_FLAGS_MASK GENMASK(5, 0)
|
||||
|
||||
struct mptcp_info {
|
||||
__u8 mptcpi_subflows;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/em.yaml */
|
||||
/* YNL-GEN kernel source */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/* Do not edit directly, auto-generated from: */
|
||||
/* Documentation/netlink/specs/em.yaml */
|
||||
/* YNL-GEN kernel header */
|
||||
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
||||
|
||||
#ifndef _LINUX_EM_GEN_H
|
||||
#define _LINUX_EM_GEN_H
|
||||
|
||||
@@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
|
||||
len = le16_to_cpu(tmp);
|
||||
|
||||
/* Subtract for FCS on length if FCS is not used. */
|
||||
if (!this->dofcs)
|
||||
if (!this->dofcs) {
|
||||
if (len < 2) {
|
||||
++cffrml_rcv_error;
|
||||
pr_err("Invalid frame length (%d)\n", len);
|
||||
cfpkt_destroy(pkt);
|
||||
return -EPROTO;
|
||||
}
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (cfpkt_setlen(pkt, len) < 0) {
|
||||
++cffrml_rcv_error;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
menuconfig CAN
|
||||
tristate "CAN bus subsystem support"
|
||||
select CAN_DEV
|
||||
help
|
||||
Controller Area Network (CAN) is a slow (up to 1Mbit/s) serial
|
||||
communications protocol. Development of the CAN bus started in
|
||||
|
||||
@@ -482,6 +482,12 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr_unsized *uaddr, in
|
||||
goto out_release_sock;
|
||||
}
|
||||
|
||||
if (ndev->reg_state != NETREG_REGISTERED) {
|
||||
dev_put(ndev);
|
||||
ret = -ENODEV;
|
||||
goto out_release_sock;
|
||||
}
|
||||
|
||||
can_ml = can_get_ml_priv(ndev);
|
||||
if (!can_ml) {
|
||||
dev_put(ndev);
|
||||
|
||||
@@ -1567,6 +1567,8 @@ int j1939_session_activate(struct j1939_session *session)
|
||||
if (active) {
|
||||
j1939_session_put(active);
|
||||
ret = -EAGAIN;
|
||||
} else if (priv->ndev->reg_state != NETREG_REGISTERED) {
|
||||
ret = -ENODEV;
|
||||
} else {
|
||||
WARN_ON_ONCE(session->state != J1939_SESSION_NEW);
|
||||
list_add_tail(&session->active_session_list_entry,
|
||||
|
||||
@@ -2383,6 +2383,9 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
|
||||
return -ENOMEM;
|
||||
WARN_ON_ONCE(!ret);
|
||||
|
||||
if (gstrings.len && gstrings.len != ret)
|
||||
gstrings.len = 0;
|
||||
else
|
||||
gstrings.len = ret;
|
||||
|
||||
if (gstrings.len) {
|
||||
@@ -2509,10 +2512,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
|
||||
if (copy_from_user(&stats, useraddr, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
|
||||
if (stats.n_stats && stats.n_stats != n_stats)
|
||||
stats.n_stats = 0;
|
||||
else
|
||||
stats.n_stats = n_stats;
|
||||
|
||||
if (n_stats) {
|
||||
data = vzalloc(array_size(n_stats, sizeof(u64)));
|
||||
if (stats.n_stats) {
|
||||
data = vzalloc(array_size(stats.n_stats, sizeof(u64)));
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
ops->get_ethtool_stats(dev, &stats, data);
|
||||
@@ -2524,7 +2530,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
|
||||
if (copy_to_user(useraddr, &stats, sizeof(stats)))
|
||||
goto out;
|
||||
useraddr += sizeof(stats);
|
||||
if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64))))
|
||||
if (stats.n_stats &&
|
||||
copy_to_user(useraddr, data,
|
||||
array_size(stats.n_stats, sizeof(u64))))
|
||||
goto out;
|
||||
ret = 0;
|
||||
|
||||
@@ -2560,6 +2568,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev,
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
n_stats = phy_ops->get_sset_count(phydev);
|
||||
if (stats->n_stats && stats->n_stats != n_stats) {
|
||||
stats->n_stats = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ethtool_vzalloc_stats_array(n_stats, data);
|
||||
if (ret)
|
||||
@@ -2580,6 +2592,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev,
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
|
||||
if (stats->n_stats && stats->n_stats != n_stats) {
|
||||
stats->n_stats = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ethtool_vzalloc_stats_array(n_stats, data);
|
||||
if (ret)
|
||||
@@ -2616,7 +2632,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
|
||||
}
|
||||
|
||||
useraddr += sizeof(stats);
|
||||
if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64))))
|
||||
if (stats.n_stats &&
|
||||
copy_to_user(useraddr, data,
|
||||
array_size(stats.n_stats, sizeof(u64))))
|
||||
ret = -EFAULT;
|
||||
|
||||
out:
|
||||
|
||||
@@ -276,6 +276,8 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req,
|
||||
out_unlock:
|
||||
spin_unlock(&hn->hn_lock);
|
||||
out_err:
|
||||
/* Restore original destructor so socket teardown still runs on failure */
|
||||
req->hr_sk->sk_destruct = req->hr_odestruct;
|
||||
trace_handshake_submit_err(net, req, req->hr_sk, ret);
|
||||
handshake_req_destroy(req);
|
||||
return ret;
|
||||
@@ -324,7 +326,11 @@ bool handshake_req_cancel(struct sock *sk)
|
||||
|
||||
hn = handshake_pernet(net);
|
||||
if (hn && remove_pending(hn, req)) {
|
||||
/* Request hadn't been accepted */
|
||||
/* Request hadn't been accepted - mark cancelled */
|
||||
if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
|
||||
trace_handshake_cancel_busy(net, req, sk);
|
||||
return false;
|
||||
}
|
||||
goto out_true;
|
||||
}
|
||||
if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) {
|
||||
|
||||
@@ -205,6 +205,8 @@ struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame,
|
||||
__pskb_copy(frame->skb_prp,
|
||||
skb_headroom(frame->skb_prp),
|
||||
GFP_ATOMIC);
|
||||
if (!frame->skb_std)
|
||||
return NULL;
|
||||
} else {
|
||||
/* Unexpected */
|
||||
WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n",
|
||||
|
||||
@@ -218,6 +218,41 @@ static int __init inet_frag_wq_init(void)
|
||||
|
||||
pure_initcall(inet_frag_wq_init);
|
||||
|
||||
void fqdir_pre_exit(struct fqdir *fqdir)
|
||||
{
|
||||
struct inet_frag_queue *fq;
|
||||
struct rhashtable_iter hti;
|
||||
|
||||
/* Prevent creation of new frags.
|
||||
* Pairs with READ_ONCE() in inet_frag_find().
|
||||
*/
|
||||
WRITE_ONCE(fqdir->high_thresh, 0);
|
||||
|
||||
/* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
|
||||
* and ip6frag_expire_frag_queue().
|
||||
*/
|
||||
WRITE_ONCE(fqdir->dead, true);
|
||||
|
||||
rhashtable_walk_enter(&fqdir->rhashtable, &hti);
|
||||
rhashtable_walk_start(&hti);
|
||||
|
||||
while ((fq = rhashtable_walk_next(&hti))) {
|
||||
if (IS_ERR(fq)) {
|
||||
if (PTR_ERR(fq) != -EAGAIN)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
spin_lock_bh(&fq->lock);
|
||||
if (!(fq->flags & INET_FRAG_COMPLETE))
|
||||
inet_frag_queue_flush(fq, 0);
|
||||
spin_unlock_bh(&fq->lock);
|
||||
}
|
||||
|
||||
rhashtable_walk_stop(&hti);
|
||||
rhashtable_walk_exit(&hti);
|
||||
}
|
||||
EXPORT_SYMBOL(fqdir_pre_exit);
|
||||
|
||||
void fqdir_exit(struct fqdir *fqdir)
|
||||
{
|
||||
INIT_WORK(&fqdir->destroy_work, fqdir_work_fn);
|
||||
@@ -263,8 +298,8 @@ static void inet_frag_destroy_rcu(struct rcu_head *head)
|
||||
kmem_cache_free(f->frags_cachep, q);
|
||||
}
|
||||
|
||||
unsigned int inet_frag_rbtree_purge(struct rb_root *root,
|
||||
enum skb_drop_reason reason)
|
||||
static unsigned int
|
||||
inet_frag_rbtree_purge(struct rb_root *root, enum skb_drop_reason reason)
|
||||
{
|
||||
struct rb_node *p = rb_first(root);
|
||||
unsigned int sum = 0;
|
||||
@@ -284,7 +319,17 @@ unsigned int inet_frag_rbtree_purge(struct rb_root *root,
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_rbtree_purge);
|
||||
|
||||
void inet_frag_queue_flush(struct inet_frag_queue *q,
|
||||
enum skb_drop_reason reason)
|
||||
{
|
||||
unsigned int sum;
|
||||
|
||||
reason = reason ?: SKB_DROP_REASON_FRAG_REASM_TIMEOUT;
|
||||
sum = inet_frag_rbtree_purge(&q->rb_fragments, reason);
|
||||
sub_frag_mem_limit(q->fqdir, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_queue_flush);
|
||||
|
||||
void inet_frag_destroy(struct inet_frag_queue *q)
|
||||
{
|
||||
@@ -327,7 +372,9 @@ static struct inet_frag_queue *inet_frag_alloc(struct fqdir *fqdir,
|
||||
|
||||
timer_setup(&q->timer, f->frag_expire, 0);
|
||||
spin_lock_init(&q->lock);
|
||||
/* One reference for the timer, one for the hash table. */
|
||||
/* One reference for the timer, one for the hash table.
|
||||
* We never take any extra references, only decrement this field.
|
||||
*/
|
||||
refcount_set(&q->refcnt, 2);
|
||||
|
||||
return q;
|
||||
|
||||
@@ -134,11 +134,6 @@ static void ip_expire(struct timer_list *t)
|
||||
net = qp->q.fqdir->net;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
/* Paired with WRITE_ONCE() in fqdir_pre_exit(). */
|
||||
if (READ_ONCE(qp->q.fqdir->dead))
|
||||
goto out_rcu_unlock;
|
||||
|
||||
spin_lock(&qp->q.lock);
|
||||
|
||||
if (qp->q.flags & INET_FRAG_COMPLETE)
|
||||
@@ -146,6 +141,13 @@ static void ip_expire(struct timer_list *t)
|
||||
|
||||
qp->q.flags |= INET_FRAG_DROP;
|
||||
inet_frag_kill(&qp->q, &refs);
|
||||
|
||||
/* Paired with WRITE_ONCE() in fqdir_pre_exit(). */
|
||||
if (READ_ONCE(qp->q.fqdir->dead)) {
|
||||
inet_frag_queue_flush(&qp->q, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
__IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
|
||||
__IP_INC_STATS(net, IPSTATS_MIB_REASMTIMEOUT);
|
||||
|
||||
@@ -240,16 +242,10 @@ static int ip_frag_too_far(struct ipq *qp)
|
||||
|
||||
static int ip_frag_reinit(struct ipq *qp)
|
||||
{
|
||||
unsigned int sum_truesize = 0;
|
||||
|
||||
if (!mod_timer(&qp->q.timer, jiffies + qp->q.fqdir->timeout)) {
|
||||
refcount_inc(&qp->q.refcnt);
|
||||
if (!mod_timer_pending(&qp->q.timer, jiffies + qp->q.fqdir->timeout))
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
sum_truesize = inet_frag_rbtree_purge(&qp->q.rb_fragments,
|
||||
SKB_DROP_REASON_FRAG_TOO_FAR);
|
||||
sub_frag_mem_limit(qp->q.fqdir, sum_truesize);
|
||||
inet_frag_queue_flush(&qp->q, SKB_DROP_REASON_FRAG_TOO_FAR);
|
||||
|
||||
qp->q.flags = 0;
|
||||
qp->q.len = 0;
|
||||
|
||||
@@ -4,7 +4,7 @@ config MPTCP
|
||||
depends on INET
|
||||
select SKB_EXTENSIONS
|
||||
select CRYPTO_LIB_SHA256
|
||||
select CRYPTO
|
||||
select CRYPTO_LIB_UTILS
|
||||
help
|
||||
Multipath TCP (MPTCP) connections send and receive data over multiple
|
||||
subflows in order to utilize multiple network paths. Each subflow
|
||||
|
||||
@@ -119,7 +119,8 @@ int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
|
||||
}
|
||||
|
||||
if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
|
||||
entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);
|
||||
entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]) &
|
||||
MPTCP_PM_ADDR_FLAGS_MASK;
|
||||
|
||||
if (tb[MPTCP_PM_ADDR_ATTR_PORT])
|
||||
entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
|
||||
|
||||
@@ -1623,7 +1623,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
|
||||
struct mptcp_sendmsg_info info = {
|
||||
.flags = flags,
|
||||
};
|
||||
bool do_check_data_fin = false;
|
||||
bool copied = false;
|
||||
int push_count = 1;
|
||||
|
||||
while (mptcp_send_head(sk) && (push_count > 0)) {
|
||||
@@ -1665,7 +1665,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
|
||||
push_count--;
|
||||
continue;
|
||||
}
|
||||
do_check_data_fin = true;
|
||||
copied = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1674,12 +1674,15 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
|
||||
if (ssk)
|
||||
mptcp_push_release(ssk, &info);
|
||||
|
||||
/* ensure the rtx timer is running */
|
||||
/* Avoid scheduling the rtx timer if no data has been pushed; the timer
|
||||
* will be updated on positive acks by __mptcp_cleanup_una().
|
||||
*/
|
||||
if (copied) {
|
||||
if (!mptcp_rtx_timer_pending(sk))
|
||||
mptcp_reset_rtx_timer(sk);
|
||||
if (do_check_data_fin)
|
||||
mptcp_check_send_data_fin(sk);
|
||||
}
|
||||
}
|
||||
|
||||
static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool first)
|
||||
{
|
||||
@@ -2766,10 +2769,13 @@ static void __mptcp_retrans(struct sock *sk)
|
||||
|
||||
/*
|
||||
* make the whole retrans decision, xmit, disallow
|
||||
* fallback atomic
|
||||
* fallback atomic, note that we can't retrans even
|
||||
* when an infinite fallback is in progress, i.e. new
|
||||
* subflows are disallowed.
|
||||
*/
|
||||
spin_lock_bh(&msk->fallback_lock);
|
||||
if (__mptcp_check_fallback(msk)) {
|
||||
if (__mptcp_check_fallback(msk) ||
|
||||
!msk->allow_subflows) {
|
||||
spin_unlock_bh(&msk->fallback_lock);
|
||||
release_sock(ssk);
|
||||
goto clear_scheduled;
|
||||
|
||||
@@ -408,6 +408,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
|
||||
return -1;
|
||||
|
||||
err_unreach:
|
||||
if (!skb->dev)
|
||||
skb->dev = skb_dst(skb)->dev;
|
||||
|
||||
dst_link_failure(skb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
|
||||
struct nf_conn *found_ct;
|
||||
unsigned int collect = 0;
|
||||
bool refcounted = false;
|
||||
int err = 0;
|
||||
|
||||
if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
|
||||
return -ENOENT;
|
||||
|
||||
if (ct && nf_ct_is_confirmed(ct)) {
|
||||
if (refcounted)
|
||||
nf_ct_put(ct);
|
||||
return -EEXIST;
|
||||
err = -EEXIST;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
if ((u32)jiffies == list->last_gc)
|
||||
@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
|
||||
}
|
||||
|
||||
add_new_node:
|
||||
if (WARN_ON_ONCE(list->count > INT_MAX))
|
||||
return -EOVERFLOW;
|
||||
if (WARN_ON_ONCE(list->count > INT_MAX)) {
|
||||
err = -EOVERFLOW;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
|
||||
if (conn == NULL)
|
||||
return -ENOMEM;
|
||||
if (conn == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
conn->tuple = tuple;
|
||||
conn->zone = *zone;
|
||||
@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
|
||||
out_put:
|
||||
if (refcounted)
|
||||
nf_ct_put(ct);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
int nf_conncount_add_skb(struct net *net,
|
||||
@@ -456,11 +460,10 @@ insert_tree(struct net *net,
|
||||
|
||||
rb_link_node_rcu(&rbconn->node, parent, rbnode);
|
||||
rb_insert_color(&rbconn->node, root);
|
||||
|
||||
if (refcounted)
|
||||
nf_ct_put(ct);
|
||||
}
|
||||
out_unlock:
|
||||
if (refcounted)
|
||||
nf_ct_put(ct);
|
||||
spin_unlock_bh(&nf_conncount_locks[hash]);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -2487,6 +2487,7 @@ void nf_conntrack_cleanup_net(struct net *net)
|
||||
void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list)
|
||||
{
|
||||
struct nf_ct_iter_data iter_data = {};
|
||||
unsigned long start = jiffies;
|
||||
struct net *net;
|
||||
int busy;
|
||||
|
||||
@@ -2507,6 +2508,8 @@ void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list)
|
||||
busy = 1;
|
||||
}
|
||||
if (busy) {
|
||||
DEBUG_NET_WARN_ONCE(time_after(jiffies, start + 60 * HZ),
|
||||
"conntrack cleanup blocked for 60s");
|
||||
schedule();
|
||||
goto i_see_dead_people;
|
||||
}
|
||||
|
||||
@@ -250,6 +250,9 @@ static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
|
||||
if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
|
||||
nft_dev_path_info(&stack, &info, ha, &ft->data);
|
||||
|
||||
if (info.outdev)
|
||||
route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||
|
||||
if (!info.indev || !nft_flowtable_find_dev(info.indev, ft))
|
||||
return;
|
||||
|
||||
@@ -269,7 +272,6 @@ static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
|
||||
|
||||
route->tuple[!dir].in.num_encaps = info.num_encaps;
|
||||
route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
|
||||
route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||
|
||||
if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
|
||||
memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
|
||||
|
||||
@@ -294,25 +294,13 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
|
||||
|
||||
ct = nf_ct_tuplehash_to_ctrack(thash);
|
||||
|
||||
/* NB: IP_CT_DIR_ORIGINAL should be impossible because
|
||||
* nf_nat_used_tuple() handles origin collisions.
|
||||
*
|
||||
* Handle remote chance other CPU confirmed its ct right after.
|
||||
*/
|
||||
if (thash->tuple.dst.dir != IP_CT_DIR_REPLY)
|
||||
goto out;
|
||||
|
||||
/* clashing connection subject to NAT? Retry with new tuple. */
|
||||
if (READ_ONCE(ct->status) & uses_nat)
|
||||
goto out;
|
||||
|
||||
if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
|
||||
&ignored_ct->tuplehash[IP_CT_DIR_REPLY].tuple) &&
|
||||
nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
|
||||
&ignored_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)) {
|
||||
&ignored_ct->tuplehash[IP_CT_DIR_REPLY].tuple))
|
||||
taken = false;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
nf_ct_put(ct);
|
||||
return taken;
|
||||
|
||||
@@ -123,6 +123,29 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s
|
||||
|
||||
table->validate_state = new_validate_state;
|
||||
}
|
||||
|
||||
static bool nft_chain_vstate_valid(const struct nft_ctx *ctx,
|
||||
const struct nft_chain *chain)
|
||||
{
|
||||
const struct nft_base_chain *base_chain;
|
||||
enum nft_chain_types type;
|
||||
u8 hooknum;
|
||||
|
||||
if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
|
||||
return false;
|
||||
|
||||
base_chain = nft_base_chain(ctx->chain);
|
||||
hooknum = base_chain->ops.hooknum;
|
||||
type = base_chain->type->type;
|
||||
|
||||
/* chain is already validated for this call depth */
|
||||
if (chain->vstate.depth >= ctx->level &&
|
||||
chain->vstate.hook_mask[type] & BIT(hooknum))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nf_tables_trans_destroy_work(struct work_struct *w);
|
||||
|
||||
static void nft_trans_gc_work(struct work_struct *work);
|
||||
@@ -4079,6 +4102,29 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r
|
||||
nf_tables_rule_destroy(ctx, rule);
|
||||
}
|
||||
|
||||
static void nft_chain_vstate_update(const struct nft_ctx *ctx, struct nft_chain *chain)
|
||||
{
|
||||
const struct nft_base_chain *base_chain;
|
||||
enum nft_chain_types type;
|
||||
u8 hooknum;
|
||||
|
||||
/* ctx->chain must hold the calling base chain. */
|
||||
if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) {
|
||||
memset(&chain->vstate, 0, sizeof(chain->vstate));
|
||||
return;
|
||||
}
|
||||
|
||||
base_chain = nft_base_chain(ctx->chain);
|
||||
hooknum = base_chain->ops.hooknum;
|
||||
type = base_chain->type->type;
|
||||
|
||||
BUILD_BUG_ON(BIT(NF_INET_NUMHOOKS) > U8_MAX);
|
||||
|
||||
chain->vstate.hook_mask[type] |= BIT(hooknum);
|
||||
if (chain->vstate.depth < ctx->level)
|
||||
chain->vstate.depth = ctx->level;
|
||||
}
|
||||
|
||||
/** nft_chain_validate - loop detection and hook validation
|
||||
*
|
||||
* @ctx: context containing call depth and base chain
|
||||
@@ -4088,15 +4134,25 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r
|
||||
* and set lookups until either the jump limit is hit or all reachable
|
||||
* chains have been validated.
|
||||
*/
|
||||
int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
|
||||
int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain)
|
||||
{
|
||||
struct nft_expr *expr, *last;
|
||||
struct nft_rule *rule;
|
||||
int err;
|
||||
|
||||
BUILD_BUG_ON(NFT_JUMP_STACK_SIZE > 255);
|
||||
if (ctx->level == NFT_JUMP_STACK_SIZE)
|
||||
return -EMLINK;
|
||||
|
||||
if (ctx->level > 0) {
|
||||
/* jumps to base chains are not allowed. */
|
||||
if (nft_is_base_chain(chain))
|
||||
return -ELOOP;
|
||||
|
||||
if (nft_chain_vstate_valid(ctx, chain))
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_for_each_entry(rule, &chain->rules, list) {
|
||||
if (fatal_signal_pending(current))
|
||||
return -EINTR;
|
||||
@@ -4115,8 +4171,11 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
nft_chain_vstate_update(ctx, chain);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_chain_validate);
|
||||
@@ -4128,7 +4187,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table)
|
||||
.net = net,
|
||||
.family = table->family,
|
||||
};
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
list_for_each_entry(chain, &table->chains, list) {
|
||||
if (!nft_is_base_chain(chain))
|
||||
@@ -4137,12 +4196,14 @@ static int nft_table_validate(struct net *net, const struct nft_table *table)
|
||||
ctx.chain = chain;
|
||||
err = nft_chain_validate(&ctx, chain);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cond_resched();
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
list_for_each_entry(chain, &table->chains, list)
|
||||
memset(&chain->vstate, 0, sizeof(chain->vstate));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
@@ -11676,21 +11737,10 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
enum nft_data_types type,
|
||||
unsigned int len)
|
||||
{
|
||||
int err;
|
||||
|
||||
switch (reg) {
|
||||
case NFT_REG_VERDICT:
|
||||
if (type != NFT_DATA_VERDICT)
|
||||
return -EINVAL;
|
||||
|
||||
if (data != NULL &&
|
||||
(data->verdict.code == NFT_GOTO ||
|
||||
data->verdict.code == NFT_JUMP)) {
|
||||
err = nft_chain_validate(ctx, data->verdict.chain);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if (type != NFT_DATA_VALUE)
|
||||
|
||||
@@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
|
||||
frontlen = skb_headroom(skb);
|
||||
|
||||
while (skb->len > 0) {
|
||||
if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL)
|
||||
if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
skb_reserve(skbn, frontlen);
|
||||
|
||||
|
||||
@@ -2802,13 +2802,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool validate_push_nsh(const struct nlattr *attr, bool log)
|
||||
static bool validate_push_nsh(const struct nlattr *a, bool log)
|
||||
{
|
||||
struct nlattr *nsh_key = nla_data(a);
|
||||
struct sw_flow_match match;
|
||||
struct sw_flow_key key;
|
||||
|
||||
/* There must be one and only one NSH header. */
|
||||
if (!nla_ok(nsh_key, nla_len(a)) ||
|
||||
nla_total_size(nla_len(nsh_key)) != nla_len(a) ||
|
||||
nla_type(nsh_key) != OVS_KEY_ATTR_NSH)
|
||||
return false;
|
||||
|
||||
ovs_match_init(&match, &key, true, NULL);
|
||||
return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
|
||||
return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log);
|
||||
}
|
||||
|
||||
/* Return false if there are any non-masked bits set.
|
||||
@@ -3389,7 +3396,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
|
||||
return -EINVAL;
|
||||
}
|
||||
mac_proto = MAC_PROTO_NONE;
|
||||
if (!validate_push_nsh(nla_data(a), log))
|
||||
if (!validate_push_nsh(a, log))
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
||||
|
||||
@@ -281,6 +281,15 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
|
||||
|
||||
want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
|
||||
|
||||
if (dev == skb->dev && want_ingress == at_ingress) {
|
||||
pr_notice_once("tc mirred: Loop (%s:%s --> %s:%s)\n",
|
||||
netdev_name(skb->dev),
|
||||
at_ingress ? "ingress" : "egress",
|
||||
netdev_name(dev),
|
||||
want_ingress ? "ingress" : "egress");
|
||||
goto err_cant_do;
|
||||
}
|
||||
|
||||
/* All mirred/redirected skbs should clear previous ct info */
|
||||
nf_reset_ct(skb_to_send);
|
||||
if (want_ingress && !at_ingress) /* drop dst for egress -> ingress */
|
||||
|
||||
@@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
sch_tree_lock(sch);
|
||||
|
||||
for (i = nbands; i < oldbands; i++) {
|
||||
if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
|
||||
if (cl_is_active(&q->classes[i]))
|
||||
list_del_init(&q->classes[i].alist);
|
||||
qdisc_purge_queue(q->classes[i].qdisc);
|
||||
}
|
||||
@@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
q->classes[i].deficit = quanta[i];
|
||||
}
|
||||
}
|
||||
for (i = q->nstrict; i < nstrict; i++) {
|
||||
if (cl_is_active(&q->classes[i]))
|
||||
list_del_init(&q->classes[i].alist);
|
||||
}
|
||||
WRITE_ONCE(q->nstrict, nstrict);
|
||||
memcpy(q->prio2band, priomap, sizeof(priomap));
|
||||
|
||||
|
||||
@@ -492,6 +492,8 @@ static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
|
||||
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
|
||||
struct ipv6_txoptions *opt;
|
||||
|
||||
inet_sk(newsk)->inet_opt = NULL;
|
||||
|
||||
newnp = inet6_sk(newsk);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
@@ -4863,8 +4863,6 @@ static struct sock *sctp_clone_sock(struct sock *sk,
|
||||
|
||||
newsp->pf->to_sk_daddr(&asoc->peer.primary_addr, newsk);
|
||||
newinet->inet_dport = htons(asoc->peer.port);
|
||||
|
||||
newsp->pf->copy_ip_options(sk, newsk);
|
||||
atomic_set(&newinet->inet_id, get_random_u16());
|
||||
|
||||
inet_set_bit(MC_LOOP, newsk);
|
||||
@@ -4874,17 +4872,20 @@ static struct sock *sctp_clone_sock(struct sock *sk,
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (sk->sk_family == AF_INET6) {
|
||||
struct ipv6_pinfo *newnp = inet6_sk(newsk);
|
||||
struct ipv6_pinfo *newnp;
|
||||
|
||||
newinet->pinet6 = &((struct sctp6_sock *)newsk)->inet6;
|
||||
newinet->ipv6_fl_list = NULL;
|
||||
|
||||
newnp = inet6_sk(newsk);
|
||||
memcpy(newnp, inet6_sk(sk), sizeof(struct ipv6_pinfo));
|
||||
newnp->ipv6_mc_list = NULL;
|
||||
newnp->ipv6_ac_list = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
newsp->pf->copy_ip_options(sk, newsk);
|
||||
|
||||
newsp->do_auto_asconf = 0;
|
||||
skb_queue_head_init(&newsp->pd_lobby);
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ static void unix_free_vertices(struct scm_fp_list *fpl)
|
||||
}
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(unix_gc_lock);
|
||||
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(unix_gc_lock);
|
||||
|
||||
void unix_add_edges(struct scm_fp_list *fpl, struct unix_sock *receiver)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ UAPI_PATH:=../../../../include/uapi/
|
||||
# need the explicit -D matching what's in /usr, to avoid multiple definitions.
|
||||
|
||||
get_hdr_inc=-D$(1) -include $(UAPI_PATH)/linux/$(2)
|
||||
get_hdr_inc2=-D$(1) -D$(2) -include $(UAPI_PATH)/linux/$(3)
|
||||
|
||||
CFLAGS_devlink:=$(call get_hdr_inc,_LINUX_DEVLINK_H_,devlink.h)
|
||||
CFLAGS_dpll:=$(call get_hdr_inc,_LINUX_DPLL_H,dpll.h)
|
||||
@@ -48,3 +49,4 @@ CFLAGS_tc:= $(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h) \
|
||||
$(call get_hdr_inc,_TC_SKBEDIT_H,tc_act/tc_skbedit.h) \
|
||||
$(call get_hdr_inc,_TC_TUNNEL_KEY_H,tc_act/tc_tunnel_key.h)
|
||||
CFLAGS_tcp_metrics:=$(call get_hdr_inc,_LINUX_TCP_METRICS_H,tcp_metrics.h)
|
||||
CFLAGS_wireguard:=$(call get_hdr_inc2,_LINUX_WIREGUARD_H,_WG_UAPI_WIREGUARD_H,wireguard.h)
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
CFLAGS += $(KHDR_INCLUDES) -Wall -Wflex-array-member-not-at-end
|
||||
top_srcdir := ../../../../..
|
||||
include $(top_srcdir)/scripts/Makefile.compiler
|
||||
|
||||
cc-option = $(call __cc-option, $(CC),,$(1),$(2))
|
||||
|
||||
CFLAGS += $(KHDR_INCLUDES) -Wall $(call cc-option,-Wflex-array-member-not-at-end)
|
||||
|
||||
TEST_GEN_PROGS := \
|
||||
diag_uid \
|
||||
|
||||
@@ -29,6 +29,7 @@ CONFIG_NET_ACT_VLAN=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_FLOWER=m
|
||||
CONFIG_NET_CLS_MATCHALL=m
|
||||
CONFIG_NET_CLS_U32=m
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_META=m
|
||||
CONFIG_NETFILTER=y
|
||||
|
||||
@@ -138,12 +138,17 @@ install_capture()
|
||||
defer tc qdisc del dev "$dev" clsact
|
||||
|
||||
tc filter add dev "$dev" ingress proto ip pref 104 \
|
||||
flower skip_hw ip_proto udp dst_port "$VXPORT" \
|
||||
u32 match ip protocol 0x11 0xff \
|
||||
match u16 "$VXPORT" 0xffff at 0x16 \
|
||||
match u16 0x0800 0xffff at 0x30 \
|
||||
action pass
|
||||
defer tc filter del dev "$dev" ingress proto ip pref 104
|
||||
|
||||
tc filter add dev "$dev" ingress proto ipv6 pref 106 \
|
||||
flower skip_hw ip_proto udp dst_port "$VXPORT" \
|
||||
u32 match ip6 protocol 0x11 0xff \
|
||||
match u16 "$VXPORT" 0xffff at 0x2a \
|
||||
match u16 0x86dd 0xffff at 0x44 \
|
||||
match u8 0x11 0xff at 0x4c \
|
||||
action pass
|
||||
defer tc filter del dev "$dev" ingress proto ipv6 pref 106
|
||||
}
|
||||
@@ -248,13 +253,6 @@ vx_create()
|
||||
}
|
||||
export -f vx_create
|
||||
|
||||
vx_wait()
|
||||
{
|
||||
# Wait for all the ARP, IGMP etc. noise to settle down so that the
|
||||
# tunnel is clear for measurements.
|
||||
sleep 10
|
||||
}
|
||||
|
||||
vx10_create()
|
||||
{
|
||||
vx_create vx10 10 id 1000 "$@"
|
||||
@@ -267,18 +265,6 @@ vx20_create()
|
||||
}
|
||||
export -f vx20_create
|
||||
|
||||
vx10_create_wait()
|
||||
{
|
||||
vx10_create "$@"
|
||||
vx_wait
|
||||
}
|
||||
|
||||
vx20_create_wait()
|
||||
{
|
||||
vx20_create "$@"
|
||||
vx_wait
|
||||
}
|
||||
|
||||
ns_init_common()
|
||||
{
|
||||
local ns=$1; shift
|
||||
@@ -554,7 +540,7 @@ ipv4_nomcroute()
|
||||
# Install a misleading (S,G) rule to attempt to trick the system into
|
||||
# pushing the packets elsewhere.
|
||||
adf_install_broken_sg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$swp2"
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$swp2"
|
||||
do_test 4 10 0 "IPv4 nomcroute"
|
||||
}
|
||||
|
||||
@@ -562,7 +548,7 @@ ipv6_nomcroute()
|
||||
{
|
||||
# Like for IPv4, install a misleading (S,G).
|
||||
adf_install_broken_sg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$swp2"
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$swp2"
|
||||
do_test 6 10 0 "IPv6 nomcroute"
|
||||
}
|
||||
|
||||
@@ -581,35 +567,35 @@ ipv6_nomcroute_rx()
|
||||
ipv4_mcroute()
|
||||
{
|
||||
adf_install_sg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
do_test 4 10 10 "IPv4 mcroute"
|
||||
}
|
||||
|
||||
ipv6_mcroute()
|
||||
{
|
||||
adf_install_sg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
do_test 6 10 10 "IPv6 mcroute"
|
||||
}
|
||||
|
||||
ipv4_mcroute_rx()
|
||||
{
|
||||
adf_install_sg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
ipv4_do_test_rx 0 "IPv4 mcroute ping"
|
||||
}
|
||||
|
||||
ipv6_mcroute_rx()
|
||||
{
|
||||
adf_install_sg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
ipv6_do_test_rx 0 "IPv6 mcroute ping"
|
||||
}
|
||||
|
||||
ipv4_mcroute_changelink()
|
||||
{
|
||||
adf_install_sg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR"
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR"
|
||||
ip link set dev vx10 type vxlan mcroute
|
||||
sleep 1
|
||||
do_test 4 10 10 "IPv4 mcroute changelink"
|
||||
@@ -618,7 +604,7 @@ ipv4_mcroute_changelink()
|
||||
ipv6_mcroute_changelink()
|
||||
{
|
||||
adf_install_sg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
ip link set dev vx20 type vxlan mcroute
|
||||
sleep 1
|
||||
do_test 6 10 10 "IPv6 mcroute changelink"
|
||||
@@ -627,47 +613,47 @@ ipv6_mcroute_changelink()
|
||||
ipv4_mcroute_starg()
|
||||
{
|
||||
adf_install_starg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
do_test 4 10 10 "IPv4 mcroute (*,G)"
|
||||
}
|
||||
|
||||
ipv6_mcroute_starg()
|
||||
{
|
||||
adf_install_starg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
do_test 6 10 10 "IPv6 mcroute (*,G)"
|
||||
}
|
||||
|
||||
ipv4_mcroute_starg_rx()
|
||||
{
|
||||
adf_install_starg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
ipv4_do_test_rx 0 "IPv4 mcroute (*,G) ping"
|
||||
}
|
||||
|
||||
ipv6_mcroute_starg_rx()
|
||||
{
|
||||
adf_install_starg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
ipv6_do_test_rx 0 "IPv6 mcroute (*,G) ping"
|
||||
}
|
||||
|
||||
ipv4_mcroute_noroute()
|
||||
{
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
do_test 4 0 0 "IPv4 mcroute, no route"
|
||||
}
|
||||
|
||||
ipv6_mcroute_noroute()
|
||||
{
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
do_test 6 0 0 "IPv6 mcroute, no route"
|
||||
}
|
||||
|
||||
ipv4_mcroute_fdb()
|
||||
{
|
||||
adf_install_sg
|
||||
vx10_create_wait local 192.0.2.100 dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 dev "$IPMR" mcroute
|
||||
bridge fdb add dev vx10 \
|
||||
00:00:00:00:00:00 self static dst "$GROUP4" via "$IPMR"
|
||||
do_test 4 10 10 "IPv4 mcroute FDB"
|
||||
@@ -676,7 +662,7 @@ ipv4_mcroute_fdb()
|
||||
ipv6_mcroute_fdb()
|
||||
{
|
||||
adf_install_sg
|
||||
vx20_create_wait local 2001:db8:4::1 dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 dev "$IPMR" mcroute
|
||||
bridge -6 fdb add dev vx20 \
|
||||
00:00:00:00:00:00 self static dst "$GROUP6" via "$IPMR"
|
||||
do_test 6 10 10 "IPv6 mcroute FDB"
|
||||
@@ -686,7 +672,7 @@ ipv6_mcroute_fdb()
|
||||
ipv4_mcroute_fdb_oif0()
|
||||
{
|
||||
adf_install_sg
|
||||
vx10_create_wait local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.100 group "$GROUP4" dev "$IPMR" mcroute
|
||||
bridge fdb del dev vx10 00:00:00:00:00:00
|
||||
bridge fdb add dev vx10 00:00:00:00:00:00 self static dst "$GROUP4"
|
||||
do_test 4 10 10 "IPv4 mcroute oif=0"
|
||||
@@ -703,7 +689,7 @@ ipv6_mcroute_fdb_oif0()
|
||||
defer ip -6 route del table local multicast "$GROUP6/128" dev "$IPMR"
|
||||
|
||||
adf_install_sg
|
||||
vx20_create_wait local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:4::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
bridge -6 fdb del dev vx20 00:00:00:00:00:00
|
||||
bridge -6 fdb add dev vx20 00:00:00:00:00:00 self static dst "$GROUP6"
|
||||
do_test 6 10 10 "IPv6 mcroute oif=0"
|
||||
@@ -716,7 +702,7 @@ ipv4_mcroute_fdb_oif0_sep()
|
||||
adf_install_sg_sep
|
||||
|
||||
adf_ip_addr_add lo 192.0.2.120/28
|
||||
vx10_create_wait local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
|
||||
bridge fdb del dev vx10 00:00:00:00:00:00
|
||||
bridge fdb add dev vx10 00:00:00:00:00:00 self static dst "$GROUP4"
|
||||
do_test 4 10 10 "IPv4 mcroute TX!=RX oif=0"
|
||||
@@ -727,7 +713,7 @@ ipv4_mcroute_fdb_oif0_sep_rx()
|
||||
adf_install_sg_sep_rx lo
|
||||
|
||||
adf_ip_addr_add lo 192.0.2.120/28
|
||||
vx10_create_wait local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
|
||||
bridge fdb del dev vx10 00:00:00:00:00:00
|
||||
bridge fdb add dev vx10 00:00:00:00:00:00 self static dst "$GROUP4"
|
||||
ipv4_do_test_rx 0 "IPv4 mcroute TX!=RX oif=0 ping"
|
||||
@@ -738,7 +724,7 @@ ipv4_mcroute_fdb_sep_rx()
|
||||
adf_install_sg_sep_rx lo
|
||||
|
||||
adf_ip_addr_add lo 192.0.2.120/28
|
||||
vx10_create_wait local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
|
||||
vx10_create local 192.0.2.120 group "$GROUP4" dev "$IPMR" mcroute
|
||||
bridge fdb del dev vx10 00:00:00:00:00:00
|
||||
bridge fdb add \
|
||||
dev vx10 00:00:00:00:00:00 self static dst "$GROUP4" via lo
|
||||
@@ -750,7 +736,7 @@ ipv6_mcroute_fdb_sep_rx()
|
||||
adf_install_sg_sep_rx "X$IPMR"
|
||||
|
||||
adf_ip_addr_add "X$IPMR" 2001:db8:5::1/64
|
||||
vx20_create_wait local 2001:db8:5::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
vx20_create local 2001:db8:5::1 group "$GROUP6" dev "$IPMR" mcroute
|
||||
bridge -6 fdb del dev vx20 00:00:00:00:00:00
|
||||
bridge -6 fdb add dev vx20 00:00:00:00:00:00 \
|
||||
self static dst "$GROUP6" via "X$IPMR"
|
||||
|
||||
@@ -280,7 +280,8 @@ tc_rule_stats_get()
|
||||
local selector=${1:-.packets}; shift
|
||||
|
||||
tc -j -s filter show dev $dev $dir pref $pref \
|
||||
| jq ".[1].options.actions[].stats$selector"
|
||||
| jq ".[] | select(.options.actions) |
|
||||
.options.actions[].stats$selector"
|
||||
}
|
||||
|
||||
tc_rule_handle_stats_get()
|
||||
|
||||
@@ -24,7 +24,8 @@ static inline void ksft_ready(void)
|
||||
fd = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
write(fd, msg, sizeof(msg));
|
||||
if (write(fd, msg, sizeof(msg)) < 0)
|
||||
perror("write()");
|
||||
if (fd != STDOUT_FILENO)
|
||||
close(fd);
|
||||
}
|
||||
@@ -48,7 +49,8 @@ static inline void ksft_wait(void)
|
||||
fd = STDIN_FILENO;
|
||||
}
|
||||
|
||||
read(fd, &byte, sizeof(byte));
|
||||
if (read(fd, &byte, sizeof(byte)) < 0)
|
||||
perror("read()");
|
||||
if (fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -192,6 +192,10 @@ check "show_endpoints" \
|
||||
flush_endpoint
|
||||
check "show_endpoints" "" "flush addrs"
|
||||
|
||||
add_endpoint 10.0.1.1 flags unknown
|
||||
check "show_endpoints" "$(format_endpoints "1,10.0.1.1")" "ignore unknown flags"
|
||||
flush_endpoint
|
||||
|
||||
set_limits 9 1 2>/dev/null
|
||||
check "get_limits" "${default_limits}" "rcv addrs above hard limit"
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#define IPPROTO_MPTCP 262
|
||||
#endif
|
||||
|
||||
#define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7)
|
||||
|
||||
static void syntax(char *argv[])
|
||||
{
|
||||
fprintf(stderr, "%s add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept [<args>]\n", argv[0]);
|
||||
@@ -836,6 +838,8 @@ int add_addr(int fd, int pm_family, int argc, char *argv[])
|
||||
flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
|
||||
else if (!strcmp(tok, "fullmesh"))
|
||||
flags |= MPTCP_PM_ADDR_FLAG_FULLMESH;
|
||||
else if (!strcmp(tok, "unknown"))
|
||||
flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN;
|
||||
else
|
||||
error(1, errno,
|
||||
"unknown flag %s", argv[arg]);
|
||||
@@ -1048,6 +1052,13 @@ static void print_addr(struct rtattr *attrs, int len)
|
||||
printf(",");
|
||||
}
|
||||
|
||||
if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) {
|
||||
printf("unknown");
|
||||
flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN;
|
||||
if (flags)
|
||||
printf(",");
|
||||
}
|
||||
|
||||
/* bump unknown flags, if any */
|
||||
if (flags)
|
||||
printf("0x%x", flags);
|
||||
|
||||
@@ -116,7 +116,7 @@ run_one_clash_test()
|
||||
# not a failure: clash resolution logic did not trigger.
|
||||
# With right timing, xmit completed sequentially and
|
||||
# no parallel insertion occurs.
|
||||
return $ksft_skip
|
||||
return $ksft_xfail
|
||||
}
|
||||
|
||||
run_clash_test()
|
||||
@@ -133,12 +133,12 @@ run_clash_test()
|
||||
if [ $rv -eq 0 ];then
|
||||
echo "PASS: clash resolution test for $daddr:$dport on attempt $i"
|
||||
return 0
|
||||
elif [ $rv -eq $ksft_skip ]; then
|
||||
elif [ $rv -eq $ksft_xfail ]; then
|
||||
softerr=1
|
||||
fi
|
||||
done
|
||||
|
||||
[ $softerr -eq 1 ] && echo "SKIP: clash resolution for $daddr:$dport did not trigger"
|
||||
[ $softerr -eq 1 ] && echo "XFAIL: clash resolution for $daddr:$dport did not trigger"
|
||||
}
|
||||
|
||||
ip link add veth0 netns "$nsclient1" type veth peer name veth0 netns "$nsrouter"
|
||||
@@ -167,8 +167,7 @@ load_simple_ruleset "$nsclient2"
|
||||
run_clash_test "$nsclient2" "$nsclient2" 127.0.0.1 9001
|
||||
|
||||
if [ $clash_resolution_active -eq 0 ];then
|
||||
[ "$ret" -eq 0 ] && ret=$ksft_skip
|
||||
echo "SKIP: Clash resolution did not trigger"
|
||||
[ "$ret" -eq 0 ] && ret=$ksft_xfail
|
||||
fi
|
||||
|
||||
exit $ret
|
||||
|
||||
@@ -33,9 +33,14 @@ static void die(const char *e)
|
||||
exit(111);
|
||||
}
|
||||
|
||||
static void die_port(uint16_t got, uint16_t want)
|
||||
static void die_port(const struct sockaddr_in *sin, uint16_t want)
|
||||
{
|
||||
fprintf(stderr, "Port number changed, wanted %d got %d\n", want, ntohs(got));
|
||||
uint16_t got = ntohs(sin->sin_port);
|
||||
char str[INET_ADDRSTRLEN];
|
||||
|
||||
inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
|
||||
|
||||
fprintf(stderr, "Port number changed, wanted %d got %d from %s\n", want, got, str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -100,7 +105,7 @@ int main(int argc, char *argv[])
|
||||
die("child recvfrom");
|
||||
|
||||
if (peer.sin_port != htons(PORT))
|
||||
die_port(peer.sin_port, PORT);
|
||||
die_port(&peer, PORT);
|
||||
} else {
|
||||
if (sendto(s2, buf, LEN, 0, (struct sockaddr *)&sa1, sizeof(sa1)) != LEN)
|
||||
continue;
|
||||
@@ -109,7 +114,7 @@ int main(int argc, char *argv[])
|
||||
die("parent recvfrom");
|
||||
|
||||
if (peer.sin_port != htons((PORT + 1)))
|
||||
die_port(peer.sin_port, PORT + 1);
|
||||
die_port(&peer, PORT + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ if ip netns exec "$ns0" ./conntrack_reverse_clash; then
|
||||
echo "PASS: No SNAT performed for null bindings"
|
||||
else
|
||||
echo "ERROR: SNAT performed without any matching snat rule"
|
||||
ip netns exec "$ns0" conntrack -L
|
||||
ip netns exec "$ns0" conntrack -S
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
+0.01 > R 643160523:643160523(0) win 0
|
||||
|
||||
+0.01 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null | grep UNREPLIED | grep -q SYN_SENT`
|
||||
+0.1 `conntrack -f $NFCT_IP_VERSION -L -p tcp --dport 8080 2>/dev/null | grep UNREPLIED | grep -q SYN_SENT`
|
||||
|
||||
// Must go through.
|
||||
+0.01 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 8>
|
||||
|
||||
@@ -81,7 +81,8 @@ static void run_server(void)
|
||||
if (getsockopt(connfd, SOL_SOCKET, SO_INCOMING_NAPI_ID, &opt, &len) < 0)
|
||||
error(1, errno, "getsockopt(SO_INCOMING_NAPI_ID)");
|
||||
|
||||
read(connfd, buf, 64);
|
||||
if (read(connfd, buf, 64) < 0)
|
||||
perror("read()");
|
||||
fprintf(outfile, "%d\n", opt);
|
||||
|
||||
fclose(outfile);
|
||||
|
||||
@@ -2786,10 +2786,10 @@ TEST_F(tls_err, epoll_partial_rec)
|
||||
TEST_F(tls_err, poll_partial_rec_async)
|
||||
{
|
||||
struct pollfd pfd = { };
|
||||
char token = '\0';
|
||||
ssize_t rec_len;
|
||||
char rec[256];
|
||||
char buf[128];
|
||||
char token;
|
||||
int p[2];
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -1052,5 +1052,51 @@
|
||||
"$TC qdisc del dev $DEV1 ingress_block 21 clsact",
|
||||
"$TC actions flush action mirred"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "7eba",
|
||||
"name": "Redirect multiport: dummy egress -> dummy egress (Loop)",
|
||||
"category": [
|
||||
"filter",
|
||||
"mirred"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": [
|
||||
"nsPlugin"
|
||||
]
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.10.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY handle 1: root drr",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 10 matchall action mirred egress redirect dev $DUMMY index 1"
|
||||
],
|
||||
"cmdUnderTest": "ping -c1 -W0.01 -I $DUMMY 10.10.10.1",
|
||||
"expExitCode": "1",
|
||||
"verifyCmd": "$TC -j -s actions get action mirred index 1",
|
||||
"matchJSON": [
|
||||
{
|
||||
"total acts": 0
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"order": 1,
|
||||
"kind": "mirred",
|
||||
"mirred_action": "redirect",
|
||||
"direction": "egress",
|
||||
"index": 1,
|
||||
"stats": {
|
||||
"packets": 1,
|
||||
"overlimits": 1
|
||||
},
|
||||
"not_in_hw": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1033,5 +1033,83 @@
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY handle 1: root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "6e4f",
|
||||
"name": "Try to delete ets drr class' qdisc while still keeping it in the active list",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"ets",
|
||||
"tbf"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": [
|
||||
"nsPlugin",
|
||||
"scapyPlugin"
|
||||
]
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.11.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY root handle 1: ets bands 2 strict 1",
|
||||
"$TC qdisc add dev $DUMMY parent 1:2 handle 20: tbf rate 8bit burst 100b latency 1s",
|
||||
"$TC filter add dev $DUMMY parent 1: basic classid 1:2",
|
||||
"ping -c2 -W0.01 -s 56 -I $DUMMY 10.10.11.11 || true",
|
||||
"$TC qdisc change dev $DUMMY root handle 1: ets bands 2 strict 2",
|
||||
"$TC qdisc change dev $DUMMY root handle 1: ets bands 1 strict 1"
|
||||
],
|
||||
"cmdUnderTest": "ping -c1 -W0.01 -s 56 -I $DUMMY 10.10.11.11",
|
||||
"expExitCode": "1",
|
||||
"verifyCmd": "$TC -s -j qdisc ls dev $DUMMY root",
|
||||
"matchJSON": [
|
||||
{
|
||||
"kind": "ets",
|
||||
"handle": "1:",
|
||||
"bytes": 196,
|
||||
"packets": 2
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root handle 1:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "0b8f",
|
||||
"name": "Try to add ets class to the active list twice",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"ets",
|
||||
"tbf"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": [
|
||||
"nsPlugin",
|
||||
"scapyPlugin"
|
||||
]
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.11.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY root handle 1: ets bands 2 strict 1",
|
||||
"$TC qdisc add dev $DUMMY parent 1:2 handle 20: tbf rate 8bit burst 100b latency 1s",
|
||||
"$TC filter add dev $DUMMY parent 1: basic classid 1:2",
|
||||
"ping -c2 -W0.01 -s 56 -I $DUMMY 10.10.11.11 || true",
|
||||
"$TC qdisc change dev $DUMMY root handle 1: ets bands 2 strict 2",
|
||||
"$TC qdisc change dev $DUMMY root handle 1: ets bands 2 strict 1"
|
||||
],
|
||||
"cmdUnderTest": "ping -c1 -W0.01 -s 56 -I $DUMMY 10.10.11.11",
|
||||
"expExitCode": "1",
|
||||
"verifyCmd": "$TC -s -j qdisc ls dev $DUMMY root",
|
||||
"matchJSON": [
|
||||
{
|
||||
"kind": "ets",
|
||||
"handle": "1:",
|
||||
"bytes": 98,
|
||||
"packets": 1
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root handle 1:"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user