linux/drivers
Vladimir Oltean 92f62485b3 net: dsa: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge
Normally it is expected that the dsa_device_ops :: rcv() method finishes
parsing the DSA tag and consumes it, then never looks at it again.

But commit c0bcf53766 ("net: dsa: ocelot: add hardware timestamping
support for Felix") added support for RX timestamping in a very
unconventional way. On this switch, a partial timestamp is available in
the DSA header, but the driver got away with not parsing that timestamp
right away, but instead delayed that parsing for a little longer:

dsa_switch_rcv():
	nskb = cpu_dp->rcv(skb, dev); <------------- not here
	-> ocelot_rcv()
	...

	skb = nskb;
	skb_push(skb, ETH_HLEN);
	skb->pkt_type = PACKET_HOST;
	skb->protocol = eth_type_trans(skb, skb->dev);

	...

	if (dsa_skb_defer_rx_timestamp(p, skb)) <--- but here
	-> felix_rxtstamp()
		return 0;

When in felix_rxtstamp(), this driver accounted for the fact that
eth_type_trans() happened in the meanwhile, so it got a hold of the
extraction header again by subtracting (ETH_HLEN + OCELOT_TAG_LEN) bytes
from the current skb->data.

This worked for quite some time but was quite fragile from the very
beginning. Not to mention that having DSA tag parsing split in two
different files, under different folders (net/dsa/tag_ocelot.c vs
drivers/net/dsa/ocelot/felix.c) made it quite non-obvious for patches to
come that they might break this.

Finally, the blamed commit does the following: at the end of
ocelot_rcv(), it checks whether the skb payload contains a VLAN header.
If it does, and this port is under a VLAN-aware bridge, that VLAN ID
might not be correct in the sense that the packet might have suffered
VLAN rewriting due to TCAM rules (VCAP IS1). So we consume the VLAN ID
from the skb payload using __skb_vlan_pop(), and take the classified
VLAN ID from the DSA tag, and construct a hwaccel VLAN tag with the
classified VLAN, and the skb payload is VLAN-untagged.

The big problem is that __skb_vlan_pop() does:

	memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
	__skb_pull(skb, VLAN_HLEN);

aka it moves the Ethernet header 4 bytes to the right, and pulls 4 bytes
from the skb headroom (effectively also moving skb->data, by definition).
So for felix_rxtstamp()'s fragile logic, all bets are off now.
Instead of having the "extraction" pointer point to the DSA header,
it actually points to 4 bytes _inside_ the extraction header.
Corollary, the last 4 bytes of the "extraction" header are in fact 4
stale bytes of the destination MAC address from the Ethernet header,
from prior to the __skb_vlan_pop() movement.

So of course, RX timestamps are completely bogus when the system is
configured in this way.

The fix is actually very simple: just don't structure the code like that.
For better or worse, the DSA PTP timestamping API does not offer a
straightforward way for drivers to present their RX timestamps, but
other drivers (sja1105) have established a simple mechanism to carry
their RX timestamp from dsa_device_ops :: rcv() all the way to
dsa_switch_ops :: port_rxtstamp() and even later. That mechanism is to
simply save the partial timestamp to the skb->cb, and complete it later.

Question: why don't we simply populate the skb's struct
skb_shared_hwtstamps from ocelot_rcv(), and bother with this
complication of propagating the timestamp to felix_rxtstamp()?

Answer: dsa_switch_ops :: port_rxtstamp() answers the question whether
PTP packets need sleepable context to retrieve the full RX timestamp.
Currently felix_rxtstamp() answers "no, thanks" to that question, and
calls ocelot_ptp_gettime64() from softirq atomic context. This is
understandable, since Felix VSC9959 is a PCIe memory-mapped switch, so
hardware access does not require sleeping. But the felix driver is
preparing for the introduction of other switches where hardware access
is over a slow bus like SPI or MDIO:
https://lore.kernel.org/lkml/20210814025003.2449143-1-colin.foster@in-advantage.com/

So I would like to keep this code structure, so the rework needed when
that driver will need PTP support will be minimal (answer "yes, I need
deferred context for this skb's RX timestamp", then the partial
timestamp will still be found in the skb->cb.

Fixes: ea440cd2d9 ("net: dsa: tag_ocelot: use VLAN information from tagging header when available")
Reported-by: Po Liu <po.liu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-11-03 14:22:00 +00:00
..
accessibility
acpi hwmon updates for v5.16-rc1 2021-11-01 19:16:49 -07:00
amba
android selinux/stable-5.16 PR 20211101 2021-11-01 21:06:18 -07:00
ata for-5.16/scsi-ma-2021-10-29 2021-11-01 10:07:26 -07:00
atm
auxdisplay
base Core: 2021-11-02 06:20:58 -07:00
bcma bcma: drop unneeded initialization value 2021-10-05 08:32:30 +03:00
block for-5.16/inode-sync-2021-10-29 2021-11-01 10:25:27 -07:00
bluetooth Bluetooth: Rename driver .prevent_wake to .wakeup 2021-10-01 15:46:15 -07:00
bus Driver core fixes for 5.15-rc6 2021-10-17 17:17:28 -10:00
cdrom for-5.16/cdrom-2021-10-29 2021-11-01 10:09:14 -07:00
char Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2021-11-01 21:24:02 -07:00
clk One fix for the composite clk that broke when we changed this clk type 2021-10-30 09:55:46 -07:00
clocksource Time, timers and timekeeping updates: 2021-11-01 13:44:55 -07:00
comedi comedi: Fix memory leak in compat_insnlist() 2021-09-21 17:53:54 +02:00
connector
counter
cpufreq Power management fixes for 5.15-rc2 2021-09-17 12:05:04 -07:00
cpuidle
crypto Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2021-11-01 21:24:02 -07:00
cxl cxl/core: Replace unions with struct_group() 2021-09-25 08:20:47 -07:00
dax
dca
devfreq
dio
dma dmaengine: pxa_dma: Prefer struct_size over open coded arithmetic 2021-10-20 18:35:22 -05:00
dma-buf
edac - amd64_edac: Add support for three-rank interleaving mode which is 2021-11-01 15:02:49 -07:00
eisa
extcon
firewire Core: 2021-11-02 06:20:58 -07:00
firmware spi: Updates for v5.16 2021-11-01 19:09:04 -07:00
fpga fpga: ice40-spi: Add SPI device ID table 2021-09-27 14:00:41 -07:00
fsi
gnss
gpio gpio: mlxbf2.c: Add check for bgpio_init failure 2021-10-25 10:15:05 +02:00
gpu media updates for v5.16-rc1 2021-11-01 18:45:08 -07:00
greybus
hid overflow updates for v5.16-rc1 2021-11-01 17:12:56 -07:00
hsi net: remove single-byte netdev->dev_addr writes 2021-10-13 10:03:59 -07:00
hv hyperv-fixes for 5.15 2021-10-22 10:31:32 -10:00
hwmon hwmon updates for v5.16-rc1 2021-11-01 19:16:49 -07:00
hwspinlock
hwtracing coresight: syscfg: Fix compiler warning 2021-09-14 09:03:16 +02:00
i2c mailbox: pcc: Use PCC mailbox channel pointer instead of standard 2021-10-29 22:46:38 -05:00
i3c
idle
iio Staging/IIO driver fixes for 5.15-rc6 2021-10-17 17:10:00 -10:00
infiniband Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-10-28 10:43:58 -07:00
input Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2021-10-17 16:57:06 -10:00
interconnect interconnect: qcom: sdm660: Add missing a2noc qos clocks 2021-09-13 15:49:55 +03:00
iommu overflow updates for v5.16-rc1 2021-11-01 17:12:56 -07:00
ipack ipack: ipoctal: fix module reference leak 2021-09-27 17:38:49 +02:00
irqchip Merge branch irq/irq_cpu_offline into irq/irqchip-next 2021-10-28 13:34:57 +01:00
isdn mISDN: Fix return values of the probe function 2021-10-19 13:09:28 +01:00
leds leds: trigger: Disable CPU trigger on PREEMPT_RT 2021-10-13 20:07:57 +02:00
macintosh powerpc: Split memset() to avoid multi-field overflow 2021-09-25 08:20:47 -07:00
mailbox mailbox: imx: support i.MX8ULP S4 MU 2021-10-29 23:03:09 -05:00
mcb mcb: fix error handling in mcb_alloc_bus() 2021-09-14 11:22:26 +02:00
md for-5.16/passthrough-flag-2021-10-29 2021-11-01 10:12:44 -07:00
media Core: 2021-11-02 06:20:58 -07:00
memory
memstick memstick: r592: Fix a UAF bug when removing the driver 2021-10-19 13:04:42 +02:00
message mpt fusion: use dev_addr_set() 2021-10-28 12:47:49 +01:00
mfd
misc net: sgi-xp: use eth_hw_addr_set() 2021-10-29 13:17:21 +01:00
mmc MMC core: 2021-11-01 18:55:12 -07:00
most
mtd mtd: add add_disk() error handling 2021-10-21 09:00:56 -06:00
mux
net net: dsa: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge 2021-11-03 14:22:00 +00:00
nfc Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-10-28 10:43:58 -07:00
ntb
nubus
nvdimm for-5.16/block-2021-10-29 2021-11-01 09:19:50 -07:00
nvme for-5.16/ki_complete-2021-10-29 2021-11-01 10:17:11 -07:00
nvmem nvmem: Fix shift-out-of-bound (UBSAN) with byte size cells 2021-10-13 15:09:58 +02:00
of Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-10-22 11:41:16 +01:00
opp
parisc
parport
pci pci-v5.15-fixes-2 2021-10-16 09:00:46 -07:00
pcmcia Core: 2021-11-02 06:20:58 -07:00
perf arm64 updates for 5.16 2021-11-01 16:33:53 -07:00
phy net: Convert more users of mdiobus_* to mdiodev_* 2021-10-24 13:40:33 +01:00
pinctrl pinctrl: amd: disable and mask interrupts on probe 2021-10-16 23:56:59 +02:00
platform platform/x86: int1092: Fix non sequential device mode handling 2021-10-11 16:39:25 +02:00
pnp
power
powercap
pps
ps3
ptp ptp: fix code indentation issues 2021-10-28 14:42:20 +01:00
pwm
rapidio
ras
regulator regulator: Updates for v5.16 2021-11-01 19:04:47 -07:00
remoteproc
reset reset: socfpga: add empty driver allowing consumers to probe 2021-10-05 12:23:16 +02:00
rpmsg
rtc rtc: cmos: Disable irq around direct invocation of cmos_interrupt() 2021-09-14 10:20:19 +02:00
s390 Core: 2021-11-02 06:20:58 -07:00
sbus
scsi Core: 2021-11-02 06:20:58 -07:00
sh
siox
slimbus
soc Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-10-22 11:41:16 +01:00
soundwire
spi spi: Updates for v5.16 2021-11-01 19:09:04 -07:00
spmi
ssb
staging Core: 2021-11-02 06:20:58 -07:00
target for-5.16/ki_complete-2021-10-29 2021-11-01 10:17:11 -07:00
tc
tee tee: optee: Fix missing devices unregister during optee_remove 2021-10-12 13:24:39 +02:00
thermal thermal/drivers/tsens: Fix wrong check for tzd in irq handlers 2021-09-21 15:17:11 +02:00
thunderbolt thunderbolt: build kunit tests without structleak plugin 2021-10-06 17:53:49 -06:00
tty Serial driver fix for 5.15-rc6 2021-10-17 17:06:31 -10:00
uio
usb Core: 2021-11-02 06:20:58 -07:00
vdpa Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-10-28 10:43:58 -07:00
vfio vfio/pci: add missing identifier name in argument of function prototype 2021-09-23 14:12:36 -06:00
vhost virtio,vdpa: fixes 2021-10-17 18:17:19 -10:00
video video: fbdev: gbefb: Only instantiate device when built for IP32 2021-10-06 11:12:28 +02:00
virt
virtio virtio-ring: fix DMA metadata flags 2021-10-27 15:54:34 -04:00
visorbus
vlynq
vme
w1
watchdog watchdog: Fix OMAP watchdog early handling 2021-10-26 20:22:51 +02:00
xen xen: branch for v5.15-rc5 2021-10-08 12:55:23 -07:00
zorro
Kconfig firmware: include drivers/firmware/Kconfig unconditionally 2021-10-07 16:51:26 +02:00
Makefile