Patch "net: mscc: ocelot: fix VCAP filters not matching on MAC with "protocol 802.1Q"" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: mscc: ocelot: fix VCAP filters not matching on MAC with "protocol 802.1Q"

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-mscc-ocelot-fix-vcap-filters-not-matching-on-mac.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 8237acb2d89d6d865180a482d922bfbed62c7ade
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Sun Feb 5 21:24:08 2023 +0200

    net: mscc: ocelot: fix VCAP filters not matching on MAC with "protocol 802.1Q"
    
    [ Upstream commit f964f8399df29d3e3ced77177cf35131cd2491bf ]
    
    Alternative short title: don't instruct the hardware to match on
    EtherType with "protocol 802.1Q" flower filters. It doesn't work for the
    reasons detailed below.
    
    With a command such as the following:
    
    tc filter add dev $swp1 ingress chain $(IS1 2) pref 3 \
            protocol 802.1Q flower skip_sw vlan_id 200 src_mac $h1_mac \
            action vlan modify id 300 \
            action goto chain $(IS2 0 0)
    
    the created filter is set by ocelot_flower_parse_key() to be of type
    OCELOT_VCAP_KEY_ETYPE, and etype is set to {value=0x8100, mask=0xffff}.
    This gets propagated all the way to is1_entry_set() which commits it to
    hardware (the VCAP_IS1_HK_ETYPE field of the key). Compare this to the
    case where src_mac isn't specified - the key type is OCELOT_VCAP_KEY_ANY,
    and is1_entry_set() doesn't populate VCAP_IS1_HK_ETYPE.
    
    The problem is that for VLAN-tagged frames, the hardware interprets the
    ETYPE field as holding the encapsulated VLAN protocol. So the above
    filter will only match those packets which have an encapsulated protocol
    of 0x8100, rather than all packets with VLAN ID 200 and the given src_mac.
    
    The reason why this is allowed to occur is because, although we have a
    block of code in ocelot_flower_parse_key() which sets "match_protocol"
    to false when VLAN keys are present, that code executes too late.
    There is another block of code, which executes for Ethernet addresses,
    and has a "goto finished_key_parsing" and skips the VLAN header parsing.
    By skipping it, "match_protocol" remains with the value it was
    initialized with, i.e. "true", and "proto" is set to f->common.protocol,
    or 0x8100.
    
    The concept of ignoring some keys rather than erroring out when they are
    present but can't be offloaded is dubious in itself, but is present
    since the initial commit fe3490e6107e ("net: mscc: ocelot: Hardware
    ofload for tc flower filter"), and it's outside of the scope of this
    patch to change that.
    
    The problem was introduced when the driver started to interpret the
    flower filter's protocol, and populate the VCAP filter's ETYPE field
    based on it.
    
    To fix this, it is sufficient to move the code that parses the VLAN keys
    earlier than the "goto finished_key_parsing" instruction. This will
    ensure that if we have a flower filter with both VLAN and Ethernet
    address keys, it won't match on ETYPE 0x8100, because the VLAN key
    parsing sets "match_protocol = false".
    
    Fixes: 86b956de119c ("net: mscc: ocelot: support matching on EtherType")
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Reviewed-by: Simon Horman <simon.horman@xxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230205192409.1796428-1-vladimir.oltean@xxxxxxx
    Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index a3a5ad5dbb0e0..b7e7bd744a1b8 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -473,6 +473,18 @@ ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress,
 		flow_rule_match_control(rule, &match);
 	}
 
+	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
+		struct flow_match_vlan match;
+
+		flow_rule_match_vlan(rule, &match);
+		filter->key_type = OCELOT_VCAP_KEY_ANY;
+		filter->vlan.vid.value = match.key->vlan_id;
+		filter->vlan.vid.mask = match.mask->vlan_id;
+		filter->vlan.pcp.value[0] = match.key->vlan_priority;
+		filter->vlan.pcp.mask[0] = match.mask->vlan_priority;
+		match_protocol = false;
+	}
+
 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
 		struct flow_match_eth_addrs match;
 
@@ -605,18 +617,6 @@ ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress,
 		match_protocol = false;
 	}
 
-	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
-		struct flow_match_vlan match;
-
-		flow_rule_match_vlan(rule, &match);
-		filter->key_type = OCELOT_VCAP_KEY_ANY;
-		filter->vlan.vid.value = match.key->vlan_id;
-		filter->vlan.vid.mask = match.mask->vlan_id;
-		filter->vlan.pcp.value[0] = match.key->vlan_priority;
-		filter->vlan.pcp.mask[0] = match.mask->vlan_priority;
-		match_protocol = false;
-	}
-
 finished_key_parsing:
 	if (match_protocol && proto != ETH_P_ALL) {
 		if (filter->block_id == VCAP_ES0) {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux