linux/drivers/net
Vladimir Oltean 2fcde9fe25 net: mscc: ocelot: fix all IPv6 getting trapped to CPU when PTP timestamping is used
While running this selftest which usually passes:

~/selftests/drivers/net/dsa# ./local_termination.sh eno0 swp0
TEST: swp0: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: swp0: Multicast IPv4 to joined group                          [ OK ]
TEST: swp0: Multicast IPv4 to unknown group                         [ OK ]
TEST: swp0: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: swp0: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: swp0: Multicast IPv6 to joined group                          [ OK ]
TEST: swp0: Multicast IPv6 to unknown group                         [ OK ]
TEST: swp0: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: swp0: Multicast IPv6 to unknown group, allmulti               [ OK ]

if I start PTP timestamping then run it again (debug prints added by me),
the unknown IPv6 MC traffic is seen by the CPU port even when it should
have been dropped:

~/selftests/drivers/net/dsa# ptp4l -i swp0 -2 -P -m
ptp4l[225.410]: selected /dev/ptp1 as PTP clock
[  225.445746] mscc_felix 0000:00:00.5: ocelot_l2_ptp_trap_add: port 0 adding L2 PTP trap
[  225.453815] mscc_felix 0000:00:00.5: ocelot_ipv4_ptp_trap_add: port 0 adding IPv4 PTP event trap
[  225.462703] mscc_felix 0000:00:00.5: ocelot_ipv4_ptp_trap_add: port 0 adding IPv4 PTP general trap
[  225.471768] mscc_felix 0000:00:00.5: ocelot_ipv6_ptp_trap_add: port 0 adding IPv6 PTP event trap
[  225.480651] mscc_felix 0000:00:00.5: ocelot_ipv6_ptp_trap_add: port 0 adding IPv6 PTP general trap
ptp4l[225.488]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[225.488]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
^C
~/selftests/drivers/net/dsa# ./local_termination.sh eno0 swp0
TEST: swp0: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: swp0: Multicast IPv4 to joined group                          [ OK ]
TEST: swp0: Multicast IPv4 to unknown group                         [ OK ]
TEST: swp0: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: swp0: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: swp0: Multicast IPv6 to joined group                          [ OK ]
TEST: swp0: Multicast IPv6 to unknown group                         [FAIL]
        reception succeeded, but should have failed
TEST: swp0: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: swp0: Multicast IPv6 to unknown group, allmulti               [ OK ]

The PGID_MCIPV6 is configured correctly to not flood to the CPU,
I checked that.

Furthermore, when I disable back PTP RX timestamping (ptp4l doesn't do
that when it exists), packets are RX filtered again as they should be:

~/selftests/drivers/net/dsa# hwstamp_ctl -i swp0 -r 0
[  218.202854] mscc_felix 0000:00:00.5: ocelot_l2_ptp_trap_del: port 0 removing L2 PTP trap
[  218.212656] mscc_felix 0000:00:00.5: ocelot_ipv4_ptp_trap_del: port 0 removing IPv4 PTP event trap
[  218.222975] mscc_felix 0000:00:00.5: ocelot_ipv4_ptp_trap_del: port 0 removing IPv4 PTP general trap
[  218.233133] mscc_felix 0000:00:00.5: ocelot_ipv6_ptp_trap_del: port 0 removing IPv6 PTP event trap
[  218.242251] mscc_felix 0000:00:00.5: ocelot_ipv6_ptp_trap_del: port 0 removing IPv6 PTP general trap
current settings:
tx_type 1
rx_filter 12
new settings:
tx_type 1
rx_filter 0
~/selftests/drivers/net/dsa# ./local_termination.sh eno0 swp0
TEST: swp0: Unicast IPv4 to primary MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to macvlan MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address                     [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address, promisc            [ OK ]
TEST: swp0: Unicast IPv4 to unknown MAC address, allmulti           [ OK ]
TEST: swp0: Multicast IPv4 to joined group                          [ OK ]
TEST: swp0: Multicast IPv4 to unknown group                         [ OK ]
TEST: swp0: Multicast IPv4 to unknown group, promisc                [ OK ]
TEST: swp0: Multicast IPv4 to unknown group, allmulti               [ OK ]
TEST: swp0: Multicast IPv6 to joined group                          [ OK ]
TEST: swp0: Multicast IPv6 to unknown group                         [ OK ]
TEST: swp0: Multicast IPv6 to unknown group, promisc                [ OK ]
TEST: swp0: Multicast IPv6 to unknown group, allmulti               [ OK ]

So it's clear that something in the PTP RX trapping logic went wrong.

Looking a bit at the code, I can see that there are 4 typos, which
populate "ipv4" VCAP IS2 key filter fields for IPv6 keys.

VCAP IS2 keys of type OCELOT_VCAP_KEY_IPV4 and OCELOT_VCAP_KEY_IPV6 are
handled by is2_entry_set(). OCELOT_VCAP_KEY_IPV4 looks at
&filter->key.ipv4, and OCELOT_VCAP_KEY_IPV6 at &filter->key.ipv6.
Simply put, when we populate the wrong key field, &filter->key.ipv6
fields "proto.mask" and "proto.value" remain all zeroes (or "don't care").
So is2_entry_set() will enter the "else" of this "if" condition:

	if (msk == 0xff && (val == IPPROTO_TCP || val == IPPROTO_UDP))

and proceed to ignore the "proto" field. The resulting rule will match
on all IPv6 traffic, trapping it to the CPU.

This is the reason why the local_termination.sh selftest sees it,
because control traps are stronger than the PGID_MCIPV6 used for
flooding (from the forwarding data path).

But the problem is in fact much deeper. We trap all IPv6 traffic to the
CPU, but if we're bridged, we set skb->offload_fwd_mark = 1, so software
forwarding will not take place and IPv6 traffic will never reach its
destination.

The fix is simple - correct the typos.

I was intentionally inaccurate in the commit message about the breakage
occurring when any PTP timestamping is enabled. In fact it only happens
when L4 timestamping is requested (HWTSTAMP_FILTER_PTP_V2_EVENT or
HWTSTAMP_FILTER_PTP_V2_L4_EVENT). But ptp4l requests a larger RX
timestamping filter than it needs for "-2": HWTSTAMP_FILTER_PTP_V2_EVENT.
I wanted people skimming through git logs to not think that the bug
doesn't affect them because they only use ptp4l in L2 mode.

Fixes: 96ca08c058 ("net: mscc: ocelot: set up traps for PTP packets")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Link: https://lore.kernel.org/r/20230207183117.1745754-1-vladimir.oltean@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2023-02-09 10:52:44 +01:00
..
appletalk
arcnet
bonding bonding: fix error checking in bond_debug_reregister() 2023-02-03 19:22:20 -08:00
caif
can can: mcp251xfd: mcp251xfd_ring_set_ringparam(): assign missing tx_obj_num_coalesce_irq 2023-02-02 10:33:27 +01:00
dsa net: dsa: mt7530: don't change PVC_EG_TAG when CPU port becomes VLAN-aware 2023-02-07 11:42:04 +01:00
ethernet net: mscc: ocelot: fix all IPv6 getting trapped to CPU when PTP timestamping is used 2023-02-09 10:52:44 +01:00
fddi net: defxx: Fix missing err handling in dfx_init() 2022-12-09 10:44:27 +00:00
fjes
hamradio Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-13 09:49:29 +01:00
hippi
hyperv hv_netvsc: Allocate memory in netvsc_dma_map() with GFP_ATOMIC 2023-02-07 20:39:26 -08:00
ieee802154 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-08 18:19:59 -08:00
ipa net: ipa: disable ipa interrupt during suspend 2023-01-17 19:04:13 -08:00
ipvlan Driver Core changes for 6.2-rc1 2022-12-16 03:54:54 -08:00
mctp mctp: serial: Fix starting value for frame check sequence 2022-12-19 12:38:45 +00:00
mdio net: mdio-mux-meson-g12a: force internal PHY off on mux switch 2023-01-25 22:46:51 -08:00
netdevsim xfrm: allow state packet offload mode 2022-12-05 10:32:44 +01:00
pcs net: pcs: altera-tse: remove unnecessary register definitions 2022-11-29 20:29:55 -08:00
phy net: phy: meson-gxl: use MMD access dummy stubs for GXL, internal PHY 2023-02-03 19:55:36 -08:00
plip net: plip: don't call kfree_skb/dev_kfree_skb() under spin_lock_irq() 2022-12-07 20:10:47 -08:00
ppp Networking changes for 6.2. 2022-12-13 15:47:48 -08:00
pse-pd
slip
team Revert "net: team: use IFF_NO_ADDRCONF flag to prevent ipv6 addrconf" 2023-01-18 20:32:44 -08:00
usb net: USB: Fix wrong-direction WARNING in plusb.c 2023-02-06 09:59:35 +00:00
vmxnet3 vmxnet3: correctly report csum_level for encapsulated packet 2022-12-21 17:55:30 -08:00
vxlan vxlan: Fix memory leaks in error path 2023-01-02 13:37:33 +00:00
wan net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs 2023-01-13 21:34:31 -08:00
wireguard wireguard: timers: cast enum limits members to int in prints 2022-12-13 19:30:45 -08:00
wireless wifi: mt76: dma: fix a regression in adding rx buffers 2023-01-16 17:27:17 +02:00
wwan net: wwan: t7xx: Fix Runtime PM initialization 2023-01-28 13:20:21 +00:00
xen-netback xen: branch for v6.2-rc4 2023-01-12 17:02:20 -06:00
amt.c
bareudp.c
dummy.c
eql.c
geneve.c
gtp.c
ifb.c
Kconfig
LICENSE.SRC
loopback.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-11-29 13:04:52 -08:00
macsec.c net: macsec: fix net device access prior to holding a lock 2022-12-13 18:58:08 -08:00
macvlan.c
macvtap.c
Makefile
mdio.c
mhi_net.c
mii.c
net_failover.c
netconsole.c netconsole: avoid CON_ENABLED misuse to track registration 2022-12-02 11:25:02 +01:00
nlmon.c
ntb_netdev.c ntb_netdev: Use dev_kfree_skb_any() in interrupt context 2022-12-12 12:56:37 -08:00
rionet.c
sb1000.c
Space.c
sungem_phy.c
tap.c driver/net/tun: Added features for USO. 2022-12-12 09:29:56 +00:00
thunderbolt.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-08 18:19:59 -08:00
tun.c driver/net/tun: Added features for USO. 2022-12-12 09:29:56 +00:00
veth.c veth: Fix race with AF_XDP exposing old or uninitialized descriptors 2022-12-22 15:06:10 +01:00
virtio_net.c virtio-net: Keep stop() to follow mirror sequence of open() 2023-02-02 10:10:53 -08:00
vrf.c net: vrf: determine the dst using the original ifindex for multicast 2022-12-21 17:47:37 -08:00
vsockmon.c
xen-netfront.c xen: branch for v6.2-rc4 2023-01-12 17:02:20 -06:00