mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
Networking fixes for 5.16-rc5, including fixes from bpf, can and netfilter.
Current release - regressions: - bpf, sockmap: re-evaluate proto ops when psock is removed from sockmap Current release - new code bugs: - bpf: fix bpf_check_mod_kfunc_call for built-in modules - ice: fixes for TC classifier offloads - vrf: don't run conntrack on vrf with !dflt qdisc Previous releases - regressions: - bpf: fix the off-by-two error in range markings - seg6: fix the iif in the IPv6 socket control block - devlink: fix netns refcount leak in devlink_nl_cmd_reload() - dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's" - dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports Previous releases - always broken: - ethtool: do not perform operations on net devices being unregistered - udp: use datalen to cap max gso segments - ice: fix races in stats collection - fec: only clear interrupt of handling queue in fec_enet_rx_queue() - m_can: pci: fix incorrect reference clock rate - m_can: disable and ignore ELO interrupt - mvpp2: fix XDP rx queues registering Misc: - treewide: add missing includes masked by cgroup -> bpf.h dependency Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmGyN1AACgkQMUZtbf5S IrtgMA/8D0qk3c75ts0hCzGXwdNdEBs+e7u1bJVPqdyU8x/ZLAp2c0EKB/7IWuxA CtsnbanPcmibqvQJDI1hZEBdafi43BmF5VuFSIxYC4EM/1vLoRprurXlIwL2YWki aWi//tyOIGBl6/ClzJ9Vm51HTJQwDmdv8GRnKAbsC1eOTM3pmmcg+6TLbDhycFEQ F9kkDCvyB9kWIH645QyJRH+Y5qQOvneCyQCPkkyjTgEADzV5i7YgtRol6J3QIbw3 umPHSckCBTjMacYcCLsbhQaF2gTMgPV1basNLPMjCquJVrItE0ZaeX3MiD6nBFae yY5+Wt5KAZDzjERhneX8AINHoRPA/tNIahC1+ytTmsTA8Hj230FHE5hH1ajWiJ9+ GSTBCBqjtZXce3r2Efxfzy0Kb9JwL3vDi7LS2eKQLv0zBLfYp2ry9Sp9qe4NhPkb OYrxws9kl5GOPvrFB5BWI9XBINciC9yC3PjIsz1noi0vD8/Hi9dPwXeAYh36fXU3 rwRg9uAt6tvFCpwbuQ9T2rsMST0miur2cDYd8qkJtuJ7zFvc+suMXwBZyI29nF2D uyymIC2XStHJfAjUkFsGVUSXF5FhML9OQsqmisdQ8KdH26jMnDeMjIWJM7UWK+zY E/fqWT8UyS3mXWqaggid4ZbotipCwA0gxiDHuqqUGTM+dbKrzmk= =F6rS -----END PGP SIGNATURE----- Merge tag 'net-5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from bpf, can and netfilter. Current release - regressions: - bpf, sockmap: re-evaluate proto ops when psock is removed from sockmap Current release - new code bugs: - bpf: fix bpf_check_mod_kfunc_call for built-in modules - ice: fixes for TC classifier offloads - vrf: don't run conntrack on vrf with !dflt qdisc Previous releases - regressions: - bpf: fix the off-by-two error in range markings - seg6: fix the iif in the IPv6 socket control block - devlink: fix netns refcount leak in devlink_nl_cmd_reload() - dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's" - dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports Previous releases - always broken: - ethtool: do not perform operations on net devices being unregistered - udp: use datalen to cap max gso segments - ice: fix races in stats collection - fec: only clear interrupt of handling queue in fec_enet_rx_queue() - m_can: pci: fix incorrect reference clock rate - m_can: disable and ignore ELO interrupt - mvpp2: fix XDP rx queues registering Misc: - treewide: add missing includes masked by cgroup -> bpf.h dependency" * tag 'net-5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (82 commits) net: dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports net: wwan: iosm: fixes unable to send AT command during mbim tx net: wwan: iosm: fixes net interface nonfunctional after fw flash net: wwan: iosm: fixes unnecessary doorbell send net: dsa: felix: Fix memory leak in felix_setup_mmio_filtering MAINTAINERS: s390/net: remove myself as maintainer net/sched: fq_pie: prevent dismantle issue net: mana: Fix memory leak in mana_hwc_create_wq seg6: fix the iif in the IPv6 socket control block nfp: Fix memory leak in nfp_cpp_area_cache_add() nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done nfc: fix segfault in nfc_genl_dump_devices_done udp: using datalen to cap max gso segments net: dsa: mv88e6xxx: error handling for serdes_power functions can: kvaser_usb: get CAN clock frequency from device can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct stats->{rx,tx}_errors counter net: mvpp2: fix XDP rx queues registering vmxnet3: fix minimum vectors alloc issue net, neigh: clear whole pneigh_entry at alloc time net: dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's" ...
This commit is contained in:
commit
ded746bfc9
@ -439,11 +439,9 @@ preemption. The following substitution works on both kernels::
|
||||
spin_lock(&p->lock);
|
||||
p->count += this_cpu_read(var2);
|
||||
|
||||
On a non-PREEMPT_RT kernel migrate_disable() maps to preempt_disable()
|
||||
which makes the above code fully equivalent. On a PREEMPT_RT kernel
|
||||
migrate_disable() ensures that the task is pinned on the current CPU which
|
||||
in turn guarantees that the per-CPU access to var1 and var2 are staying on
|
||||
the same CPU.
|
||||
the same CPU while the task remains preemptible.
|
||||
|
||||
The migrate_disable() substitution is not valid for the following
|
||||
scenario::
|
||||
@ -456,9 +454,8 @@ scenario::
|
||||
p = this_cpu_ptr(&var1);
|
||||
p->val = func2();
|
||||
|
||||
While correct on a non-PREEMPT_RT kernel, this breaks on PREEMPT_RT because
|
||||
here migrate_disable() does not protect against reentrancy from a
|
||||
preempting task. A correct substitution for this case is::
|
||||
This breaks because migrate_disable() does not protect against reentrancy from
|
||||
a preempting task. A correct substitution for this case is::
|
||||
|
||||
func()
|
||||
{
|
||||
|
@ -12180,8 +12180,8 @@ F: drivers/net/ethernet/mellanox/mlx5/core/fpga/*
|
||||
F: include/linux/mlx5/mlx5_ifc_fpga.h
|
||||
|
||||
MELLANOX ETHERNET SWITCH DRIVERS
|
||||
M: Jiri Pirko <jiri@nvidia.com>
|
||||
M: Ido Schimmel <idosch@nvidia.com>
|
||||
M: Petr Machata <petrm@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
@ -16629,7 +16629,6 @@ W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
F: drivers/iommu/s390-iommu.c
|
||||
|
||||
S390 IUCV NETWORK LAYER
|
||||
M: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
M: Alexandra Winter <wintera@linux.ibm.com>
|
||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
@ -16641,7 +16640,6 @@ F: include/net/iucv/
|
||||
F: net/iucv/
|
||||
|
||||
S390 NETWORK DRIVERS
|
||||
M: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
M: Alexandra Winter <wintera@linux.ibm.com>
|
||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
|
@ -98,7 +98,7 @@ do { \
|
||||
#define emit(...) __emit(__VA_ARGS__)
|
||||
|
||||
/* Workaround for R10000 ll/sc errata */
|
||||
#ifdef CONFIG_WAR_R10000
|
||||
#ifdef CONFIG_WAR_R10000_LLSC
|
||||
#define LLSC_beqz beqzl
|
||||
#else
|
||||
#define LLSC_beqz beqz
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/falloc.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include "blk.h"
|
||||
|
||||
static inline struct inode *bdev_file_inode(struct file *file)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#include <asm/set_memory.h>
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/slab.h> /* fault-inject.h is not standalone! */
|
||||
|
||||
#include <linux/fault-inject.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include "gem/i915_gem_lmem.h"
|
||||
#include "i915_trace.h"
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/clock.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include "gem/i915_gem_context.h"
|
||||
#include "gt/intel_breadcrumbs.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
#include "msm_gem.h"
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/module.h>
|
||||
#include <drm/drm_cache.h>
|
||||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
|
||||
|
@ -1501,14 +1501,14 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
struct slave *slave;
|
||||
|
||||
if (!bond_has_slaves(bond)) {
|
||||
bond_info->tx_rebalance_counter = 0;
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
bond_info->lp_counter = 0;
|
||||
goto re_arm;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
bond_info->tx_rebalance_counter++;
|
||||
atomic_inc(&bond_info->tx_rebalance_counter);
|
||||
bond_info->lp_counter++;
|
||||
|
||||
/* send learning packets */
|
||||
@ -1530,7 +1530,7 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* rebalance tx traffic */
|
||||
if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) {
|
||||
if (atomic_read(&bond_info->tx_rebalance_counter) >= BOND_TLB_REBALANCE_TICKS) {
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
tlb_clear_slave(bond, slave, 1);
|
||||
if (slave == rcu_access_pointer(bond->curr_active_slave)) {
|
||||
@ -1540,7 +1540,7 @@ void bond_alb_monitor(struct work_struct *work)
|
||||
bond_info->unbalanced_load = 0;
|
||||
}
|
||||
}
|
||||
bond_info->tx_rebalance_counter = 0;
|
||||
atomic_set(&bond_info->tx_rebalance_counter, 0);
|
||||
}
|
||||
|
||||
if (bond_info->rlb_enabled) {
|
||||
@ -1610,7 +1610,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
|
||||
tlb_init_slave(slave);
|
||||
|
||||
/* order a rebalance ASAP */
|
||||
bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
|
||||
atomic_set(&bond->alb_info.tx_rebalance_counter,
|
||||
BOND_TLB_REBALANCE_TICKS);
|
||||
|
||||
if (bond->alb_info.rlb_enabled)
|
||||
bond->alb_info.rlb_rebalance = 1;
|
||||
@ -1647,7 +1648,8 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
|
||||
rlb_clear_slave(bond, slave);
|
||||
} else if (link == BOND_LINK_UP) {
|
||||
/* order a rebalance ASAP */
|
||||
bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
|
||||
atomic_set(&bond_info->tx_rebalance_counter,
|
||||
BOND_TLB_REBALANCE_TICKS);
|
||||
if (bond->alb_info.rlb_enabled) {
|
||||
bond->alb_info.rlb_rebalance = 1;
|
||||
/* If the updelay module parameter is smaller than the
|
||||
|
@ -248,6 +248,9 @@ MODULE_DESCRIPTION("CAN driver for Kvaser CAN/PCIe devices");
|
||||
#define KVASER_PCIEFD_SPACK_EWLR BIT(23)
|
||||
#define KVASER_PCIEFD_SPACK_EPLR BIT(24)
|
||||
|
||||
/* Kvaser KCAN_EPACK second word */
|
||||
#define KVASER_PCIEFD_EPACK_DIR_TX BIT(0)
|
||||
|
||||
struct kvaser_pciefd;
|
||||
|
||||
struct kvaser_pciefd_can {
|
||||
@ -1285,7 +1288,10 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
|
||||
|
||||
can->err_rep_cnt++;
|
||||
can->can.can_stats.bus_error++;
|
||||
stats->rx_errors++;
|
||||
if (p->header[1] & KVASER_PCIEFD_EPACK_DIR_TX)
|
||||
stats->tx_errors++;
|
||||
else
|
||||
stats->rx_errors++;
|
||||
|
||||
can->bec.txerr = bec.txerr;
|
||||
can->bec.rxerr = bec.rxerr;
|
||||
|
@ -204,16 +204,16 @@ enum m_can_reg {
|
||||
|
||||
/* Interrupts for version 3.0.x */
|
||||
#define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE)
|
||||
#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \
|
||||
IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
|
||||
IR_RF1L | IR_RF0L)
|
||||
#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_BEU | IR_BEC | \
|
||||
IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \
|
||||
IR_RF0L)
|
||||
#define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X)
|
||||
|
||||
/* Interrupts for version >= 3.1.x */
|
||||
#define IR_ERR_LEC_31X (IR_PED | IR_PEA)
|
||||
#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \
|
||||
IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
|
||||
IR_RF1L | IR_RF0L)
|
||||
#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_BEU | IR_BEC | \
|
||||
IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \
|
||||
IR_RF0L)
|
||||
#define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X)
|
||||
|
||||
/* Interrupt Line Select (ILS) */
|
||||
@ -517,7 +517,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
|
||||
err = m_can_fifo_read(cdev, fgi, M_CAN_FIFO_DATA,
|
||||
cf->data, DIV_ROUND_UP(cf->len, 4));
|
||||
if (err)
|
||||
goto out_fail;
|
||||
goto out_free_skb;
|
||||
}
|
||||
|
||||
/* acknowledge rx fifo 0 */
|
||||
@ -532,6 +532,8 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs)
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_skb:
|
||||
kfree_skb(skb);
|
||||
out_fail:
|
||||
netdev_err(dev, "FIFO read returned %d\n", err);
|
||||
return err;
|
||||
@ -810,8 +812,6 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
|
||||
{
|
||||
if (irqstatus & IR_WDI)
|
||||
netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
|
||||
if (irqstatus & IR_ELO)
|
||||
netdev_err(dev, "Error Logging Overflow\n");
|
||||
if (irqstatus & IR_BEU)
|
||||
netdev_err(dev, "Bit Error Uncorrected\n");
|
||||
if (irqstatus & IR_BEC)
|
||||
@ -1494,20 +1494,32 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
|
||||
case 30:
|
||||
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */
|
||||
can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
|
||||
cdev->can.bittiming_const = &m_can_bittiming_const_30X;
|
||||
cdev->can.data_bittiming_const = &m_can_data_bittiming_const_30X;
|
||||
cdev->can.bittiming_const = cdev->bit_timing ?
|
||||
cdev->bit_timing : &m_can_bittiming_const_30X;
|
||||
|
||||
cdev->can.data_bittiming_const = cdev->data_timing ?
|
||||
cdev->data_timing :
|
||||
&m_can_data_bittiming_const_30X;
|
||||
break;
|
||||
case 31:
|
||||
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */
|
||||
can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
|
||||
cdev->can.bittiming_const = &m_can_bittiming_const_31X;
|
||||
cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X;
|
||||
cdev->can.bittiming_const = cdev->bit_timing ?
|
||||
cdev->bit_timing : &m_can_bittiming_const_31X;
|
||||
|
||||
cdev->can.data_bittiming_const = cdev->data_timing ?
|
||||
cdev->data_timing :
|
||||
&m_can_data_bittiming_const_31X;
|
||||
break;
|
||||
case 32:
|
||||
case 33:
|
||||
/* Support both MCAN version v3.2.x and v3.3.0 */
|
||||
cdev->can.bittiming_const = &m_can_bittiming_const_31X;
|
||||
cdev->can.data_bittiming_const = &m_can_data_bittiming_const_31X;
|
||||
cdev->can.bittiming_const = cdev->bit_timing ?
|
||||
cdev->bit_timing : &m_can_bittiming_const_31X;
|
||||
|
||||
cdev->can.data_bittiming_const = cdev->data_timing ?
|
||||
cdev->data_timing :
|
||||
&m_can_data_bittiming_const_31X;
|
||||
|
||||
cdev->can.ctrlmode_supported |=
|
||||
(m_can_niso_supported(cdev) ?
|
||||
|
@ -85,6 +85,9 @@ struct m_can_classdev {
|
||||
struct sk_buff *tx_skb;
|
||||
struct phy *transceiver;
|
||||
|
||||
const struct can_bittiming_const *bit_timing;
|
||||
const struct can_bittiming_const *data_timing;
|
||||
|
||||
struct m_can_ops *ops;
|
||||
|
||||
int version;
|
||||
|
@ -18,9 +18,14 @@
|
||||
|
||||
#define M_CAN_PCI_MMIO_BAR 0
|
||||
|
||||
#define M_CAN_CLOCK_FREQ_EHL 100000000
|
||||
#define CTL_CSR_INT_CTL_OFFSET 0x508
|
||||
|
||||
struct m_can_pci_config {
|
||||
const struct can_bittiming_const *bit_timing;
|
||||
const struct can_bittiming_const *data_timing;
|
||||
unsigned int clock_freq;
|
||||
};
|
||||
|
||||
struct m_can_pci_priv {
|
||||
struct m_can_classdev cdev;
|
||||
|
||||
@ -42,8 +47,13 @@ static u32 iomap_read_reg(struct m_can_classdev *cdev, int reg)
|
||||
static int iomap_read_fifo(struct m_can_classdev *cdev, int offset, void *val, size_t val_count)
|
||||
{
|
||||
struct m_can_pci_priv *priv = cdev_to_priv(cdev);
|
||||
void __iomem *src = priv->base + offset;
|
||||
|
||||
ioread32_rep(priv->base + offset, val, val_count);
|
||||
while (val_count--) {
|
||||
*(unsigned int *)val = ioread32(src);
|
||||
val += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -61,8 +71,13 @@ static int iomap_write_fifo(struct m_can_classdev *cdev, int offset,
|
||||
const void *val, size_t val_count)
|
||||
{
|
||||
struct m_can_pci_priv *priv = cdev_to_priv(cdev);
|
||||
void __iomem *dst = priv->base + offset;
|
||||
|
||||
iowrite32_rep(priv->base + offset, val, val_count);
|
||||
while (val_count--) {
|
||||
iowrite32(*(unsigned int *)val, dst);
|
||||
val += 4;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -74,9 +89,40 @@ static struct m_can_ops m_can_pci_ops = {
|
||||
.read_fifo = iomap_read_fifo,
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const m_can_bittiming_const_ehl = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
|
||||
.tseg1_max = 64,
|
||||
.tseg2_min = 1, /* Time segment 2 = phase_seg2 */
|
||||
.tseg2_max = 128,
|
||||
.sjw_max = 128,
|
||||
.brp_min = 1,
|
||||
.brp_max = 512,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const m_can_data_bittiming_const_ehl = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
|
||||
.tseg1_max = 16,
|
||||
.tseg2_min = 1, /* Time segment 2 = phase_seg2 */
|
||||
.tseg2_max = 8,
|
||||
.sjw_max = 4,
|
||||
.brp_min = 1,
|
||||
.brp_max = 32,
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
static const struct m_can_pci_config m_can_pci_ehl = {
|
||||
.bit_timing = &m_can_bittiming_const_ehl,
|
||||
.data_timing = &m_can_data_bittiming_const_ehl,
|
||||
.clock_freq = 200000000,
|
||||
};
|
||||
|
||||
static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
{
|
||||
struct device *dev = &pci->dev;
|
||||
const struct m_can_pci_config *cfg;
|
||||
struct m_can_classdev *mcan_class;
|
||||
struct m_can_pci_priv *priv;
|
||||
void __iomem *base;
|
||||
@ -104,6 +150,8 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
if (!mcan_class)
|
||||
return -ENOMEM;
|
||||
|
||||
cfg = (const struct m_can_pci_config *)id->driver_data;
|
||||
|
||||
priv = cdev_to_priv(mcan_class);
|
||||
|
||||
priv->base = base;
|
||||
@ -115,7 +163,9 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
|
||||
mcan_class->dev = &pci->dev;
|
||||
mcan_class->net->irq = pci_irq_vector(pci, 0);
|
||||
mcan_class->pm_clock_support = 1;
|
||||
mcan_class->can.clock.freq = id->driver_data;
|
||||
mcan_class->bit_timing = cfg->bit_timing;
|
||||
mcan_class->data_timing = cfg->data_timing;
|
||||
mcan_class->can.clock.freq = cfg->clock_freq;
|
||||
mcan_class->ops = &m_can_pci_ops;
|
||||
|
||||
pci_set_drvdata(pci, mcan_class);
|
||||
@ -168,8 +218,8 @@ static SIMPLE_DEV_PM_OPS(m_can_pci_pm_ops,
|
||||
m_can_pci_suspend, m_can_pci_resume);
|
||||
|
||||
static const struct pci_device_id m_can_pci_id_table[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x4bc1), M_CAN_CLOCK_FREQ_EHL, },
|
||||
{ PCI_VDEVICE(INTEL, 0x4bc2), M_CAN_CLOCK_FREQ_EHL, },
|
||||
{ PCI_VDEVICE(INTEL, 0x4bc1), (kernel_ulong_t)&m_can_pci_ehl, },
|
||||
{ PCI_VDEVICE(INTEL, 0x4bc2), (kernel_ulong_t)&m_can_pci_ehl, },
|
||||
{ } /* Terminating Entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, m_can_pci_id_table);
|
||||
|
@ -692,11 +692,11 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
|
||||
cf->data[i + 1] = data_reg >> 8;
|
||||
}
|
||||
|
||||
netif_receive_skb(skb);
|
||||
rcv_pkts++;
|
||||
stats->rx_packets++;
|
||||
quota--;
|
||||
stats->rx_bytes += cf->len;
|
||||
netif_receive_skb(skb);
|
||||
|
||||
pch_fifo_thresh(priv, obj_num);
|
||||
obj_num++;
|
||||
|
@ -234,7 +234,12 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
|
||||
free_sja1000dev(dev);
|
||||
}
|
||||
|
||||
err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
|
||||
if (!card->channels) {
|
||||
err = -ENODEV;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
|
||||
DRV_NAME, card);
|
||||
if (!err)
|
||||
return 0;
|
||||
|
@ -28,10 +28,6 @@
|
||||
|
||||
#include "kvaser_usb.h"
|
||||
|
||||
/* Forward declaration */
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg;
|
||||
|
||||
#define CAN_USB_CLOCK 8000000
|
||||
#define MAX_USBCAN_NET_DEVICES 2
|
||||
|
||||
/* Command header size */
|
||||
@ -80,6 +76,12 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg;
|
||||
|
||||
#define CMD_LEAF_LOG_MESSAGE 106
|
||||
|
||||
/* Leaf frequency options */
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_MASK 0x60
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5)
|
||||
#define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6)
|
||||
|
||||
/* error factors */
|
||||
#define M16C_EF_ACKE BIT(0)
|
||||
#define M16C_EF_CRCE BIT(1)
|
||||
@ -340,6 +342,50 @@ struct kvaser_usb_err_summary {
|
||||
};
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
|
||||
.name = "kvaser_usb",
|
||||
.tseg1_min = KVASER_USB_TSEG1_MIN,
|
||||
.tseg1_max = KVASER_USB_TSEG1_MAX,
|
||||
.tseg2_min = KVASER_USB_TSEG2_MIN,
|
||||
.tseg2_max = KVASER_USB_TSEG2_MAX,
|
||||
.sjw_max = KVASER_USB_SJW_MAX,
|
||||
.brp_min = KVASER_USB_BRP_MIN,
|
||||
.brp_max = KVASER_USB_BRP_MAX,
|
||||
.brp_inc = KVASER_USB_BRP_INC,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = {
|
||||
.clock = {
|
||||
.freq = 8000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = {
|
||||
.clock = {
|
||||
.freq = 16000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = {
|
||||
.clock = {
|
||||
.freq = 24000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = {
|
||||
.clock = {
|
||||
.freq = 32000000,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
||||
static void *
|
||||
kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
|
||||
const struct sk_buff *skb, int *frame_len,
|
||||
@ -471,6 +517,27 @@ static int kvaser_usb_leaf_send_simple_cmd(const struct kvaser_usb *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
|
||||
const struct leaf_cmd_softinfo *softinfo)
|
||||
{
|
||||
u32 sw_options = le32_to_cpu(softinfo->sw_options);
|
||||
|
||||
dev->fw_version = le32_to_cpu(softinfo->fw_version);
|
||||
dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
|
||||
|
||||
switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
|
||||
break;
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
|
||||
break;
|
||||
case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
|
||||
{
|
||||
struct kvaser_cmd cmd;
|
||||
@ -486,14 +553,13 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev)
|
||||
|
||||
switch (dev->card_data.leaf.family) {
|
||||
case KVASER_LEAF:
|
||||
dev->fw_version = le32_to_cpu(cmd.u.leaf.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(cmd.u.leaf.softinfo.max_outstanding_tx);
|
||||
kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
|
||||
break;
|
||||
case KVASER_USBCAN:
|
||||
dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx);
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1225,24 +1291,11 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev)
|
||||
{
|
||||
struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
|
||||
|
||||
dev->cfg = &kvaser_usb_leaf_dev_cfg;
|
||||
card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = {
|
||||
.name = "kvaser_usb",
|
||||
.tseg1_min = KVASER_USB_TSEG1_MIN,
|
||||
.tseg1_max = KVASER_USB_TSEG1_MAX,
|
||||
.tseg2_min = KVASER_USB_TSEG2_MIN,
|
||||
.tseg2_max = KVASER_USB_TSEG2_MAX,
|
||||
.sjw_max = KVASER_USB_SJW_MAX,
|
||||
.brp_min = KVASER_USB_BRP_MIN,
|
||||
.brp_max = KVASER_USB_BRP_MAX,
|
||||
.brp_inc = KVASER_USB_BRP_INC,
|
||||
};
|
||||
|
||||
static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
|
||||
{
|
||||
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
|
||||
@ -1348,11 +1401,3 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
|
||||
.dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback,
|
||||
.dev_frame_to_cmd = kvaser_usb_leaf_frame_to_cmd,
|
||||
};
|
||||
|
||||
static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg = {
|
||||
.clock = {
|
||||
.freq = CAN_USB_CLOCK,
|
||||
},
|
||||
.timestamp_freq = 1,
|
||||
.bittiming_const = &kvaser_usb_leaf_bittiming_const,
|
||||
};
|
||||
|
@ -471,6 +471,12 @@ static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
|
||||
u16 reg;
|
||||
int err;
|
||||
|
||||
/* The 88e6250 family does not have the PHY detect bit. Instead,
|
||||
* report whether the port is internal.
|
||||
*/
|
||||
if (chip->info->family == MV88E6XXX_FAMILY_6250)
|
||||
return port < chip->info->num_internal_phys;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
|
||||
if (err) {
|
||||
dev_err(chip->dev,
|
||||
@ -692,44 +698,48 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
struct mv88e6xxx_port *p;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
p = &chip->ports[port];
|
||||
|
||||
/* FIXME: is this the correct test? If we're in fixed mode on an
|
||||
* internal port, why should we process this any different from
|
||||
* PHY mode? On the other hand, the port may be automedia between
|
||||
* an internal PHY and the serdes...
|
||||
*/
|
||||
if ((mode == MLO_AN_PHY) && mv88e6xxx_phy_is_internal(ds, port))
|
||||
return;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
/* In inband mode, the link may come up at any time while the link
|
||||
* is not forced down. Force the link down while we reconfigure the
|
||||
* interface mode.
|
||||
*/
|
||||
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
|
||||
chip->info->ops->port_set_link)
|
||||
chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
|
||||
|
||||
err = mv88e6xxx_port_config_interface(chip, port, state->interface);
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
goto err_unlock;
|
||||
if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) {
|
||||
/* In inband mode, the link may come up at any time while the
|
||||
* link is not forced down. Force the link down while we
|
||||
* reconfigure the interface mode.
|
||||
*/
|
||||
if (mode == MLO_AN_INBAND &&
|
||||
p->interface != state->interface &&
|
||||
chip->info->ops->port_set_link)
|
||||
chip->info->ops->port_set_link(chip, port,
|
||||
LINK_FORCED_DOWN);
|
||||
|
||||
err = mv88e6xxx_serdes_pcs_config(chip, port, mode, state->interface,
|
||||
state->advertising);
|
||||
/* FIXME: we should restart negotiation if something changed - which
|
||||
* is something we get if we convert to using phylinks PCS operations.
|
||||
*/
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
err = mv88e6xxx_port_config_interface(chip, port,
|
||||
state->interface);
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
goto err_unlock;
|
||||
|
||||
err = mv88e6xxx_serdes_pcs_config(chip, port, mode,
|
||||
state->interface,
|
||||
state->advertising);
|
||||
/* FIXME: we should restart negotiation if something changed -
|
||||
* which is something we get if we convert to using phylinks
|
||||
* PCS operations.
|
||||
*/
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
}
|
||||
|
||||
/* Undo the forced down state above after completing configuration
|
||||
* irrespective of its state on entry, which allows the link to come up.
|
||||
* irrespective of its state on entry, which allows the link to come
|
||||
* up in the in-band case where there is no separate SERDES. Also
|
||||
* ensure that the link can come up if the PPU is in use and we are
|
||||
* in PHY mode (we treat the PPU as an effective in-band mechanism.)
|
||||
*/
|
||||
if (mode == MLO_AN_INBAND && p->interface != state->interface &&
|
||||
chip->info->ops->port_set_link)
|
||||
if (chip->info->ops->port_set_link &&
|
||||
((mode == MLO_AN_INBAND && p->interface != state->interface) ||
|
||||
(mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
|
||||
chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
|
||||
|
||||
p->interface = state->interface;
|
||||
@ -752,11 +762,10 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
|
||||
ops = chip->info->ops;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
/* Internal PHYs propagate their configuration directly to the MAC.
|
||||
* External PHYs depend on whether the PPU is enabled for this port.
|
||||
/* Force the link down if we know the port may not be automatically
|
||||
* updated by the switch or if we are using fixed-link mode.
|
||||
*/
|
||||
if (((!mv88e6xxx_phy_is_internal(ds, port) &&
|
||||
!mv88e6xxx_port_ppu_updates(chip, port)) ||
|
||||
if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) && ops->port_sync_link)
|
||||
err = ops->port_sync_link(chip, port, mode, false);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
@ -779,11 +788,11 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
|
||||
ops = chip->info->ops;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
/* Internal PHYs propagate their configuration directly to the MAC.
|
||||
* External PHYs depend on whether the PPU is enabled for this port.
|
||||
/* Configure and force the link up if we know that the port may not
|
||||
* automatically updated by the switch or if we are using fixed-link
|
||||
* mode.
|
||||
*/
|
||||
if ((!mv88e6xxx_phy_is_internal(ds, port) &&
|
||||
!mv88e6xxx_port_ppu_updates(chip, port)) ||
|
||||
if (!mv88e6xxx_port_ppu_updates(chip, port) ||
|
||||
mode == MLO_AN_FIXED) {
|
||||
/* FIXME: for an automedia port, should we force the link
|
||||
* down here - what if the link comes up due to "other" media
|
||||
|
@ -830,7 +830,7 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
|
||||
bool up)
|
||||
{
|
||||
u8 cmode = chip->ports[port].cmode;
|
||||
int err = 0;
|
||||
int err;
|
||||
|
||||
switch (cmode) {
|
||||
case MV88E6XXX_PORT_STS_CMODE_SGMII:
|
||||
@ -842,6 +842,9 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
|
||||
case MV88E6XXX_PORT_STS_CMODE_RXAUI:
|
||||
err = mv88e6390_serdes_power_10g(chip, lane, up);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!err && up)
|
||||
@ -1541,6 +1544,9 @@ int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
|
||||
case MV88E6393X_PORT_STS_CMODE_10GBASER:
|
||||
err = mv88e6390_serdes_power_10g(chip, lane, on);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
|
@ -290,8 +290,11 @@ static int felix_setup_mmio_filtering(struct felix *felix)
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu < 0)
|
||||
if (cpu < 0) {
|
||||
kfree(tagging_rule);
|
||||
kfree(redirect_rule);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tagging_rule->key_type = OCELOT_VCAP_KEY_ETYPE;
|
||||
*(__be16 *)tagging_rule->key.etype.etype.value = htons(ETH_P_1588);
|
||||
|
@ -1430,16 +1430,19 @@ static int altera_tse_probe(struct platform_device *pdev)
|
||||
priv->rxdescmem_busaddr = dma_res->start;
|
||||
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask)))
|
||||
if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) {
|
||||
dma_set_coherent_mask(priv->device,
|
||||
DMA_BIT_MASK(priv->dmaops->dmamask));
|
||||
else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32)))
|
||||
} else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) {
|
||||
dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32));
|
||||
else
|
||||
} else {
|
||||
ret = -EIO;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
/* MAC address space */
|
||||
ret = request_and_map(pdev, "control_port", &control_port,
|
||||
|
@ -708,7 +708,9 @@ static int bcm4908_enet_probe(struct platform_device *pdev)
|
||||
|
||||
enet->irq_tx = platform_get_irq_byname(pdev, "tx");
|
||||
|
||||
dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
|
||||
err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = bcm4908_enet_dma_alloc(enet);
|
||||
if (err)
|
||||
|
@ -377,6 +377,9 @@ struct bufdesc_ex {
|
||||
#define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */
|
||||
#define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2)
|
||||
#define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2)
|
||||
#define FEC_ENET_RXF_GET(X) (((X) == 0) ? FEC_ENET_RXF_0 : \
|
||||
(((X) == 1) ? FEC_ENET_RXF_1 : \
|
||||
FEC_ENET_RXF_2))
|
||||
#define FEC_ENET_TS_AVAIL ((uint)0x00010000)
|
||||
#define FEC_ENET_TS_TIMER ((uint)0x00008000)
|
||||
|
||||
|
@ -1480,7 +1480,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
|
||||
break;
|
||||
pkt_received++;
|
||||
|
||||
writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
|
||||
writel(FEC_ENET_RXF_GET(queue_id), fep->hwp + FEC_IEVENT);
|
||||
|
||||
/* Check for errors. */
|
||||
status ^= BD_ENET_RX_LAST;
|
||||
|
@ -68,6 +68,9 @@ struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
|
||||
set_protocol = ctx->curr_frag_cnt == ctx->expected_frag_cnt - 1;
|
||||
} else {
|
||||
skb = napi_alloc_skb(napi, len);
|
||||
|
||||
if (unlikely(!skb))
|
||||
return NULL;
|
||||
set_protocol = true;
|
||||
}
|
||||
__skb_put(skb, len);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hinic_hw_dev.h"
|
||||
#include "hinic_dev.h"
|
||||
|
@ -553,6 +553,14 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
|
||||
dev_info(&pf->pdev->dev, "vsi %d not found\n", vsi_seid);
|
||||
return;
|
||||
}
|
||||
if (vsi->type != I40E_VSI_MAIN &&
|
||||
vsi->type != I40E_VSI_FDIR &&
|
||||
vsi->type != I40E_VSI_VMDQ2) {
|
||||
dev_info(&pf->pdev->dev,
|
||||
"vsi %d type %d descriptor rings not available\n",
|
||||
vsi_seid, vsi->type);
|
||||
return;
|
||||
}
|
||||
if (type == RING_TYPE_XDP && !i40e_enabled_xdp_vsi(vsi)) {
|
||||
dev_info(&pf->pdev->dev, "XDP not enabled on VSI %d\n", vsi_seid);
|
||||
return;
|
||||
|
@ -1948,6 +1948,32 @@ static int i40e_vc_send_resp_to_vf(struct i40e_vf *vf,
|
||||
return i40e_vc_send_msg_to_vf(vf, opcode, retval, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_sync_vf_state
|
||||
* @vf: pointer to the VF info
|
||||
* @state: VF state
|
||||
*
|
||||
* Called from a VF message to synchronize the service with a potential
|
||||
* VF reset state
|
||||
**/
|
||||
static bool i40e_sync_vf_state(struct i40e_vf *vf, enum i40e_vf_states state)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* When handling some messages, it needs VF state to be set.
|
||||
* It is possible that this flag is cleared during VF reset,
|
||||
* so there is a need to wait until the end of the reset to
|
||||
* handle the request message correctly.
|
||||
*/
|
||||
for (i = 0; i < I40E_VF_STATE_WAIT_COUNT; i++) {
|
||||
if (test_bit(state, &vf->vf_states))
|
||||
return true;
|
||||
usleep_range(10000, 20000);
|
||||
}
|
||||
|
||||
return test_bit(state, &vf->vf_states);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_vc_get_version_msg
|
||||
* @vf: pointer to the VF info
|
||||
@ -2008,7 +2034,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
|
||||
size_t len = 0;
|
||||
int ret;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_INIT)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -2131,7 +2157,7 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, u8 *msg)
|
||||
bool allmulti = false;
|
||||
bool alluni = false;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err_out;
|
||||
}
|
||||
@ -2219,7 +2245,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
|
||||
struct i40e_vsi *vsi;
|
||||
u16 num_qps_all = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
}
|
||||
@ -2368,7 +2394,7 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
int i;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
}
|
||||
@ -2540,7 +2566,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg)
|
||||
struct i40e_pf *pf = vf->pf;
|
||||
i40e_status aq_ret = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
}
|
||||
@ -2590,7 +2616,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg)
|
||||
u8 cur_pairs = vf->num_queue_pairs;
|
||||
struct i40e_pf *pf = vf->pf;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states))
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE))
|
||||
return -EINVAL;
|
||||
|
||||
if (req_pairs > I40E_MAX_VF_QUEUES) {
|
||||
@ -2635,7 +2661,7 @@ static int i40e_vc_get_stats_msg(struct i40e_vf *vf, u8 *msg)
|
||||
|
||||
memset(&stats, 0, sizeof(struct i40e_eth_stats));
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
}
|
||||
@ -2752,7 +2778,7 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status ret = 0;
|
||||
int i;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
|
||||
!i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) {
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
@ -2824,7 +2850,7 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status ret = 0;
|
||||
int i;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
|
||||
!i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) {
|
||||
ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
@ -2968,7 +2994,7 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
int i;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
|
||||
!i40e_vc_isvalid_vsi_id(vf, vfl->vsi_id)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto error_param;
|
||||
@ -3088,9 +3114,9 @@ static int i40e_vc_config_rss_key(struct i40e_vf *vf, u8 *msg)
|
||||
struct i40e_vsi *vsi = NULL;
|
||||
i40e_status aq_ret = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
|
||||
!i40e_vc_isvalid_vsi_id(vf, vrk->vsi_id) ||
|
||||
(vrk->key_len != I40E_HKEY_ARRAY_SIZE)) {
|
||||
vrk->key_len != I40E_HKEY_ARRAY_SIZE) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3119,9 +3145,9 @@ static int i40e_vc_config_rss_lut(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
u16 i;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) ||
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) ||
|
||||
!i40e_vc_isvalid_vsi_id(vf, vrl->vsi_id) ||
|
||||
(vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE)) {
|
||||
vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3154,7 +3180,7 @@ static int i40e_vc_get_rss_hena(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
int len = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3190,7 +3216,7 @@ static int i40e_vc_set_rss_hena(struct i40e_vf *vf, u8 *msg)
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
i40e_status aq_ret = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3215,7 +3241,7 @@ static int i40e_vc_enable_vlan_stripping(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
struct i40e_vsi *vsi;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3241,7 +3267,7 @@ static int i40e_vc_disable_vlan_stripping(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
struct i40e_vsi *vsi;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3468,7 +3494,7 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
int i, ret;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3599,7 +3625,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
int i, ret;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err_out;
|
||||
}
|
||||
@ -3708,7 +3734,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
|
||||
i40e_status aq_ret = 0;
|
||||
u64 speed = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
@ -3797,11 +3823,6 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
|
||||
|
||||
/* set this flag only after making sure all inputs are sane */
|
||||
vf->adq_enabled = true;
|
||||
/* num_req_queues is set when user changes number of queues via ethtool
|
||||
* and this causes issue for default VSI(which depends on this variable)
|
||||
* when ADq is enabled, hence reset it.
|
||||
*/
|
||||
vf->num_req_queues = 0;
|
||||
|
||||
/* reset the VF in order to allocate resources */
|
||||
i40e_vc_reset_vf(vf, true);
|
||||
@ -3824,7 +3845,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg)
|
||||
struct i40e_pf *pf = vf->pf;
|
||||
i40e_status aq_ret = 0;
|
||||
|
||||
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) {
|
||||
if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) {
|
||||
aq_ret = I40E_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#define I40E_MAX_VF_PROMISC_FLAGS 3
|
||||
|
||||
#define I40E_VF_STATE_WAIT_COUNT 20
|
||||
|
||||
/* Various queue ctrls */
|
||||
enum i40e_queue_ctrl {
|
||||
I40E_QUEUE_CTRL_UNKNOWN = 0,
|
||||
|
@ -615,23 +615,44 @@ static int iavf_set_ringparam(struct net_device *netdev,
|
||||
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
|
||||
return -EINVAL;
|
||||
|
||||
new_tx_count = clamp_t(u32, ring->tx_pending,
|
||||
IAVF_MIN_TXD,
|
||||
IAVF_MAX_TXD);
|
||||
new_tx_count = ALIGN(new_tx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE);
|
||||
if (ring->tx_pending > IAVF_MAX_TXD ||
|
||||
ring->tx_pending < IAVF_MIN_TXD ||
|
||||
ring->rx_pending > IAVF_MAX_RXD ||
|
||||
ring->rx_pending < IAVF_MIN_RXD) {
|
||||
netdev_err(netdev, "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d] (increment %d)\n",
|
||||
ring->tx_pending, ring->rx_pending, IAVF_MIN_TXD,
|
||||
IAVF_MAX_RXD, IAVF_REQ_DESCRIPTOR_MULTIPLE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
new_rx_count = clamp_t(u32, ring->rx_pending,
|
||||
IAVF_MIN_RXD,
|
||||
IAVF_MAX_RXD);
|
||||
new_rx_count = ALIGN(new_rx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE);
|
||||
new_tx_count = ALIGN(ring->tx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE);
|
||||
if (new_tx_count != ring->tx_pending)
|
||||
netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n",
|
||||
new_tx_count);
|
||||
|
||||
new_rx_count = ALIGN(ring->rx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE);
|
||||
if (new_rx_count != ring->rx_pending)
|
||||
netdev_info(netdev, "Requested Rx descriptor count rounded up to %d\n",
|
||||
new_rx_count);
|
||||
|
||||
/* if nothing to do return success */
|
||||
if ((new_tx_count == adapter->tx_desc_count) &&
|
||||
(new_rx_count == adapter->rx_desc_count))
|
||||
(new_rx_count == adapter->rx_desc_count)) {
|
||||
netdev_dbg(netdev, "Nothing to change, descriptor count is same as requested\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
adapter->tx_desc_count = new_tx_count;
|
||||
adapter->rx_desc_count = new_rx_count;
|
||||
if (new_tx_count != adapter->tx_desc_count) {
|
||||
netdev_dbg(netdev, "Changing Tx descriptor count from %d to %d\n",
|
||||
adapter->tx_desc_count, new_tx_count);
|
||||
adapter->tx_desc_count = new_tx_count;
|
||||
}
|
||||
|
||||
if (new_rx_count != adapter->rx_desc_count) {
|
||||
netdev_dbg(netdev, "Changing Rx descriptor count from %d to %d\n",
|
||||
adapter->rx_desc_count, new_rx_count);
|
||||
adapter->rx_desc_count = new_rx_count;
|
||||
}
|
||||
|
||||
if (netif_running(netdev)) {
|
||||
adapter->flags |= IAVF_FLAG_RESET_NEEDED;
|
||||
|
@ -2248,6 +2248,7 @@ static void iavf_reset_task(struct work_struct *work)
|
||||
}
|
||||
|
||||
pci_set_master(adapter->pdev);
|
||||
pci_restore_msi_state(adapter->pdev);
|
||||
|
||||
if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) {
|
||||
dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n",
|
||||
|
@ -97,6 +97,9 @@ static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets)
|
||||
|
||||
new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc;
|
||||
|
||||
if (!bwcfg)
|
||||
new_cfg->etscfg.tcbwtable[0] = 100;
|
||||
|
||||
if (!bwrec)
|
||||
new_cfg->etsrec.tcbwtable[0] = 100;
|
||||
|
||||
@ -167,15 +170,18 @@ static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
|
||||
if (mode == pf->dcbx_cap)
|
||||
return ICE_DCB_NO_HW_CHG;
|
||||
|
||||
pf->dcbx_cap = mode;
|
||||
qos_cfg = &pf->hw.port_info->qos_cfg;
|
||||
if (mode & DCB_CAP_DCBX_VER_CEE) {
|
||||
if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP)
|
||||
return ICE_DCB_NO_HW_CHG;
|
||||
|
||||
/* DSCP configuration is not DCBx negotiated */
|
||||
if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP)
|
||||
return ICE_DCB_NO_HW_CHG;
|
||||
|
||||
pf->dcbx_cap = mode;
|
||||
|
||||
if (mode & DCB_CAP_DCBX_VER_CEE)
|
||||
qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE;
|
||||
} else {
|
||||
else
|
||||
qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE;
|
||||
}
|
||||
|
||||
dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode);
|
||||
return ICE_DCB_HW_CHG_RST;
|
||||
|
@ -1268,7 +1268,7 @@ ice_fdir_write_all_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input,
|
||||
bool is_tun = tun == ICE_FD_HW_SEG_TUN;
|
||||
int err;
|
||||
|
||||
if (is_tun && !ice_get_open_tunnel_port(&pf->hw, &port_num))
|
||||
if (is_tun && !ice_get_open_tunnel_port(&pf->hw, &port_num, TNL_ALL))
|
||||
continue;
|
||||
err = ice_fdir_write_fltr(pf, input, add, is_tun);
|
||||
if (err)
|
||||
@ -1652,7 +1652,7 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd)
|
||||
}
|
||||
|
||||
/* return error if not an update and no available filters */
|
||||
fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port) ? 2 : 1;
|
||||
fltrs_needed = ice_get_open_tunnel_port(hw, &tunnel_port, TNL_ALL) ? 2 : 1;
|
||||
if (!ice_fdir_find_fltr_by_idx(hw, fsp->location) &&
|
||||
ice_fdir_num_avail_fltr(hw, pf->vsi[vsi->idx]) < fltrs_needed) {
|
||||
dev_err(dev, "Failed to add filter. The maximum number of flow director filters has been reached.\n");
|
||||
|
@ -924,7 +924,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
|
||||
memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
|
||||
loc = pkt;
|
||||
} else {
|
||||
if (!ice_get_open_tunnel_port(hw, &tnl_port))
|
||||
if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL))
|
||||
return ICE_ERR_DOES_NOT_EXIST;
|
||||
if (!ice_fdir_pkt[idx].tun_pkt)
|
||||
return ICE_ERR_PARAM;
|
||||
|
@ -1899,9 +1899,11 @@ static struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)
|
||||
* ice_get_open_tunnel_port - retrieve an open tunnel port
|
||||
* @hw: pointer to the HW structure
|
||||
* @port: returns open port
|
||||
* @type: type of tunnel, can be TNL_LAST if it doesn't matter
|
||||
*/
|
||||
bool
|
||||
ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port)
|
||||
ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port,
|
||||
enum ice_tunnel_type type)
|
||||
{
|
||||
bool res = false;
|
||||
u16 i;
|
||||
@ -1909,7 +1911,8 @@ ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port)
|
||||
mutex_lock(&hw->tnl_lock);
|
||||
|
||||
for (i = 0; i < hw->tnl.count && i < ICE_TUNNEL_MAX_ENTRIES; i++)
|
||||
if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].port) {
|
||||
if (hw->tnl.tbl[i].valid && hw->tnl.tbl[i].port &&
|
||||
(type == TNL_LAST || type == hw->tnl.tbl[i].type)) {
|
||||
*port = hw->tnl.tbl[i].port;
|
||||
res = true;
|
||||
break;
|
||||
|
@ -33,7 +33,8 @@ enum ice_status
|
||||
ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
|
||||
unsigned long *bm, struct list_head *fv_list);
|
||||
bool
|
||||
ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port);
|
||||
ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port,
|
||||
enum ice_tunnel_type type);
|
||||
int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
|
||||
unsigned int idx, struct udp_tunnel_info *ti);
|
||||
int ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
|
||||
|
@ -5881,6 +5881,9 @@ static int ice_up_complete(struct ice_vsi *vsi)
|
||||
netif_carrier_on(vsi->netdev);
|
||||
}
|
||||
|
||||
/* clear this now, and the first stats read will be used as baseline */
|
||||
vsi->stat_offsets_loaded = false;
|
||||
|
||||
ice_service_task_schedule(pf);
|
||||
|
||||
return 0;
|
||||
@ -5927,14 +5930,15 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats st
|
||||
/**
|
||||
* ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters
|
||||
* @vsi: the VSI to be updated
|
||||
* @vsi_stats: the stats struct to be updated
|
||||
* @rings: rings to work on
|
||||
* @count: number of rings
|
||||
*/
|
||||
static void
|
||||
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings,
|
||||
u16 count)
|
||||
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi,
|
||||
struct rtnl_link_stats64 *vsi_stats,
|
||||
struct ice_tx_ring **rings, u16 count)
|
||||
{
|
||||
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats;
|
||||
u16 i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
@ -5958,15 +5962,13 @@ ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings,
|
||||
*/
|
||||
static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
|
||||
{
|
||||
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats;
|
||||
struct rtnl_link_stats64 *vsi_stats;
|
||||
u64 pkts, bytes;
|
||||
int i;
|
||||
|
||||
/* reset netdev stats */
|
||||
vsi_stats->tx_packets = 0;
|
||||
vsi_stats->tx_bytes = 0;
|
||||
vsi_stats->rx_packets = 0;
|
||||
vsi_stats->rx_bytes = 0;
|
||||
vsi_stats = kzalloc(sizeof(*vsi_stats), GFP_ATOMIC);
|
||||
if (!vsi_stats)
|
||||
return;
|
||||
|
||||
/* reset non-netdev (extended) stats */
|
||||
vsi->tx_restart = 0;
|
||||
@ -5978,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
|
||||
rcu_read_lock();
|
||||
|
||||
/* update Tx rings counters */
|
||||
ice_update_vsi_tx_ring_stats(vsi, vsi->tx_rings, vsi->num_txq);
|
||||
ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->tx_rings,
|
||||
vsi->num_txq);
|
||||
|
||||
/* update Rx rings counters */
|
||||
ice_for_each_rxq(vsi, i) {
|
||||
@ -5993,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
|
||||
|
||||
/* update XDP Tx rings counters */
|
||||
if (ice_is_xdp_ena_vsi(vsi))
|
||||
ice_update_vsi_tx_ring_stats(vsi, vsi->xdp_rings,
|
||||
ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->xdp_rings,
|
||||
vsi->num_xdp_txq);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
vsi->net_stats.tx_packets = vsi_stats->tx_packets;
|
||||
vsi->net_stats.tx_bytes = vsi_stats->tx_bytes;
|
||||
vsi->net_stats.rx_packets = vsi_stats->rx_packets;
|
||||
vsi->net_stats.rx_bytes = vsi_stats->rx_bytes;
|
||||
|
||||
kfree(vsi_stats);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3796,10 +3796,13 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
|
||||
* ice_find_recp - find a recipe
|
||||
* @hw: pointer to the hardware structure
|
||||
* @lkup_exts: extension sequence to match
|
||||
* @tun_type: type of recipe tunnel
|
||||
*
|
||||
* Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
|
||||
*/
|
||||
static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts)
|
||||
static u16
|
||||
ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
|
||||
enum ice_sw_tunnel_type tun_type)
|
||||
{
|
||||
bool refresh_required = true;
|
||||
struct ice_sw_recipe *recp;
|
||||
@ -3860,8 +3863,9 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts)
|
||||
}
|
||||
/* If for "i"th recipe the found was never set to false
|
||||
* then it means we found our match
|
||||
* Also tun type of recipe needs to be checked
|
||||
*/
|
||||
if (found)
|
||||
if (found && recp[i].tun_type == tun_type)
|
||||
return i; /* Return the recipe ID */
|
||||
}
|
||||
}
|
||||
@ -4651,11 +4655,12 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
|
||||
}
|
||||
|
||||
/* Look for a recipe which matches our requested fv / mask list */
|
||||
*rid = ice_find_recp(hw, lkup_exts);
|
||||
*rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type);
|
||||
if (*rid < ICE_MAX_NUM_RECIPES)
|
||||
/* Success if found a recipe that match the existing criteria */
|
||||
goto err_unroll;
|
||||
|
||||
rm->tun_type = rinfo->tun_type;
|
||||
/* Recipe we need does not exist, add a recipe */
|
||||
status = ice_add_sw_recipe(hw, rm, profiles);
|
||||
if (status)
|
||||
@ -4958,11 +4963,13 @@ ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
|
||||
|
||||
switch (tun_type) {
|
||||
case ICE_SW_TUN_VXLAN:
|
||||
case ICE_SW_TUN_GENEVE:
|
||||
if (!ice_get_open_tunnel_port(hw, &open_port))
|
||||
if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
|
||||
return ICE_ERR_CFG;
|
||||
break;
|
||||
case ICE_SW_TUN_GENEVE:
|
||||
if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
|
||||
return ICE_ERR_CFG;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Nothing needs to be done for this tunnel type */
|
||||
return 0;
|
||||
@ -5555,7 +5562,7 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
rid = ice_find_recp(hw, &lkup_exts);
|
||||
rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type);
|
||||
/* If did not find a recipe that match the existing criteria */
|
||||
if (rid == ICE_MAX_NUM_RECIPES)
|
||||
return ICE_ERR_PARAM;
|
||||
|
@ -74,21 +74,13 @@ static enum ice_protocol_type ice_proto_type_from_ipv6(bool inner)
|
||||
return inner ? ICE_IPV6_IL : ICE_IPV6_OFOS;
|
||||
}
|
||||
|
||||
static enum ice_protocol_type
|
||||
ice_proto_type_from_l4_port(bool inner, u16 ip_proto)
|
||||
static enum ice_protocol_type ice_proto_type_from_l4_port(u16 ip_proto)
|
||||
{
|
||||
if (inner) {
|
||||
switch (ip_proto) {
|
||||
case IPPROTO_UDP:
|
||||
return ICE_UDP_ILOS;
|
||||
}
|
||||
} else {
|
||||
switch (ip_proto) {
|
||||
case IPPROTO_TCP:
|
||||
return ICE_TCP_IL;
|
||||
case IPPROTO_UDP:
|
||||
return ICE_UDP_OF;
|
||||
}
|
||||
switch (ip_proto) {
|
||||
case IPPROTO_TCP:
|
||||
return ICE_TCP_IL;
|
||||
case IPPROTO_UDP:
|
||||
return ICE_UDP_ILOS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -191,8 +183,9 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
|
||||
i++;
|
||||
}
|
||||
|
||||
if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT) {
|
||||
list[i].type = ice_proto_type_from_l4_port(false, hdr->l3_key.ip_proto);
|
||||
if ((flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT) &&
|
||||
hdr->l3_key.ip_proto == IPPROTO_UDP) {
|
||||
list[i].type = ICE_UDP_OF;
|
||||
list[i].h_u.l4_hdr.dst_port = hdr->l4_key.dst_port;
|
||||
list[i].m_u.l4_hdr.dst_port = hdr->l4_mask.dst_port;
|
||||
i++;
|
||||
@ -317,7 +310,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
|
||||
ICE_TC_FLWR_FIELD_SRC_L4_PORT)) {
|
||||
struct ice_tc_l4_hdr *l4_key, *l4_mask;
|
||||
|
||||
list[i].type = ice_proto_type_from_l4_port(inner, headers->l3_key.ip_proto);
|
||||
list[i].type = ice_proto_type_from_l4_port(headers->l3_key.ip_proto);
|
||||
l4_key = &headers->l4_key;
|
||||
l4_mask = &headers->l4_mask;
|
||||
|
||||
@ -802,7 +795,8 @@ ice_parse_tunnel_attr(struct net_device *dev, struct flow_rule *rule,
|
||||
headers->l3_mask.ttl = match.mask->ttl;
|
||||
}
|
||||
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS) &&
|
||||
fltr->tunnel_type != TNL_VXLAN && fltr->tunnel_type != TNL_GENEVE) {
|
||||
struct flow_match_ports match;
|
||||
|
||||
flow_rule_match_enc_ports(rule, &match);
|
||||
|
@ -1617,6 +1617,7 @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
|
||||
ice_vc_set_default_allowlist(vf);
|
||||
|
||||
ice_vf_fdir_exit(vf);
|
||||
ice_vf_fdir_init(vf);
|
||||
/* clean VF control VSI when resetting VFs since it should be
|
||||
* setup only when VF creates its first FDIR rule.
|
||||
*/
|
||||
@ -1747,6 +1748,7 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
|
||||
}
|
||||
|
||||
ice_vf_fdir_exit(vf);
|
||||
ice_vf_fdir_init(vf);
|
||||
/* clean VF control VSI when resetting VF since it should be setup
|
||||
* only when VF creates its first FDIR rule.
|
||||
*/
|
||||
@ -2021,6 +2023,10 @@ static int ice_ena_vfs(struct ice_pf *pf, u16 num_vfs)
|
||||
if (ret)
|
||||
goto err_unroll_sriov;
|
||||
|
||||
/* rearm global interrupts */
|
||||
if (test_and_clear_bit(ICE_OICR_INTR_DIS, pf->state))
|
||||
ice_irq_dynamic_ena(hw, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unroll_sriov:
|
||||
|
@ -2960,11 +2960,11 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
|
||||
mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size);
|
||||
|
||||
if (priv->percpu_pools) {
|
||||
err = xdp_rxq_info_reg(&rxq->xdp_rxq_short, port->dev, rxq->id, 0);
|
||||
err = xdp_rxq_info_reg(&rxq->xdp_rxq_short, port->dev, rxq->logic_rxq, 0);
|
||||
if (err < 0)
|
||||
goto err_free_dma;
|
||||
|
||||
err = xdp_rxq_info_reg(&rxq->xdp_rxq_long, port->dev, rxq->id, 0);
|
||||
err = xdp_rxq_info_reg(&rxq->xdp_rxq_long, port->dev, rxq->logic_rxq, 0);
|
||||
if (err < 0)
|
||||
goto err_unregister_rxq_short;
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "otx2_common.h"
|
||||
#include "otx2_ptp.h"
|
||||
|
||||
|
@ -480,16 +480,16 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = mana_hwc_alloc_dma_buf(hwc, q_depth, max_msg_size,
|
||||
&hwc_wq->msg_buf);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
hwc_wq->hwc = hwc;
|
||||
hwc_wq->gdma_wq = queue;
|
||||
hwc_wq->queue_depth = q_depth;
|
||||
hwc_wq->hwc_cq = hwc_cq;
|
||||
|
||||
err = mana_hwc_alloc_dma_buf(hwc, q_depth, max_msg_size,
|
||||
&hwc_wq->msg_buf);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
*hwc_wq_ptr = hwc_wq;
|
||||
return 0;
|
||||
out:
|
||||
|
@ -803,8 +803,10 @@ int nfp_cpp_area_cache_add(struct nfp_cpp *cpp, size_t size)
|
||||
return -ENOMEM;
|
||||
|
||||
cache = kzalloc(sizeof(*cache), GFP_KERNEL);
|
||||
if (!cache)
|
||||
if (!cache) {
|
||||
nfp_cpp_area_free(area);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cache->id = 0;
|
||||
cache->addr = 0;
|
||||
|
@ -1643,6 +1643,13 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
data_split = true;
|
||||
}
|
||||
} else {
|
||||
if (unlikely(skb->len > ETH_TX_MAX_NON_LSO_PKT_LEN)) {
|
||||
DP_ERR(edev, "Unexpected non LSO skb length = 0x%x\n", skb->len);
|
||||
qede_free_failed_tx_pkt(txq, first_bd, 0, false);
|
||||
qede_update_tx_producer(txq);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
val |= ((skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) <<
|
||||
ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT);
|
||||
}
|
||||
|
@ -3480,20 +3480,19 @@ static int ql_adapter_up(struct ql3_adapter *qdev)
|
||||
|
||||
spin_lock_irqsave(&qdev->hw_lock, hw_flags);
|
||||
|
||||
err = ql_wait_for_drvr_lock(qdev);
|
||||
if (err) {
|
||||
err = ql_adapter_initialize(qdev);
|
||||
if (err) {
|
||||
netdev_err(ndev, "Unable to initialize adapter\n");
|
||||
goto err_init;
|
||||
}
|
||||
netdev_err(ndev, "Releasing driver lock\n");
|
||||
ql_sem_unlock(qdev, QL_DRVR_SEM_MASK);
|
||||
} else {
|
||||
if (!ql_wait_for_drvr_lock(qdev)) {
|
||||
netdev_err(ndev, "Could not acquire driver lock\n");
|
||||
err = -ENODEV;
|
||||
goto err_lock;
|
||||
}
|
||||
|
||||
err = ql_adapter_initialize(qdev);
|
||||
if (err) {
|
||||
netdev_err(ndev, "Unable to initialize adapter\n");
|
||||
goto err_init;
|
||||
}
|
||||
ql_sem_unlock(qdev, QL_DRVR_SEM_MASK);
|
||||
|
||||
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
|
||||
|
||||
set_bit(QL_ADAPTER_UP, &qdev->flags);
|
||||
|
@ -1388,6 +1388,7 @@ EXPORT_SYMBOL_GPL(phylink_stop);
|
||||
* @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan
|
||||
*
|
||||
* Handle a network device suspend event. There are several cases:
|
||||
*
|
||||
* - If Wake-on-Lan is not active, we can bring down the link between
|
||||
* the MAC and PHY by calling phylink_stop().
|
||||
* - If Wake-on-Lan is active, and being handled only by the PHY, we
|
||||
|
@ -181,6 +181,8 @@ static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx)
|
||||
min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32);
|
||||
|
||||
max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize));
|
||||
if (max == 0)
|
||||
max = CDC_NCM_NTB_MAX_SIZE_TX; /* dwNtbOutMaxSize not set */
|
||||
|
||||
/* some devices set dwNtbOutMaxSize too low for the above default */
|
||||
min = min(min, max);
|
||||
|
@ -3261,7 +3261,7 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (adapter->intr.type == VMXNET3_IT_MSIX) {
|
||||
int i, nvec;
|
||||
int i, nvec, nvec_allocated;
|
||||
|
||||
nvec = adapter->share_intr == VMXNET3_INTR_TXSHARE ?
|
||||
1 : adapter->num_tx_queues;
|
||||
@ -3274,14 +3274,15 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
|
||||
for (i = 0; i < nvec; i++)
|
||||
adapter->intr.msix_entries[i].entry = i;
|
||||
|
||||
nvec = vmxnet3_acquire_msix_vectors(adapter, nvec);
|
||||
if (nvec < 0)
|
||||
nvec_allocated = vmxnet3_acquire_msix_vectors(adapter, nvec);
|
||||
if (nvec_allocated < 0)
|
||||
goto msix_err;
|
||||
|
||||
/* If we cannot allocate one MSIx vector per queue
|
||||
* then limit the number of rx queues to 1
|
||||
*/
|
||||
if (nvec == VMXNET3_LINUX_MIN_MSIX_VECT) {
|
||||
if (nvec_allocated == VMXNET3_LINUX_MIN_MSIX_VECT &&
|
||||
nvec != VMXNET3_LINUX_MIN_MSIX_VECT) {
|
||||
if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE
|
||||
|| adapter->num_rx_queues != 1) {
|
||||
adapter->share_intr = VMXNET3_INTR_TXSHARE;
|
||||
@ -3291,14 +3292,14 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
|
||||
}
|
||||
}
|
||||
|
||||
adapter->intr.num_intrs = nvec;
|
||||
adapter->intr.num_intrs = nvec_allocated;
|
||||
return;
|
||||
|
||||
msix_err:
|
||||
/* If we cannot allocate MSIx vectors use only one rx queue */
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"Failed to enable MSI-X, error %d. "
|
||||
"Limiting #rx queues to 1, try MSI.\n", nvec);
|
||||
"Limiting #rx queues to 1, try MSI.\n", nvec_allocated);
|
||||
|
||||
adapter->intr.type = VMXNET3_IT_MSI;
|
||||
}
|
||||
|
@ -770,8 +770,6 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
|
||||
|
||||
skb->dev = vrf_dev;
|
||||
|
||||
vrf_nf_set_untracked(skb);
|
||||
|
||||
err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk,
|
||||
skb, NULL, vrf_dev, vrf_ip6_out_direct_finish);
|
||||
|
||||
@ -792,6 +790,8 @@ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
|
||||
if (rt6_need_strict(&ipv6_hdr(skb)->daddr))
|
||||
return skb;
|
||||
|
||||
vrf_nf_set_untracked(skb);
|
||||
|
||||
if (qdisc_tx_is_default(vrf_dev) ||
|
||||
IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
|
||||
return vrf_ip6_out_direct(vrf_dev, sk, skb);
|
||||
@ -1000,8 +1000,6 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
|
||||
|
||||
skb->dev = vrf_dev;
|
||||
|
||||
vrf_nf_set_untracked(skb);
|
||||
|
||||
err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk,
|
||||
skb, NULL, vrf_dev, vrf_ip_out_direct_finish);
|
||||
|
||||
@ -1023,6 +1021,8 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
|
||||
ipv4_is_lbcast(ip_hdr(skb)->daddr))
|
||||
return skb;
|
||||
|
||||
vrf_nf_set_untracked(skb);
|
||||
|
||||
if (qdisc_tx_is_default(vrf_dev) ||
|
||||
IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
|
||||
return vrf_ip_out_direct(vrf_dev, sk, skb);
|
||||
|
@ -181,9 +181,9 @@ void ipc_imem_hrtimer_stop(struct hrtimer *hr_timer)
|
||||
bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem)
|
||||
{
|
||||
struct ipc_mem_channel *channel;
|
||||
bool hpda_ctrl_pending = false;
|
||||
struct sk_buff_head *ul_list;
|
||||
bool hpda_pending = false;
|
||||
bool forced_hpdu = false;
|
||||
struct ipc_pipe *pipe;
|
||||
int i;
|
||||
|
||||
@ -200,15 +200,19 @@ bool ipc_imem_ul_write_td(struct iosm_imem *ipc_imem)
|
||||
ul_list = &channel->ul_list;
|
||||
|
||||
/* Fill the transfer descriptor with the uplink buffer info. */
|
||||
hpda_pending |= ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
|
||||
if (!ipc_imem_check_wwan_ips(channel)) {
|
||||
hpda_ctrl_pending |=
|
||||
ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
|
||||
pipe, ul_list);
|
||||
|
||||
/* forced HP update needed for non data channels */
|
||||
if (hpda_pending && !ipc_imem_check_wwan_ips(channel))
|
||||
forced_hpdu = true;
|
||||
} else {
|
||||
hpda_pending |=
|
||||
ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
|
||||
pipe, ul_list);
|
||||
}
|
||||
}
|
||||
|
||||
if (forced_hpdu) {
|
||||
/* forced HP update needed for non data channels */
|
||||
if (hpda_ctrl_pending) {
|
||||
hpda_pending = false;
|
||||
ipc_protocol_doorbell_trigger(ipc_imem->ipc_protocol,
|
||||
IPC_HP_UL_WRITE_TD);
|
||||
@ -527,6 +531,9 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
|
||||
return;
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag))
|
||||
ipc_devlink_deinit(ipc_imem->ipc_devlink);
|
||||
|
||||
if (!ipc_imem_setup_cp_mux_cap_init(ipc_imem, &mux_cfg))
|
||||
ipc_imem->mux = ipc_mux_init(&mux_cfg, ipc_imem);
|
||||
|
||||
@ -1167,7 +1174,7 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem)
|
||||
ipc_port_deinit(ipc_imem->ipc_port);
|
||||
}
|
||||
|
||||
if (ipc_imem->ipc_devlink)
|
||||
if (test_and_clear_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag))
|
||||
ipc_devlink_deinit(ipc_imem->ipc_devlink);
|
||||
|
||||
ipc_imem_device_ipc_uninit(ipc_imem);
|
||||
@ -1263,7 +1270,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
|
||||
|
||||
ipc_imem->pci_device_id = device_id;
|
||||
|
||||
ipc_imem->ev_cdev_write_pending = false;
|
||||
ipc_imem->cp_version = 0;
|
||||
ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP;
|
||||
|
||||
@ -1331,6 +1337,8 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
|
||||
|
||||
if (ipc_flash_link_establish(ipc_imem))
|
||||
goto devlink_channel_fail;
|
||||
|
||||
set_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag);
|
||||
}
|
||||
return ipc_imem;
|
||||
devlink_channel_fail:
|
||||
|
@ -101,6 +101,7 @@ struct ipc_chnl_cfg;
|
||||
#define IOSM_CHIP_INFO_SIZE_MAX 100
|
||||
|
||||
#define FULLY_FUNCTIONAL 0
|
||||
#define IOSM_DEVLINK_INIT 1
|
||||
|
||||
/* List of the supported UL/DL pipes. */
|
||||
enum ipc_mem_pipes {
|
||||
@ -335,8 +336,6 @@ enum ipc_phase {
|
||||
* process the irq actions.
|
||||
* @flag: Flag to monitor the state of driver
|
||||
* @td_update_timer_suspended: if true then td update timer suspend
|
||||
* @ev_cdev_write_pending: 0 means inform the IPC tasklet to pass
|
||||
* the accumulated uplink buffers to CP.
|
||||
* @ev_mux_net_transmit_pending:0 means inform the IPC tasklet to pass
|
||||
* @reset_det_n: Reset detect flag
|
||||
* @pcie_wake_n: Pcie wake flag
|
||||
@ -374,7 +373,6 @@ struct iosm_imem {
|
||||
u8 ev_irq_pending[IPC_IRQ_VECTORS];
|
||||
unsigned long flag;
|
||||
u8 td_update_timer_suspended:1,
|
||||
ev_cdev_write_pending:1,
|
||||
ev_mux_net_transmit_pending:1,
|
||||
reset_det_n:1,
|
||||
pcie_wake_n:1;
|
||||
|
@ -41,7 +41,6 @@ void ipc_imem_sys_wwan_close(struct iosm_imem *ipc_imem, int if_id,
|
||||
static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg,
|
||||
void *msg, size_t size)
|
||||
{
|
||||
ipc_imem->ev_cdev_write_pending = false;
|
||||
ipc_imem_ul_send(ipc_imem);
|
||||
|
||||
return 0;
|
||||
@ -50,11 +49,6 @@ static int ipc_imem_tq_cdev_write(struct iosm_imem *ipc_imem, int arg,
|
||||
/* Through tasklet to do sio write. */
|
||||
static int ipc_imem_call_cdev_write(struct iosm_imem *ipc_imem)
|
||||
{
|
||||
if (ipc_imem->ev_cdev_write_pending)
|
||||
return -1;
|
||||
|
||||
ipc_imem->ev_cdev_write_pending = true;
|
||||
|
||||
return ipc_task_queue_send_task(ipc_imem, ipc_imem_tq_cdev_write, 0,
|
||||
NULL, 0, false);
|
||||
}
|
||||
@ -450,6 +444,7 @@ void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink)
|
||||
/* Release the pipe resources */
|
||||
ipc_imem_pipe_cleanup(ipc_imem, &channel->ul_pipe);
|
||||
ipc_imem_pipe_cleanup(ipc_imem, &channel->dl_pipe);
|
||||
ipc_imem->nr_of_channels--;
|
||||
}
|
||||
|
||||
void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "pcie-designware.h"
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "pcie-designware.h"
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include "core.h"
|
||||
#include "drd.h"
|
||||
#include "host-export.h"
|
||||
|
@ -732,6 +732,7 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr)
|
||||
struct bpf_trampoline *bpf_trampoline_get(u64 key,
|
||||
struct bpf_attach_target_info *tgt_info);
|
||||
void bpf_trampoline_put(struct bpf_trampoline *tr);
|
||||
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
|
||||
#define BPF_DISPATCHER_INIT(_name) { \
|
||||
.mutex = __MUTEX_INITIALIZER(_name.mutex), \
|
||||
.func = &_name##_func, \
|
||||
@ -1352,28 +1353,16 @@ extern struct mutex bpf_stats_enabled_mutex;
|
||||
* kprobes, tracepoints) to prevent deadlocks on map operations as any of
|
||||
* these events can happen inside a region which holds a map bucket lock
|
||||
* and can deadlock on it.
|
||||
*
|
||||
* Use the preemption safe inc/dec variants on RT because migrate disable
|
||||
* is preemptible on RT and preemption in the middle of the RMW operation
|
||||
* might lead to inconsistent state. Use the raw variants for non RT
|
||||
* kernels as migrate_disable() maps to preempt_disable() so the slightly
|
||||
* more expensive save operation can be avoided.
|
||||
*/
|
||||
static inline void bpf_disable_instrumentation(void)
|
||||
{
|
||||
migrate_disable();
|
||||
if (IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
this_cpu_inc(bpf_prog_active);
|
||||
else
|
||||
__this_cpu_inc(bpf_prog_active);
|
||||
this_cpu_inc(bpf_prog_active);
|
||||
}
|
||||
|
||||
static inline void bpf_enable_instrumentation(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||
this_cpu_dec(bpf_prog_active);
|
||||
else
|
||||
__this_cpu_dec(bpf_prog_active);
|
||||
this_cpu_dec(bpf_prog_active);
|
||||
migrate_enable();
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,10 @@ struct kfunc_btf_id_set {
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
struct kfunc_btf_id_list;
|
||||
struct kfunc_btf_id_list {
|
||||
struct list_head list;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
|
||||
void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
|
||||
@ -254,6 +257,9 @@ void unregister_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
|
||||
struct kfunc_btf_id_set *s);
|
||||
bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id,
|
||||
struct module *owner);
|
||||
|
||||
extern struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list;
|
||||
extern struct kfunc_btf_id_list prog_test_kfunc_list;
|
||||
#else
|
||||
static inline void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
|
||||
struct kfunc_btf_id_set *s)
|
||||
@ -268,13 +274,13 @@ static inline bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list __maybe_unused;
|
||||
static struct kfunc_btf_id_list prog_test_kfunc_list __maybe_unused;
|
||||
#endif
|
||||
|
||||
#define DEFINE_KFUNC_BTF_ID_SET(set, name) \
|
||||
struct kfunc_btf_id_set name = { LIST_HEAD_INIT(name.list), (set), \
|
||||
THIS_MODULE }
|
||||
|
||||
extern struct kfunc_btf_id_list bpf_tcp_ca_kfunc_list;
|
||||
extern struct kfunc_btf_id_list prog_test_kfunc_list;
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,6 @@
|
||||
#define _LINUX_CACHEINFO_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/klist.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/device/bus.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/**
|
||||
* enum probe_type - device driver probe type to try
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define __LINUX_FILTER_H__
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/skbuff.h>
|
||||
@ -26,7 +27,6 @@
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <uapi/linux/filter.h>
|
||||
#include <uapi/linux/bpf.h>
|
||||
|
||||
struct sk_buff;
|
||||
struct sock;
|
||||
@ -640,9 +640,6 @@ static __always_inline u32 bpf_prog_run(const struct bpf_prog *prog, const void
|
||||
* This uses migrate_disable/enable() explicitly to document that the
|
||||
* invocation of a BPF program does not require reentrancy protection
|
||||
* against a BPF program which is invoked from a preempting task.
|
||||
*
|
||||
* For non RT enabled kernels migrate_disable/enable() maps to
|
||||
* preempt_disable/enable(), i.e. it disables also preemption.
|
||||
*/
|
||||
static inline u32 bpf_prog_run_pin_on_cpu(const struct bpf_prog *prog,
|
||||
const void *ctx)
|
||||
|
@ -538,11 +538,12 @@ struct macsec_ops;
|
||||
* @mac_managed_pm: Set true if MAC driver takes of suspending/resuming PHY
|
||||
* @state: State of the PHY for management purposes
|
||||
* @dev_flags: Device-specific flags used by the PHY driver.
|
||||
* Bits [15:0] are free to use by the PHY driver to communicate
|
||||
* driver specific behavior.
|
||||
* Bits [23:16] are currently reserved for future use.
|
||||
* Bits [31:24] are reserved for defining generic
|
||||
* PHY driver behavior.
|
||||
*
|
||||
* - Bits [15:0] are free to use by the PHY driver to communicate
|
||||
* driver specific behavior.
|
||||
* - Bits [23:16] are currently reserved for future use.
|
||||
* - Bits [31:24] are reserved for defining generic
|
||||
* PHY driver behavior.
|
||||
* @irq: IRQ number of the PHY's interrupt (-1 if none)
|
||||
* @phy_timer: The timer for handling the state machine
|
||||
* @phylink: Pointer to phylink instance for this PHY
|
||||
|
@ -126,7 +126,7 @@ struct tlb_slave_info {
|
||||
struct alb_bond_info {
|
||||
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
|
||||
u32 unbalanced_load;
|
||||
int tx_rebalance_counter;
|
||||
atomic_t tx_rebalance_counter;
|
||||
int lp_counter;
|
||||
/* -------- rlb parameters -------- */
|
||||
int rlb_enabled;
|
||||
|
@ -136,6 +136,19 @@ static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb)
|
||||
sk_rx_queue_update(sk, skb);
|
||||
}
|
||||
|
||||
/* Variant of sk_mark_napi_id() for passive flow setup,
|
||||
* as sk->sk_napi_id and sk->sk_rx_queue_mapping content
|
||||
* needs to be set.
|
||||
*/
|
||||
static inline void sk_mark_napi_id_set(struct sock *sk,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
WRITE_ONCE(sk->sk_napi_id, skb->napi_id);
|
||||
#endif
|
||||
sk_rx_queue_set(sk, skb);
|
||||
}
|
||||
|
||||
static inline void __sk_mark_napi_id_once(struct sock *sk, unsigned int napi_id)
|
||||
{
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
|
@ -276,14 +276,14 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
|
||||
/* jiffies until ct expires, 0 if already expired */
|
||||
static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
|
||||
{
|
||||
s32 timeout = ct->timeout - nfct_time_stamp;
|
||||
s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
|
||||
|
||||
return timeout > 0 ? timeout : 0;
|
||||
}
|
||||
|
||||
static inline bool nf_ct_is_expired(const struct nf_conn *ct)
|
||||
{
|
||||
return (__s32)(ct->timeout - nfct_time_stamp) <= 0;
|
||||
return (__s32)(READ_ONCE(ct->timeout) - nfct_time_stamp) <= 0;
|
||||
}
|
||||
|
||||
/* use after obtaining a reference count */
|
||||
@ -302,7 +302,7 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
|
||||
static inline void nf_ct_offload_timeout(struct nf_conn *ct)
|
||||
{
|
||||
if (nf_ct_expires(ct) < NF_CT_DAY / 2)
|
||||
ct->timeout = nfct_time_stamp + NF_CT_DAY;
|
||||
WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);
|
||||
}
|
||||
|
||||
struct kernel_param;
|
||||
|
@ -6346,11 +6346,6 @@ BTF_ID_LIST_GLOBAL_SINGLE(btf_task_struct_ids, struct, task_struct)
|
||||
|
||||
/* BTF ID set registration API for modules */
|
||||
|
||||
struct kfunc_btf_id_list {
|
||||
struct list_head list;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
|
||||
|
||||
void register_kfunc_btf_id_set(struct kfunc_btf_id_list *l,
|
||||
@ -6376,8 +6371,6 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id,
|
||||
{
|
||||
struct kfunc_btf_id_set *s;
|
||||
|
||||
if (!owner)
|
||||
return false;
|
||||
mutex_lock(&klist->mutex);
|
||||
list_for_each_entry(s, &klist->list, list) {
|
||||
if (s->owner == owner && btf_id_set_contains(s->set, kfunc_id)) {
|
||||
@ -6389,8 +6382,6 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define DEFINE_KFUNC_BTF_ID_LIST(name) \
|
||||
struct kfunc_btf_id_list name = { LIST_HEAD_INIT(name.list), \
|
||||
__MUTEX_INITIALIZER(name.mutex) }; \
|
||||
@ -6398,3 +6389,5 @@ bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id,
|
||||
|
||||
DEFINE_KFUNC_BTF_ID_LIST(bpf_tcp_ca_kfunc_list);
|
||||
DEFINE_KFUNC_BTF_ID_LIST(prog_test_kfunc_list);
|
||||
|
||||
#endif
|
||||
|
@ -8422,7 +8422,7 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
|
||||
|
||||
new_range = dst_reg->off;
|
||||
if (range_right_open)
|
||||
new_range--;
|
||||
new_range++;
|
||||
|
||||
/* Examples for register markings:
|
||||
*
|
||||
|
@ -316,6 +316,7 @@ config DEBUG_INFO_BTF
|
||||
bool "Generate BTF typeinfo"
|
||||
depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED
|
||||
depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST
|
||||
depends on BPF_SYSCALL
|
||||
help
|
||||
Generate deduplicated BTF type information from DWARF debug info.
|
||||
Turning this on expects presence of pahole tool, which will convert
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/mmu_notifier.h>
|
||||
#include <linux/page_idle.h>
|
||||
#include <linux/pagewalk.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include "prmtv-common.h"
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/compaction.h>
|
||||
#include <linux/rmap.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <linux/swap_slots.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mm.h>
|
||||
|
@ -4110,14 +4110,6 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
|
||||
info->attrs[DEVLINK_ATTR_NETNS_FD] ||
|
||||
info->attrs[DEVLINK_ATTR_NETNS_ID]) {
|
||||
dest_net = devlink_netns_get(skb, info);
|
||||
if (IS_ERR(dest_net))
|
||||
return PTR_ERR(dest_net);
|
||||
}
|
||||
|
||||
if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
|
||||
action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
|
||||
else
|
||||
@ -4160,6 +4152,14 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
|
||||
info->attrs[DEVLINK_ATTR_NETNS_FD] ||
|
||||
info->attrs[DEVLINK_ATTR_NETNS_ID]) {
|
||||
dest_net = devlink_netns_get(skb, info);
|
||||
if (IS_ERR(dest_net))
|
||||
return PTR_ERR(dest_net);
|
||||
}
|
||||
|
||||
err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
|
||||
|
||||
if (dest_net)
|
||||
|
@ -763,11 +763,10 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL);
|
||||
n = kzalloc(sizeof(*n) + key_len, GFP_KERNEL);
|
||||
if (!n)
|
||||
goto out;
|
||||
|
||||
n->protocol = 0;
|
||||
write_pnet(&n->net, net);
|
||||
memcpy(n->key, pkey, key_len);
|
||||
n->dev = dev;
|
||||
|
@ -1124,6 +1124,8 @@ void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock)
|
||||
|
||||
void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock)
|
||||
{
|
||||
psock_set_prog(&psock->progs.stream_parser, NULL);
|
||||
|
||||
if (!psock->saved_data_ready)
|
||||
return;
|
||||
|
||||
@ -1212,6 +1214,9 @@ void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock)
|
||||
|
||||
void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock)
|
||||
{
|
||||
psock_set_prog(&psock->progs.stream_verdict, NULL);
|
||||
psock_set_prog(&psock->progs.skb_verdict, NULL);
|
||||
|
||||
if (!psock->saved_data_ready)
|
||||
return;
|
||||
|
||||
|
@ -167,8 +167,11 @@ static void sock_map_del_link(struct sock *sk,
|
||||
write_lock_bh(&sk->sk_callback_lock);
|
||||
if (strp_stop)
|
||||
sk_psock_stop_strp(sk, psock);
|
||||
else
|
||||
if (verdict_stop)
|
||||
sk_psock_stop_verdict(sk, psock);
|
||||
|
||||
if (psock->psock_update_sk_prot)
|
||||
psock->psock_update_sk_prot(sk, psock, false);
|
||||
write_unlock_bh(&sk->sk_callback_lock);
|
||||
}
|
||||
}
|
||||
@ -282,6 +285,12 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
|
||||
|
||||
if (msg_parser)
|
||||
psock_set_prog(&psock->progs.msg_parser, msg_parser);
|
||||
if (stream_parser)
|
||||
psock_set_prog(&psock->progs.stream_parser, stream_parser);
|
||||
if (stream_verdict)
|
||||
psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
|
||||
if (skb_verdict)
|
||||
psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
|
||||
|
||||
ret = sock_map_init_proto(sk, psock);
|
||||
if (ret < 0)
|
||||
@ -292,14 +301,10 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
|
||||
ret = sk_psock_init_strp(sk, psock);
|
||||
if (ret)
|
||||
goto out_unlock_drop;
|
||||
psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
|
||||
psock_set_prog(&psock->progs.stream_parser, stream_parser);
|
||||
sk_psock_start_strp(sk, psock);
|
||||
} else if (!stream_parser && stream_verdict && !psock->saved_data_ready) {
|
||||
psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
|
||||
sk_psock_start_verdict(sk,psock);
|
||||
} else if (!stream_verdict && skb_verdict && !psock->saved_data_ready) {
|
||||
psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
|
||||
sk_psock_start_verdict(sk, psock);
|
||||
}
|
||||
write_unlock_bh(&sk->sk_callback_lock);
|
||||
|
@ -40,7 +40,8 @@ int ethnl_ops_begin(struct net_device *dev)
|
||||
if (dev->dev.parent)
|
||||
pm_runtime_get_sync(dev->dev.parent);
|
||||
|
||||
if (!netif_device_present(dev)) {
|
||||
if (!netif_device_present(dev) ||
|
||||
dev->reg_state == NETREG_UNREGISTERING) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
@ -721,7 +721,7 @@ static struct request_sock *inet_reqsk_clone(struct request_sock *req,
|
||||
|
||||
sk_node_init(&nreq_sk->sk_node);
|
||||
nreq_sk->sk_tx_queue_mapping = req_sk->sk_tx_queue_mapping;
|
||||
#ifdef CONFIG_XPS
|
||||
#ifdef CONFIG_SOCK_RX_QUEUE_MAPPING
|
||||
nreq_sk->sk_rx_queue_mapping = req_sk->sk_rx_queue_mapping;
|
||||
#endif
|
||||
nreq_sk->sk_incoming_cpu = req_sk->sk_incoming_cpu;
|
||||
|
@ -829,8 +829,8 @@ int tcp_child_process(struct sock *parent, struct sock *child,
|
||||
int ret = 0;
|
||||
int state = child->sk_state;
|
||||
|
||||
/* record NAPI ID of child */
|
||||
sk_mark_napi_id(child, skb);
|
||||
/* record sk_napi_id and sk_rx_queue_mapping of child. */
|
||||
sk_mark_napi_id_set(child, skb);
|
||||
|
||||
tcp_segs_in(tcp_sk(child), skb);
|
||||
if (!sock_owned_by_user(child)) {
|
||||
|
@ -916,7 +916,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) {
|
||||
if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) {
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -161,6 +161,14 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
|
||||
hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));
|
||||
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
|
||||
/* the control block has been erased, so we have to set the
|
||||
* iif once again.
|
||||
* We read the receiving interface index directly from the
|
||||
* skb->skb_iif as it is done in the IPv4 receiving path (i.e.:
|
||||
* ip_rcv_core(...)).
|
||||
*/
|
||||
IP6CB(skb)->iif = skb->skb_iif;
|
||||
}
|
||||
|
||||
hdr->nexthdr = NEXTHDR_ROUTING;
|
||||
|
@ -684,7 +684,7 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
|
||||
|
||||
tstamp = nf_conn_tstamp_find(ct);
|
||||
if (tstamp) {
|
||||
s32 timeout = ct->timeout - nfct_time_stamp;
|
||||
s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
|
||||
|
||||
tstamp->stop = ktime_get_real_ns();
|
||||
if (timeout < 0)
|
||||
@ -1036,7 +1036,7 @@ static int nf_ct_resolve_clash_harder(struct sk_buff *skb, u32 repl_idx)
|
||||
}
|
||||
|
||||
/* We want the clashing entry to go away real soon: 1 second timeout. */
|
||||
loser_ct->timeout = nfct_time_stamp + HZ;
|
||||
WRITE_ONCE(loser_ct->timeout, nfct_time_stamp + HZ);
|
||||
|
||||
/* IPS_NAT_CLASH removes the entry automatically on the first
|
||||
* reply. Also prevents UDP tracker from moving the entry to
|
||||
@ -1560,7 +1560,7 @@ __nf_conntrack_alloc(struct net *net,
|
||||
/* save hash for reusing when confirming */
|
||||
*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
|
||||
ct->status = 0;
|
||||
ct->timeout = 0;
|
||||
WRITE_ONCE(ct->timeout, 0);
|
||||
write_pnet(&ct->ct_net, net);
|
||||
memset(&ct->__nfct_init_offset, 0,
|
||||
offsetof(struct nf_conn, proto) -
|
||||
|
@ -1998,7 +1998,7 @@ static int ctnetlink_change_timeout(struct nf_conn *ct,
|
||||
|
||||
if (timeout > INT_MAX)
|
||||
timeout = INT_MAX;
|
||||
ct->timeout = nfct_time_stamp + (u32)timeout;
|
||||
WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);
|
||||
|
||||
if (test_bit(IPS_DYING_BIT, &ct->status))
|
||||
return -ETIME;
|
||||
|
@ -201,8 +201,8 @@ static void flow_offload_fixup_ct_timeout(struct nf_conn *ct)
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
|
||||
if (nf_flow_timeout_delta(ct->timeout) > (__s32)timeout)
|
||||
ct->timeout = nfct_time_stamp + timeout;
|
||||
if (nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout)
|
||||
WRITE_ONCE(ct->timeout, nfct_time_stamp + timeout);
|
||||
}
|
||||
|
||||
static void flow_offload_fixup_ct_state(struct nf_conn *ct)
|
||||
|
@ -387,7 +387,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
struct net_device *indev;
|
||||
struct net_device *outdev;
|
||||
struct nf_conn *ct = NULL;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
enum ip_conntrack_info ctinfo = 0;
|
||||
struct nfnl_ct_hook *nfnl_ct;
|
||||
bool csum_verify;
|
||||
char *secdata = NULL;
|
||||
|
@ -236,7 +236,7 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
|
||||
|
||||
tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len);
|
||||
if (!tcph)
|
||||
return;
|
||||
goto err;
|
||||
|
||||
opt = (u8 *)tcph;
|
||||
for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {
|
||||
@ -251,16 +251,16 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
|
||||
continue;
|
||||
|
||||
if (i + optl > tcphdr_len || priv->len + priv->offset > optl)
|
||||
return;
|
||||
goto err;
|
||||
|
||||
if (skb_ensure_writable(pkt->skb,
|
||||
nft_thoff(pkt) + i + priv->len))
|
||||
return;
|
||||
goto err;
|
||||
|
||||
tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff,
|
||||
&tcphdr_len);
|
||||
if (!tcph)
|
||||
return;
|
||||
goto err;
|
||||
|
||||
offset = i + priv->offset;
|
||||
|
||||
@ -303,6 +303,9 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
err:
|
||||
regs->verdict.code = NFT_BREAK;
|
||||
}
|
||||
|
||||
static void nft_exthdr_sctp_eval(const struct nft_expr *expr,
|
||||
|
@ -886,7 +886,7 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill,
|
||||
NFT_PIPAPO_AVX2_BUCKET_LOAD8(4, lt, 4, pkt[4], bsize);
|
||||
|
||||
NFT_PIPAPO_AVX2_AND(5, 0, 1);
|
||||
NFT_PIPAPO_AVX2_BUCKET_LOAD8(6, lt, 6, pkt[5], bsize);
|
||||
NFT_PIPAPO_AVX2_BUCKET_LOAD8(6, lt, 5, pkt[5], bsize);
|
||||
NFT_PIPAPO_AVX2_AND(7, 2, 3);
|
||||
|
||||
/* Stall */
|
||||
|
@ -636,8 +636,10 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
|
||||
{
|
||||
struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
|
||||
|
||||
nfc_device_iter_exit(iter);
|
||||
kfree(iter);
|
||||
if (iter) {
|
||||
nfc_device_iter_exit(iter);
|
||||
kfree(iter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1392,8 +1394,10 @@ static int nfc_genl_dump_ses_done(struct netlink_callback *cb)
|
||||
{
|
||||
struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
|
||||
|
||||
nfc_device_iter_exit(iter);
|
||||
kfree(iter);
|
||||
if (iter) {
|
||||
nfc_device_iter_exit(iter);
|
||||
kfree(iter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -531,6 +531,7 @@ static void fq_pie_destroy(struct Qdisc *sch)
|
||||
struct fq_pie_sched_data *q = qdisc_priv(sch);
|
||||
|
||||
tcf_block_put(q->block);
|
||||
q->p_params.tupdate = 0;
|
||||
del_timer_sync(&q->adapt_timer);
|
||||
kvfree(q->flows);
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ struct btf_id {
|
||||
int cnt;
|
||||
};
|
||||
int addr_cnt;
|
||||
bool is_set;
|
||||
Elf64_Addr addr[ADDR_CNT];
|
||||
};
|
||||
|
||||
@ -451,8 +452,10 @@ static int symbols_collect(struct object *obj)
|
||||
* in symbol's size, together with 'cnt' field hence
|
||||
* that - 1.
|
||||
*/
|
||||
if (id)
|
||||
if (id) {
|
||||
id->cnt = sym.st_size / sizeof(int) - 1;
|
||||
id->is_set = true;
|
||||
}
|
||||
} else {
|
||||
pr_err("FAILED unsupported prefix %s\n", prefix);
|
||||
return -1;
|
||||
@ -568,9 +571,8 @@ static int id_patch(struct object *obj, struct btf_id *id)
|
||||
int *ptr = data->d_buf;
|
||||
int i;
|
||||
|
||||
if (!id->id) {
|
||||
if (!id->id && !id->is_set)
|
||||
pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
|
||||
}
|
||||
|
||||
for (i = 0; i < id->addr_cnt; i++) {
|
||||
unsigned long addr = id->addr[i];
|
||||
|
@ -35,7 +35,7 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' > pkt_end, good access",
|
||||
"XDP pkt read, pkt_data' > pkt_end, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
@ -87,6 +87,41 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' > pkt_end, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' > pkt_end, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end > pkt_data', good access",
|
||||
.insns = {
|
||||
@ -106,16 +141,16 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end > pkt_data', bad access 1",
|
||||
"XDP pkt read, pkt_end > pkt_data', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -142,6 +177,42 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end > pkt_data', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end > pkt_data', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' < pkt_end, good access",
|
||||
.insns = {
|
||||
@ -161,16 +232,16 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' < pkt_end, bad access 1",
|
||||
"XDP pkt read, pkt_data' < pkt_end, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -198,7 +269,43 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end < pkt_data', good access",
|
||||
"XDP pkt read, pkt_data' < pkt_end, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' < pkt_end, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end < pkt_data', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
@ -250,6 +357,41 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end < pkt_data', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end < pkt_data', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' >= pkt_end, good access",
|
||||
.insns = {
|
||||
@ -268,15 +410,15 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' >= pkt_end, bad access 1",
|
||||
"XDP pkt read, pkt_data' >= pkt_end, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -304,7 +446,41 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end >= pkt_data', good access",
|
||||
"XDP pkt read, pkt_data' >= pkt_end, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' >= pkt_end, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end >= pkt_data', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
@ -359,7 +535,44 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' <= pkt_end, good access",
|
||||
"XDP pkt read, pkt_end >= pkt_data', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end >= pkt_data', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' <= pkt_end, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
@ -413,6 +626,43 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' <= pkt_end, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data' <= pkt_end, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end <= pkt_data', good access",
|
||||
.insns = {
|
||||
@ -431,15 +681,15 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end <= pkt_data', bad access 1",
|
||||
"XDP pkt read, pkt_end <= pkt_data', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -467,7 +717,41 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' > pkt_data, good access",
|
||||
"XDP pkt read, pkt_end <= pkt_data', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_end <= pkt_data', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_end)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' > pkt_data, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
@ -519,6 +803,41 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' > pkt_data, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' > pkt_data, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data > pkt_meta', good access",
|
||||
.insns = {
|
||||
@ -538,16 +857,16 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data > pkt_meta', bad access 1",
|
||||
"XDP pkt read, pkt_data > pkt_meta', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -574,6 +893,42 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data > pkt_meta', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data > pkt_meta', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' < pkt_data, good access",
|
||||
.insns = {
|
||||
@ -593,16 +948,16 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' < pkt_data, bad access 1",
|
||||
"XDP pkt read, pkt_meta' < pkt_data, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -630,7 +985,43 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data < pkt_meta', good access",
|
||||
"XDP pkt read, pkt_meta' < pkt_data, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' < pkt_data, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data < pkt_meta', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
@ -682,6 +1073,41 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data < pkt_meta', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data < pkt_meta', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' >= pkt_data, good access",
|
||||
.insns = {
|
||||
@ -700,15 +1126,15 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' >= pkt_data, bad access 1",
|
||||
"XDP pkt read, pkt_meta' >= pkt_data, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -736,7 +1162,41 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data >= pkt_meta', good access",
|
||||
"XDP pkt read, pkt_meta' >= pkt_data, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' >= pkt_data, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data >= pkt_meta', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
@ -791,7 +1251,44 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' <= pkt_data, good access",
|
||||
"XDP pkt read, pkt_data >= pkt_meta', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data >= pkt_meta', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' <= pkt_data, corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
@ -845,6 +1342,43 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' <= pkt_data, corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 9),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -9),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_meta' <= pkt_data, corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1),
|
||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "R1 offset is outside of the packet",
|
||||
.result = REJECT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data <= pkt_meta', good access",
|
||||
.insns = {
|
||||
@ -863,15 +1397,15 @@
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data <= pkt_meta', bad access 1",
|
||||
"XDP pkt read, pkt_data <= pkt_meta', corner case -1, bad access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
@ -898,3 +1432,37 @@
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data <= pkt_meta', corner case, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 7),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -7),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
{
|
||||
"XDP pkt read, pkt_data <= pkt_meta', corner case +1, good access",
|
||||
.insns = {
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
|
||||
offsetof(struct xdp_md, data_meta)),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
|
||||
},
|
||||
|
@ -4077,3 +4077,11 @@ cleanup 2>/dev/null
|
||||
|
||||
printf "\nTests passed: %3d\n" ${nsuccess}
|
||||
printf "Tests failed: %3d\n" ${nfail}
|
||||
|
||||
if [ $nfail -ne 0 ]; then
|
||||
exit 1 # KSFT_FAIL
|
||||
elif [ $nsuccess -eq 0 ]; then
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
exit 0 # KSFT_PASS
|
||||
|
@ -444,24 +444,63 @@ fib_rp_filter_test()
|
||||
setup
|
||||
|
||||
set -e
|
||||
ip netns add ns2
|
||||
ip netns set ns2 auto
|
||||
|
||||
ip -netns ns2 link set dev lo up
|
||||
|
||||
$IP link add name veth1 type veth peer name veth2
|
||||
$IP link set dev veth2 netns ns2
|
||||
$IP address add 192.0.2.1/24 dev veth1
|
||||
ip -netns ns2 address add 192.0.2.1/24 dev veth2
|
||||
$IP link set dev veth1 up
|
||||
ip -netns ns2 link set dev veth2 up
|
||||
|
||||
$IP link set dev lo address 52:54:00:6a:c7:5e
|
||||
$IP link set dummy0 address 52:54:00:6a:c7:5e
|
||||
$IP link add dummy1 type dummy
|
||||
$IP link set dummy1 address 52:54:00:6a:c7:5e
|
||||
$IP link set dev dummy1 up
|
||||
$IP link set dev veth1 address 52:54:00:6a:c7:5e
|
||||
ip -netns ns2 link set dev lo address 52:54:00:6a:c7:5e
|
||||
ip -netns ns2 link set dev veth2 address 52:54:00:6a:c7:5e
|
||||
|
||||
# 1. (ns2) redirect lo's egress to veth2's egress
|
||||
ip netns exec ns2 tc qdisc add dev lo parent root handle 1: fq_codel
|
||||
ip netns exec ns2 tc filter add dev lo parent 1: protocol arp basic \
|
||||
action mirred egress redirect dev veth2
|
||||
ip netns exec ns2 tc filter add dev lo parent 1: protocol ip basic \
|
||||
action mirred egress redirect dev veth2
|
||||
|
||||
# 2. (ns1) redirect veth1's ingress to lo's ingress
|
||||
$NS_EXEC tc qdisc add dev veth1 ingress
|
||||
$NS_EXEC tc filter add dev veth1 ingress protocol arp basic \
|
||||
action mirred ingress redirect dev lo
|
||||
$NS_EXEC tc filter add dev veth1 ingress protocol ip basic \
|
||||
action mirred ingress redirect dev lo
|
||||
|
||||
# 3. (ns1) redirect lo's egress to veth1's egress
|
||||
$NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel
|
||||
$NS_EXEC tc filter add dev lo parent 1: protocol arp basic \
|
||||
action mirred egress redirect dev veth1
|
||||
$NS_EXEC tc filter add dev lo parent 1: protocol ip basic \
|
||||
action mirred egress redirect dev veth1
|
||||
|
||||
# 4. (ns2) redirect veth2's ingress to lo's ingress
|
||||
ip netns exec ns2 tc qdisc add dev veth2 ingress
|
||||
ip netns exec ns2 tc filter add dev veth2 ingress protocol arp basic \
|
||||
action mirred ingress redirect dev lo
|
||||
ip netns exec ns2 tc filter add dev veth2 ingress protocol ip basic \
|
||||
action mirred ingress redirect dev lo
|
||||
|
||||
$NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
|
||||
$NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
|
||||
$NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
|
||||
|
||||
$NS_EXEC tc qd add dev dummy1 parent root handle 1: fq_codel
|
||||
$NS_EXEC tc filter add dev dummy1 parent 1: protocol arp basic action mirred egress redirect dev lo
|
||||
$NS_EXEC tc filter add dev dummy1 parent 1: protocol ip basic action mirred egress redirect dev lo
|
||||
ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1
|
||||
ip netns exec ns2 sysctl -qw net.ipv4.conf.all.accept_local=1
|
||||
ip netns exec ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1
|
||||
set +e
|
||||
|
||||
run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 198.51.100.1"
|
||||
run_cmd "ip netns exec ns2 ping -w1 -c1 192.0.2.1"
|
||||
log_test $? 0 "rp_filter passes local packets"
|
||||
|
||||
run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 127.0.0.1"
|
||||
run_cmd "ip netns exec ns2 ping -w1 -c1 127.0.0.1"
|
||||
log_test $? 0 "rp_filter passes loopback packets"
|
||||
|
||||
cleanup
|
||||
|
@ -31,6 +31,8 @@ struct tls_crypto_info_keys {
|
||||
struct tls12_crypto_info_chacha20_poly1305 chacha20;
|
||||
struct tls12_crypto_info_sm4_gcm sm4gcm;
|
||||
struct tls12_crypto_info_sm4_ccm sm4ccm;
|
||||
struct tls12_crypto_info_aes_ccm_128 aesccm128;
|
||||
struct tls12_crypto_info_aes_gcm_256 aesgcm256;
|
||||
};
|
||||
size_t len;
|
||||
};
|
||||
@ -61,6 +63,16 @@ static void tls_crypto_info_init(uint16_t tls_version, uint16_t cipher_type,
|
||||
tls12->sm4ccm.info.version = tls_version;
|
||||
tls12->sm4ccm.info.cipher_type = cipher_type;
|
||||
break;
|
||||
case TLS_CIPHER_AES_CCM_128:
|
||||
tls12->len = sizeof(struct tls12_crypto_info_aes_ccm_128);
|
||||
tls12->aesccm128.info.version = tls_version;
|
||||
tls12->aesccm128.info.cipher_type = cipher_type;
|
||||
break;
|
||||
case TLS_CIPHER_AES_GCM_256:
|
||||
tls12->len = sizeof(struct tls12_crypto_info_aes_gcm_256);
|
||||
tls12->aesgcm256.info.version = tls_version;
|
||||
tls12->aesgcm256.info.cipher_type = cipher_type;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -261,6 +273,30 @@ FIXTURE_VARIANT_ADD(tls, 13_sm4_ccm)
|
||||
.cipher_type = TLS_CIPHER_SM4_CCM,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(tls, 12_aes_ccm)
|
||||
{
|
||||
.tls_version = TLS_1_2_VERSION,
|
||||
.cipher_type = TLS_CIPHER_AES_CCM_128,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(tls, 13_aes_ccm)
|
||||
{
|
||||
.tls_version = TLS_1_3_VERSION,
|
||||
.cipher_type = TLS_CIPHER_AES_CCM_128,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(tls, 12_aes_gcm_256)
|
||||
{
|
||||
.tls_version = TLS_1_2_VERSION,
|
||||
.cipher_type = TLS_CIPHER_AES_GCM_256,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(tls, 13_aes_gcm_256)
|
||||
{
|
||||
.tls_version = TLS_1_3_VERSION,
|
||||
.cipher_type = TLS_CIPHER_AES_GCM_256,
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(tls)
|
||||
{
|
||||
struct tls_crypto_info_keys tls12;
|
||||
|
@ -150,11 +150,27 @@ EOF
|
||||
# oifname is the vrf device.
|
||||
test_masquerade_vrf()
|
||||
{
|
||||
local qdisc=$1
|
||||
|
||||
if [ "$qdisc" != "default" ]; then
|
||||
tc -net $ns0 qdisc add dev tvrf root $qdisc
|
||||
fi
|
||||
|
||||
ip netns exec $ns0 conntrack -F 2>/dev/null
|
||||
|
||||
ip netns exec $ns0 nft -f - <<EOF
|
||||
flush ruleset
|
||||
table ip nat {
|
||||
chain rawout {
|
||||
type filter hook output priority raw;
|
||||
|
||||
oif tvrf ct state untracked counter
|
||||
}
|
||||
chain postrouting2 {
|
||||
type filter hook postrouting priority mangle;
|
||||
|
||||
oif tvrf ct state untracked counter
|
||||
}
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 0;
|
||||
# NB: masquerade should always be combined with 'oif(name) bla',
|
||||
@ -171,13 +187,18 @@ EOF
|
||||
fi
|
||||
|
||||
# must also check that nat table was evaluated on second (lower device) iteration.
|
||||
ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2'
|
||||
ip netns exec $ns0 nft list table ip nat |grep -q 'counter packets 2' &&
|
||||
ip netns exec $ns0 nft list table ip nat |grep -q 'untracked counter packets [1-9]'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "PASS: iperf3 connect with masquerade + sport rewrite on vrf device"
|
||||
echo "PASS: iperf3 connect with masquerade + sport rewrite on vrf device ($qdisc qdisc)"
|
||||
else
|
||||
echo "FAIL: vrf masq rule has unexpected counter value"
|
||||
echo "FAIL: vrf rules have unexpected counter value"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
if [ "$qdisc" != "default" ]; then
|
||||
tc -net $ns0 qdisc del dev tvrf root
|
||||
fi
|
||||
}
|
||||
|
||||
# add masq rule that gets evaluated w. outif set to veth device.
|
||||
@ -213,7 +234,8 @@ EOF
|
||||
}
|
||||
|
||||
test_ct_zone_in
|
||||
test_masquerade_vrf
|
||||
test_masquerade_vrf "default"
|
||||
test_masquerade_vrf "pfifo"
|
||||
test_masquerade_veth
|
||||
|
||||
exit $ret
|
||||
|
@ -23,8 +23,8 @@ TESTS="reported_issues correctness concurrency timeout"
|
||||
|
||||
# Set types, defined by TYPE_ variables below
|
||||
TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto
|
||||
net_port_net net_mac net_mac_icmp net6_mac_icmp net6_port_net6_port
|
||||
net_port_mac_proto_net"
|
||||
net_port_net net_mac mac_net net_mac_icmp net6_mac_icmp
|
||||
net6_port_net6_port net_port_mac_proto_net"
|
||||
|
||||
# Reported bugs, also described by TYPE_ variables below
|
||||
BUGS="flush_remove_add"
|
||||
@ -277,6 +277,23 @@ perf_entries 1000
|
||||
perf_proto ipv4
|
||||
"
|
||||
|
||||
TYPE_mac_net="
|
||||
display mac,net
|
||||
type_spec ether_addr . ipv4_addr
|
||||
chain_spec ether saddr . ip saddr
|
||||
dst
|
||||
src mac addr4
|
||||
start 1
|
||||
count 5
|
||||
src_delta 2000
|
||||
tools sendip nc bash
|
||||
proto udp
|
||||
|
||||
race_repeat 0
|
||||
|
||||
perf_duration 0
|
||||
"
|
||||
|
||||
TYPE_net_mac_icmp="
|
||||
display net,mac - ICMP
|
||||
type_spec ipv4_addr . ether_addr
|
||||
@ -984,7 +1001,8 @@ format() {
|
||||
fi
|
||||
done
|
||||
for f in ${src}; do
|
||||
__expr="${__expr} . "
|
||||
[ "${__expr}" != "{ " ] && __expr="${__expr} . "
|
||||
|
||||
__start="$(eval format_"${f}" "${srcstart}")"
|
||||
__end="$(eval format_"${f}" "${srcend}")"
|
||||
|
||||
|
@ -18,11 +18,17 @@ cleanup()
|
||||
ip netns del $ns
|
||||
}
|
||||
|
||||
ip netns add $ns
|
||||
if [ $? -ne 0 ];then
|
||||
echo "SKIP: Could not create net namespace $gw"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
checktool (){
|
||||
if ! $1 > /dev/null 2>&1; then
|
||||
echo "SKIP: Could not $2"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
}
|
||||
|
||||
checktool "nft --version" "run test without nft tool"
|
||||
checktool "ip -Version" "run test without ip tool"
|
||||
checktool "socat -V" "run test without socat tool"
|
||||
checktool "ip netns add $ns" "create net namespace"
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
@ -71,7 +77,8 @@ EOF
|
||||
local start=$(date +%s%3N)
|
||||
i=$((i + 10000))
|
||||
j=$((j + 1))
|
||||
dd if=/dev/zero of=/dev/stdout bs=8k count=10000 2>/dev/null | ip netns exec "$ns" nc -w 1 -q 1 -u -p 12345 127.0.0.1 12345 > /dev/null
|
||||
# nft rule in output places each packet in a different zone.
|
||||
dd if=/dev/zero of=/dev/stdout bs=8k count=10000 2>/dev/null | ip netns exec "$ns" socat STDIN UDP:127.0.0.1:12345,sourceport=12345
|
||||
if [ $? -ne 0 ] ;then
|
||||
ret=1
|
||||
break
|
||||
|
@ -60,6 +60,8 @@ CONFIG_NET_IFE_SKBTCINDEX=m
|
||||
CONFIG_NET_SCH_FIFO=y
|
||||
CONFIG_NET_SCH_ETS=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_FQ_PIE=m
|
||||
CONFIG_NETDEVSIM=m
|
||||
|
||||
#
|
||||
## Network testing
|
||||
|
@ -716,6 +716,7 @@ def set_operation_mode(pm, parser, args, remaining):
|
||||
list_test_cases(alltests)
|
||||
exit(0)
|
||||
|
||||
exit_code = 0 # KSFT_PASS
|
||||
if len(alltests):
|
||||
req_plugins = pm.get_required_plugins(alltests)
|
||||
try:
|
||||
@ -724,6 +725,8 @@ def set_operation_mode(pm, parser, args, remaining):
|
||||
print('The following plugins were not found:')
|
||||
print('{}'.format(pde.missing_pg))
|
||||
catresults = test_runner(pm, args, alltests)
|
||||
if catresults.count_failures() != 0:
|
||||
exit_code = 1 # KSFT_FAIL
|
||||
if args.format == 'none':
|
||||
print('Test results output suppression requested\n')
|
||||
else:
|
||||
@ -748,6 +751,8 @@ def set_operation_mode(pm, parser, args, remaining):
|
||||
gid=int(os.getenv('SUDO_GID')))
|
||||
else:
|
||||
print('No tests found\n')
|
||||
exit_code = 4 # KSFT_SKIP
|
||||
exit(exit_code)
|
||||
|
||||
def main():
|
||||
"""
|
||||
@ -767,8 +772,5 @@ def main():
|
||||
|
||||
set_operation_mode(pm, parser, args, remaining)
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
modprobe netdevsim
|
||||
./tdc.py -c actions --nobuildebpf
|
||||
./tdc.py -c qdisc
|
||||
|
Loading…
Reference in New Issue
Block a user