2019-05-31 09:16:57 +02:00
|
|
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
|
|
|
/* Microsemi Ocelot Switch driver
|
|
|
|
* Copyright (c) 2019 Microsemi Corporation
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <net/pkt_cls.h>
|
|
|
|
#include <net/tc_act/tc_gact.h>
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
#include <soc/mscc/ocelot_vcap.h>
|
2020-06-20 18:43:45 +03:00
|
|
|
#include "ocelot_vcap.h"
|
2019-05-31 09:16:57 +02:00
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
/* Arbitrarily chosen constants for encoding the VCAP block and lookup number
|
|
|
|
* into the chain number. This is UAPI.
|
|
|
|
*/
|
|
|
|
#define VCAP_BLOCK 10000
|
|
|
|
#define VCAP_LOOKUP 1000
|
|
|
|
#define VCAP_IS1_NUM_LOOKUPS 3
|
|
|
|
#define VCAP_IS2_NUM_LOOKUPS 2
|
|
|
|
#define VCAP_IS2_NUM_PAG 256
|
|
|
|
#define VCAP_IS1_CHAIN(lookup) \
|
|
|
|
(1 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP)
|
|
|
|
#define VCAP_IS2_CHAIN(lookup, pag) \
|
|
|
|
(2 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP + (pag))
|
|
|
|
|
|
|
|
static int ocelot_chain_to_block(int chain, bool ingress)
|
|
|
|
{
|
|
|
|
int lookup, pag;
|
|
|
|
|
|
|
|
if (!ingress) {
|
|
|
|
if (chain == 0)
|
|
|
|
return VCAP_ES0;
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Backwards compatibility with older, single-chain tc-flower
|
|
|
|
* offload support in Ocelot
|
|
|
|
*/
|
|
|
|
if (chain == 0)
|
|
|
|
return VCAP_IS2;
|
|
|
|
|
|
|
|
for (lookup = 0; lookup < VCAP_IS1_NUM_LOOKUPS; lookup++)
|
|
|
|
if (chain == VCAP_IS1_CHAIN(lookup))
|
|
|
|
return VCAP_IS1;
|
|
|
|
|
|
|
|
for (lookup = 0; lookup < VCAP_IS2_NUM_LOOKUPS; lookup++)
|
|
|
|
for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
|
|
|
|
if (chain == VCAP_IS2_CHAIN(lookup, pag))
|
|
|
|
return VCAP_IS2;
|
|
|
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Caller must ensure this is a valid IS1 or IS2 chain first,
|
|
|
|
* by calling ocelot_chain_to_block.
|
|
|
|
*/
|
|
|
|
static int ocelot_chain_to_lookup(int chain)
|
|
|
|
{
|
|
|
|
return (chain / VCAP_LOOKUP) % 10;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
/* Caller must ensure this is a valid IS2 chain first,
|
|
|
|
* by calling ocelot_chain_to_block.
|
|
|
|
*/
|
|
|
|
static int ocelot_chain_to_pag(int chain)
|
|
|
|
{
|
|
|
|
int lookup = ocelot_chain_to_lookup(chain);
|
|
|
|
|
|
|
|
/* calculate PAG value as chain index relative to the first PAG */
|
|
|
|
return chain - VCAP_IS2_CHAIN(lookup, 0);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
static bool ocelot_is_goto_target_valid(int goto_target, int chain,
|
|
|
|
bool ingress)
|
|
|
|
{
|
|
|
|
int pag;
|
|
|
|
|
|
|
|
/* Can't offload GOTO in VCAP ES0 */
|
|
|
|
if (!ingress)
|
|
|
|
return (goto_target < 0);
|
|
|
|
|
|
|
|
/* Non-optional GOTOs */
|
|
|
|
if (chain == 0)
|
|
|
|
/* VCAP IS1 can be skipped, either partially or completely */
|
|
|
|
return (goto_target == VCAP_IS1_CHAIN(0) ||
|
|
|
|
goto_target == VCAP_IS1_CHAIN(1) ||
|
|
|
|
goto_target == VCAP_IS1_CHAIN(2) ||
|
|
|
|
goto_target == VCAP_IS2_CHAIN(0, 0) ||
|
|
|
|
goto_target == VCAP_IS2_CHAIN(1, 0));
|
|
|
|
|
|
|
|
if (chain == VCAP_IS1_CHAIN(0))
|
|
|
|
return (goto_target == VCAP_IS1_CHAIN(1));
|
|
|
|
|
|
|
|
if (chain == VCAP_IS1_CHAIN(1))
|
|
|
|
return (goto_target == VCAP_IS1_CHAIN(2));
|
|
|
|
|
|
|
|
/* Lookup 2 of VCAP IS1 can really support non-optional GOTOs,
|
|
|
|
* using a Policy Association Group (PAG) value, which is an 8-bit
|
|
|
|
* value encoding a VCAP IS2 target chain.
|
|
|
|
*/
|
|
|
|
if (chain == VCAP_IS1_CHAIN(2)) {
|
|
|
|
for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
|
|
|
|
if (goto_target == VCAP_IS2_CHAIN(0, pag))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Non-optional GOTO from VCAP IS2 lookup 0 to lookup 1.
|
|
|
|
* We cannot change the PAG at this point.
|
|
|
|
*/
|
|
|
|
for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
|
|
|
|
if (chain == VCAP_IS2_CHAIN(0, pag))
|
|
|
|
return (goto_target == VCAP_IS2_CHAIN(1, pag));
|
|
|
|
|
|
|
|
/* VCAP IS2 lookup 1 cannot jump anywhere */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ocelot_vcap_filter *
|
|
|
|
ocelot_find_vcap_filter_that_points_at(struct ocelot *ocelot, int chain)
|
|
|
|
{
|
|
|
|
struct ocelot_vcap_filter *filter;
|
|
|
|
struct ocelot_vcap_block *block;
|
|
|
|
int block_id;
|
|
|
|
|
|
|
|
block_id = ocelot_chain_to_block(chain, true);
|
|
|
|
if (block_id < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (block_id == VCAP_IS2) {
|
|
|
|
block = &ocelot->block[VCAP_IS1];
|
|
|
|
|
|
|
|
list_for_each_entry(filter, &block->rules, list)
|
|
|
|
if (filter->type == OCELOT_VCAP_FILTER_PAG &&
|
|
|
|
filter->goto_target == chain)
|
|
|
|
return filter;
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry(filter, &ocelot->dummy_rules, list)
|
|
|
|
if (filter->goto_target == chain)
|
|
|
|
return filter;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: offload VLAN mangle action to VCAP IS1
The VCAP_IS1_ACT_VID_REPLACE_ENA action, from the VCAP IS1 ingress TCAM,
changes the classified VLAN.
We are only exposing this ability for switch ports that are under VLAN
aware bridges. This is because in standalone ports mode and under a
bridge with vlan_filtering=0, the ocelot driver configures the switch to
operate as VLAN-unaware, so the classified VLAN is not derived from the
802.1Q header from the packet, but instead is always equal to the
port-based VLAN ID of the ingress port. We _can_ still change the
classified VLAN for packets when operating in this mode, but the end
result will most likely be a drop, since both the ingress and the egress
port need to be members of the modified VLAN. And even if we install the
new classified VLAN into the VLAN table of the switch, the result would
still not be as expected: we wouldn't see, on the output port, the
modified VLAN tag, but the original one, even though the classified VLAN
was indeed modified. This is because of how the hardware works: on
egress, what is pushed to the frame is a "port tag", which gives us the
following options:
- Tag all frames with port tag (derived from the classified VLAN)
- Tag all frames with port tag, except if the classified VLAN is 0 or
equal to the native VLAN of the egress port
- No port tag
Needless to say, in VLAN-unaware mode we are disabling the port tag.
Otherwise, the existing VLAN tag would be ignored, and a second VLAN
tag (the port tag), holding the classified VLAN, would be pushed
(instead of replacing the existing 802.1Q tag). This is definitely not
what the user wanted when installing a "vlan modify" action.
So it is simply not worth bothering with VLAN modify rules under other
configurations except when the ports are fully VLAN-aware.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-10-08 14:56:58 +03:00
|
|
|
static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
|
|
|
|
bool ingress, struct flow_cls_offload *f,
|
2020-06-20 18:43:46 +03:00
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 09:16:57 +02:00
|
|
|
{
|
net: mscc: ocelot: offload VLAN mangle action to VCAP IS1
The VCAP_IS1_ACT_VID_REPLACE_ENA action, from the VCAP IS1 ingress TCAM,
changes the classified VLAN.
We are only exposing this ability for switch ports that are under VLAN
aware bridges. This is because in standalone ports mode and under a
bridge with vlan_filtering=0, the ocelot driver configures the switch to
operate as VLAN-unaware, so the classified VLAN is not derived from the
802.1Q header from the packet, but instead is always equal to the
port-based VLAN ID of the ingress port. We _can_ still change the
classified VLAN for packets when operating in this mode, but the end
result will most likely be a drop, since both the ingress and the egress
port need to be members of the modified VLAN. And even if we install the
new classified VLAN into the VLAN table of the switch, the result would
still not be as expected: we wouldn't see, on the output port, the
modified VLAN tag, but the original one, even though the classified VLAN
was indeed modified. This is because of how the hardware works: on
egress, what is pushed to the frame is a "port tag", which gives us the
following options:
- Tag all frames with port tag (derived from the classified VLAN)
- Tag all frames with port tag, except if the classified VLAN is 0 or
equal to the native VLAN of the egress port
- No port tag
Needless to say, in VLAN-unaware mode we are disabling the port tag.
Otherwise, the existing VLAN tag would be ignored, and a second VLAN
tag (the port tag), holding the classified VLAN, would be pushed
(instead of replacing the existing 802.1Q tag). This is definitely not
what the user wanted when installing a "vlan modify" action.
So it is simply not worth bothering with VLAN modify rules under other
configurations except when the ports are fully VLAN-aware.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-10-08 14:56:58 +03:00
|
|
|
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
struct netlink_ext_ack *extack = f->common.extack;
|
|
|
|
bool allow_missing_goto_target = false;
|
2019-05-31 09:16:57 +02:00
|
|
|
const struct flow_action_entry *a;
|
2020-10-02 15:02:24 +03:00
|
|
|
enum ocelot_tag_tpid_sel tpid;
|
2020-10-02 15:02:27 +03:00
|
|
|
int i, chain, egress_port;
|
2020-03-29 14:51:57 +03:00
|
|
|
u64 rate;
|
2019-05-31 09:16:57 +02:00
|
|
|
|
2020-03-16 18:42:11 -07:00
|
|
|
if (!flow_action_basic_hw_stats_check(&f->rule->action,
|
|
|
|
f->common.extack))
|
2020-03-07 12:40:13 +01:00
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
chain = f->common.chain_index;
|
|
|
|
filter->block_id = ocelot_chain_to_block(chain, ingress);
|
|
|
|
if (filter->block_id < 0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack, "Cannot offload to this chain");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->block_id == VCAP_IS1 || filter->block_id == VCAP_IS2)
|
|
|
|
filter->lookup = ocelot_chain_to_lookup(chain);
|
2020-10-02 15:02:25 +03:00
|
|
|
if (filter->block_id == VCAP_IS2)
|
|
|
|
filter->pag = ocelot_chain_to_pag(chain);
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
|
|
|
|
filter->goto_target = -1;
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_DUMMY;
|
|
|
|
|
2019-05-31 09:16:57 +02:00
|
|
|
flow_action_for_each(i, a, &f->rule->action) {
|
|
|
|
switch (a->id) {
|
|
|
|
case FLOW_ACTION_DROP:
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
if (filter->block_id != VCAP_IS2) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Drop action can only be offloaded to VCAP IS2");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
2020-10-02 15:02:20 +03:00
|
|
|
filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
|
|
|
|
filter->action.port_mask = 0;
|
|
|
|
filter->action.police_ena = true;
|
|
|
|
filter->action.pol_ix = OCELOT_POLICER_DISCARD;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
2019-05-31 09:16:57 +02:00
|
|
|
break;
|
|
|
|
case FLOW_ACTION_TRAP:
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
if (filter->block_id != VCAP_IS2) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Trap action can only be offloaded to VCAP IS2");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
2020-10-02 15:02:20 +03:00
|
|
|
filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
|
|
|
|
filter->action.port_mask = 0;
|
|
|
|
filter->action.cpu_copy_ena = true;
|
|
|
|
filter->action.cpu_qu_num = 0;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
2019-05-31 09:16:57 +02:00
|
|
|
break;
|
2020-03-29 14:51:57 +03:00
|
|
|
case FLOW_ACTION_POLICE:
|
2020-10-02 15:02:25 +03:00
|
|
|
if (filter->block_id != VCAP_IS2 ||
|
|
|
|
filter->lookup != 0) {
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
2020-10-02 15:02:25 +03:00
|
|
|
"Police action can only be offloaded to VCAP IS2 lookup 0");
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
2020-10-02 15:02:20 +03:00
|
|
|
filter->action.police_ena = true;
|
2020-03-29 14:51:57 +03:00
|
|
|
rate = a->police.rate_bytes_ps;
|
2020-10-02 15:02:20 +03:00
|
|
|
filter->action.pol.rate = div_u64(rate, 1000) * 8;
|
|
|
|
filter->action.pol.burst = a->police.burst;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
|
|
|
break;
|
2020-10-02 15:02:27 +03:00
|
|
|
case FLOW_ACTION_REDIRECT:
|
|
|
|
if (filter->block_id != VCAP_IS2) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Redirect action can only be offloaded to VCAP IS2");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
egress_port = ocelot->ops->netdev_to_port(a->dev);
|
|
|
|
if (egress_port < 0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Destination not an ocelot port");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
filter->action.mask_mode = OCELOT_MASK_MODE_REDIRECT;
|
|
|
|
filter->action.port_mask = BIT(egress_port);
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
|
|
|
break;
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
case FLOW_ACTION_VLAN_POP:
|
|
|
|
if (filter->block_id != VCAP_IS1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VLAN pop action can only be offloaded to VCAP IS1");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
filter->action.vlan_pop_cnt_ena = true;
|
|
|
|
filter->action.vlan_pop_cnt++;
|
|
|
|
if (filter->action.vlan_pop_cnt > 2) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Cannot pop more than 2 VLAN headers");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
|
|
|
break;
|
net: mscc: ocelot: offload VLAN mangle action to VCAP IS1
The VCAP_IS1_ACT_VID_REPLACE_ENA action, from the VCAP IS1 ingress TCAM,
changes the classified VLAN.
We are only exposing this ability for switch ports that are under VLAN
aware bridges. This is because in standalone ports mode and under a
bridge with vlan_filtering=0, the ocelot driver configures the switch to
operate as VLAN-unaware, so the classified VLAN is not derived from the
802.1Q header from the packet, but instead is always equal to the
port-based VLAN ID of the ingress port. We _can_ still change the
classified VLAN for packets when operating in this mode, but the end
result will most likely be a drop, since both the ingress and the egress
port need to be members of the modified VLAN. And even if we install the
new classified VLAN into the VLAN table of the switch, the result would
still not be as expected: we wouldn't see, on the output port, the
modified VLAN tag, but the original one, even though the classified VLAN
was indeed modified. This is because of how the hardware works: on
egress, what is pushed to the frame is a "port tag", which gives us the
following options:
- Tag all frames with port tag (derived from the classified VLAN)
- Tag all frames with port tag, except if the classified VLAN is 0 or
equal to the native VLAN of the egress port
- No port tag
Needless to say, in VLAN-unaware mode we are disabling the port tag.
Otherwise, the existing VLAN tag would be ignored, and a second VLAN
tag (the port tag), holding the classified VLAN, would be pushed
(instead of replacing the existing 802.1Q tag). This is definitely not
what the user wanted when installing a "vlan modify" action.
So it is simply not worth bothering with VLAN modify rules under other
configurations except when the ports are fully VLAN-aware.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-10-08 14:56:58 +03:00
|
|
|
case FLOW_ACTION_VLAN_MANGLE:
|
|
|
|
if (filter->block_id != VCAP_IS1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VLAN modify action can only be offloaded to VCAP IS1");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (!ocelot_port->vlan_aware) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Can only modify VLAN under VLAN aware bridge");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
filter->action.vid_replace_ena = true;
|
|
|
|
filter->action.pcp_dei_ena = true;
|
|
|
|
filter->action.vid = a->vlan.vid;
|
|
|
|
filter->action.pcp = a->vlan.prio;
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
|
|
|
break;
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
case FLOW_ACTION_PRIORITY:
|
|
|
|
if (filter->block_id != VCAP_IS1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Priority action can only be offloaded to VCAP IS1");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (filter->goto_target != -1) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Last action must be GOTO");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
filter->action.qos_ena = true;
|
|
|
|
filter->action.qos_val = a->priority;
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
|
|
|
break;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
case FLOW_ACTION_GOTO:
|
|
|
|
filter->goto_target = a->chain_index;
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
|
2020-10-02 15:02:25 +03:00
|
|
|
if (filter->block_id == VCAP_IS1 && filter->lookup == 2) {
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
int pag = ocelot_chain_to_pag(filter->goto_target);
|
|
|
|
|
|
|
|
filter->action.pag_override_mask = 0xff;
|
|
|
|
filter->action.pag_val = pag;
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_PAG;
|
|
|
|
}
|
2020-03-29 14:51:57 +03:00
|
|
|
break;
|
2020-10-02 15:02:24 +03:00
|
|
|
case FLOW_ACTION_VLAN_PUSH:
|
|
|
|
if (filter->block_id != VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VLAN push action can only be offloaded to VCAP ES0");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
switch (ntohs(a->vlan.proto)) {
|
|
|
|
case ETH_P_8021Q:
|
|
|
|
tpid = OCELOT_TAG_TPID_SEL_8021Q;
|
|
|
|
break;
|
|
|
|
case ETH_P_8021AD:
|
|
|
|
tpid = OCELOT_TAG_TPID_SEL_8021AD;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Cannot push custom TPID");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
filter->action.tag_a_tpid_sel = tpid;
|
|
|
|
filter->action.push_outer_tag = OCELOT_ES0_TAG;
|
|
|
|
filter->action.tag_a_vid_sel = 1;
|
|
|
|
filter->action.vid_a_val = a->vlan.vid;
|
|
|
|
filter->action.pcp_a_val = a->vlan.prio;
|
|
|
|
filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
|
|
|
|
break;
|
2019-05-31 09:16:57 +02:00
|
|
|
default:
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
NL_SET_ERR_MSG_MOD(extack, "Cannot offload action");
|
2019-05-31 09:16:57 +02:00
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
if (filter->goto_target == -1) {
|
|
|
|
if ((filter->block_id == VCAP_IS2 && filter->lookup == 1) ||
|
|
|
|
chain == 0) {
|
|
|
|
allow_missing_goto_target = true;
|
|
|
|
} else {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack, "Missing GOTO action");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ocelot_is_goto_target_valid(filter->goto_target, chain, ingress) &&
|
|
|
|
!allow_missing_goto_target) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack, "Cannot offload this GOTO target");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:16:57 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
static int ocelot_flower_parse_indev(struct ocelot *ocelot, int port,
|
|
|
|
struct flow_cls_offload *f,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
|
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
|
|
|
|
int key_length = vcap->keys[VCAP_ES0_IGR_PORT].length;
|
|
|
|
struct netlink_ext_ack *extack = f->common.extack;
|
|
|
|
struct net_device *dev, *indev;
|
|
|
|
struct flow_match_meta match;
|
|
|
|
int ingress_port;
|
|
|
|
|
|
|
|
flow_rule_match_meta(rule, &match);
|
|
|
|
|
|
|
|
if (!match.mask->ingress_ifindex)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (match.mask->ingress_ifindex != 0xFFFFFFFF) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack, "Unsupported ingress ifindex mask");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
dev = ocelot->ops->port_to_netdev(ocelot, port);
|
|
|
|
if (!dev)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
indev = __dev_get_by_index(dev_net(dev), match.key->ingress_ifindex);
|
|
|
|
if (!indev) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Can't find the ingress port to match on");
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
ingress_port = ocelot->ops->netdev_to_port(indev);
|
|
|
|
if (ingress_port < 0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Can only offload an ocelot ingress port");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
if (ingress_port == port) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Ingress port is equal to the egress port");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
filter->ingress_port.value = ingress_port;
|
|
|
|
filter->ingress_port.mask = GENMASK(key_length - 1, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress,
|
|
|
|
struct flow_cls_offload *f,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 09:16:57 +02:00
|
|
|
{
|
2019-07-09 22:55:49 +02:00
|
|
|
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
|
2019-05-31 09:16:57 +02:00
|
|
|
struct flow_dissector *dissector = rule->match.dissector;
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
struct netlink_ext_ack *extack = f->common.extack;
|
2020-04-20 19:27:41 +03:00
|
|
|
u16 proto = ntohs(f->common.protocol);
|
|
|
|
bool match_protocol = true;
|
2020-10-02 15:02:24 +03:00
|
|
|
int ret;
|
2019-05-31 09:16:57 +02:00
|
|
|
|
|
|
|
if (dissector->used_keys &
|
|
|
|
~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_BASIC) |
|
2020-10-02 15:02:24 +03:00
|
|
|
BIT(FLOW_DISSECTOR_KEY_META) |
|
2019-05-31 09:16:57 +02:00
|
|
|
BIT(FLOW_DISSECTOR_KEY_PORTS) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_VLAN) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS))) {
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
/* For VCAP ES0 (egress rewriter) we can match on the ingress port */
|
|
|
|
if (!ingress) {
|
|
|
|
ret = ocelot_flower_parse_indev(ocelot, port, f, filter);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:16:57 +02:00
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
|
|
|
|
struct flow_match_control match;
|
|
|
|
|
|
|
|
flow_rule_match_control(rule, &match);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
|
|
|
struct flow_match_eth_addrs match;
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
if (filter->block_id == VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VCAP ES0 cannot match on MAC address");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
if (filter->block_id == VCAP_IS1 &&
|
|
|
|
!is_zero_ether_addr(match.mask->dst)) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Key type S1_NORMAL cannot match on destination MAC");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:16:57 +02:00
|
|
|
/* The hw support mac matches only for MAC_ETYPE key,
|
|
|
|
* therefore if other matches(port, tcp flags, etc) are added
|
|
|
|
* then just bail out
|
|
|
|
*/
|
|
|
|
if ((dissector->used_keys &
|
|
|
|
(BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_BASIC) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_CONTROL))) !=
|
|
|
|
(BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_BASIC) |
|
|
|
|
BIT(FLOW_DISSECTOR_KEY_CONTROL)))
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
flow_rule_match_eth_addrs(rule, &match);
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key_type = OCELOT_VCAP_KEY_ETYPE;
|
|
|
|
ether_addr_copy(filter->key.etype.dmac.value,
|
2019-05-31 09:16:57 +02:00
|
|
|
match.key->dst);
|
2020-06-20 18:43:46 +03:00
|
|
|
ether_addr_copy(filter->key.etype.smac.value,
|
2019-05-31 09:16:57 +02:00
|
|
|
match.key->src);
|
2020-06-20 18:43:46 +03:00
|
|
|
ether_addr_copy(filter->key.etype.dmac.mask,
|
2019-05-31 09:16:57 +02:00
|
|
|
match.mask->dst);
|
2020-06-20 18:43:46 +03:00
|
|
|
ether_addr_copy(filter->key.etype.smac.mask,
|
2019-05-31 09:16:57 +02:00
|
|
|
match.mask->src);
|
|
|
|
goto finished_key_parsing;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
|
|
|
|
struct flow_match_basic match;
|
|
|
|
|
|
|
|
flow_rule_match_basic(rule, &match);
|
|
|
|
if (ntohs(match.key->n_proto) == ETH_P_IP) {
|
2020-10-02 15:02:24 +03:00
|
|
|
if (filter->block_id == VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VCAP ES0 cannot match on IP protocol");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key_type = OCELOT_VCAP_KEY_IPV4;
|
|
|
|
filter->key.ipv4.proto.value[0] =
|
2019-05-31 09:16:57 +02:00
|
|
|
match.key->ip_proto;
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key.ipv4.proto.mask[0] =
|
2019-05-31 09:16:57 +02:00
|
|
|
match.mask->ip_proto;
|
2020-04-20 19:27:41 +03:00
|
|
|
match_protocol = false;
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
if (ntohs(match.key->n_proto) == ETH_P_IPV6) {
|
2020-10-02 15:02:24 +03:00
|
|
|
if (filter->block_id == VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VCAP ES0 cannot match on IP protocol");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key_type = OCELOT_VCAP_KEY_IPV6;
|
|
|
|
filter->key.ipv6.proto.value[0] =
|
2019-05-31 09:16:57 +02:00
|
|
|
match.key->ip_proto;
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key.ipv6.proto.mask[0] =
|
2019-05-31 09:16:57 +02:00
|
|
|
match.mask->ip_proto;
|
2020-04-20 19:27:41 +03:00
|
|
|
match_protocol = false;
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS) &&
|
2020-04-20 19:27:41 +03:00
|
|
|
proto == ETH_P_IP) {
|
2019-05-31 09:16:57 +02:00
|
|
|
struct flow_match_ipv4_addrs match;
|
|
|
|
u8 *tmp;
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
if (filter->block_id == VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VCAP ES0 cannot match on IP address");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:23 +03:00
|
|
|
if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"Key type S1_NORMAL cannot match on destination IP");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:16:57 +02:00
|
|
|
flow_rule_match_ipv4_addrs(rule, &match);
|
2020-06-20 18:43:46 +03:00
|
|
|
tmp = &filter->key.ipv4.sip.value.addr[0];
|
2019-05-31 09:16:57 +02:00
|
|
|
memcpy(tmp, &match.key->src, 4);
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
tmp = &filter->key.ipv4.sip.mask.addr[0];
|
2019-05-31 09:16:57 +02:00
|
|
|
memcpy(tmp, &match.mask->src, 4);
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
tmp = &filter->key.ipv4.dip.value.addr[0];
|
2019-05-31 09:16:57 +02:00
|
|
|
memcpy(tmp, &match.key->dst, 4);
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
tmp = &filter->key.ipv4.dip.mask.addr[0];
|
2019-05-31 09:16:57 +02:00
|
|
|
memcpy(tmp, &match.mask->dst, 4);
|
2020-04-20 19:27:41 +03:00
|
|
|
match_protocol = false;
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS) &&
|
2020-04-20 19:27:41 +03:00
|
|
|
proto == ETH_P_IPV6) {
|
2019-05-31 09:16:57 +02:00
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
|
|
|
|
struct flow_match_ports match;
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
if (filter->block_id == VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VCAP ES0 cannot match on L4 ports");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:16:57 +02:00
|
|
|
flow_rule_match_ports(rule, &match);
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key.ipv4.sport.value = ntohs(match.key->src);
|
|
|
|
filter->key.ipv4.sport.mask = ntohs(match.mask->src);
|
|
|
|
filter->key.ipv4.dport.value = ntohs(match.key->dst);
|
|
|
|
filter->key.ipv4.dport.mask = ntohs(match.mask->dst);
|
2020-04-20 19:27:41 +03:00
|
|
|
match_protocol = false;
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
|
|
|
|
struct flow_match_vlan match;
|
|
|
|
|
|
|
|
flow_rule_match_vlan(rule, &match);
|
2020-06-20 18:43:46 +03:00
|
|
|
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;
|
2020-04-20 19:27:41 +03:00
|
|
|
match_protocol = false;
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
finished_key_parsing:
|
2020-04-20 19:27:41 +03:00
|
|
|
if (match_protocol && proto != ETH_P_ALL) {
|
2020-10-02 15:02:24 +03:00
|
|
|
if (filter->block_id == VCAP_ES0) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
|
|
|
"VCAP ES0 cannot match on L2 proto");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2020-04-20 19:27:41 +03:00
|
|
|
/* TODO: support SNAP, LLC etc */
|
|
|
|
if (proto < ETH_P_802_3_MIN)
|
|
|
|
return -EOPNOTSUPP;
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->key_type = OCELOT_VCAP_KEY_ETYPE;
|
|
|
|
*(__be16 *)filter->key.etype.etype.value = htons(proto);
|
|
|
|
*(__be16 *)filter->key.etype.etype.mask = htons(0xffff);
|
2020-04-20 19:27:41 +03:00
|
|
|
}
|
2020-06-20 18:43:46 +03:00
|
|
|
/* else, a filter of type OCELOT_VCAP_KEY_ANY is implicitly added */
|
2020-04-20 19:27:41 +03:00
|
|
|
|
2020-09-30 01:27:28 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
static int ocelot_flower_parse(struct ocelot *ocelot, int port, bool ingress,
|
|
|
|
struct flow_cls_offload *f,
|
2020-09-30 01:27:28 +03:00
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
filter->prio = f->common.prio;
|
|
|
|
filter->id = f->cookie;
|
2020-09-30 01:27:28 +03:00
|
|
|
|
net: mscc: ocelot: offload VLAN mangle action to VCAP IS1
The VCAP_IS1_ACT_VID_REPLACE_ENA action, from the VCAP IS1 ingress TCAM,
changes the classified VLAN.
We are only exposing this ability for switch ports that are under VLAN
aware bridges. This is because in standalone ports mode and under a
bridge with vlan_filtering=0, the ocelot driver configures the switch to
operate as VLAN-unaware, so the classified VLAN is not derived from the
802.1Q header from the packet, but instead is always equal to the
port-based VLAN ID of the ingress port. We _can_ still change the
classified VLAN for packets when operating in this mode, but the end
result will most likely be a drop, since both the ingress and the egress
port need to be members of the modified VLAN. And even if we install the
new classified VLAN into the VLAN table of the switch, the result would
still not be as expected: we wouldn't see, on the output port, the
modified VLAN tag, but the original one, even though the classified VLAN
was indeed modified. This is because of how the hardware works: on
egress, what is pushed to the frame is a "port tag", which gives us the
following options:
- Tag all frames with port tag (derived from the classified VLAN)
- Tag all frames with port tag, except if the classified VLAN is 0 or
equal to the native VLAN of the egress port
- No port tag
Needless to say, in VLAN-unaware mode we are disabling the port tag.
Otherwise, the existing VLAN tag would be ignored, and a second VLAN
tag (the port tag), holding the classified VLAN, would be pushed
(instead of replacing the existing 802.1Q tag). This is definitely not
what the user wanted when installing a "vlan modify" action.
So it is simply not worth bothering with VLAN modify rules under other
configurations except when the ports are fully VLAN-aware.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-10-08 14:56:58 +03:00
|
|
|
ret = ocelot_flower_parse_action(ocelot, port, ingress, f, filter);
|
2020-09-30 01:27:28 +03:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
return ocelot_flower_parse_key(ocelot, port, ingress, f, filter);
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
static struct ocelot_vcap_filter
|
2020-10-02 15:02:24 +03:00
|
|
|
*ocelot_vcap_filter_create(struct ocelot *ocelot, int port, bool ingress,
|
|
|
|
struct flow_cls_offload *f)
|
2019-05-31 09:16:57 +02:00
|
|
|
{
|
2020-06-20 18:43:46 +03:00
|
|
|
struct ocelot_vcap_filter *filter;
|
2019-05-31 09:16:57 +02:00
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
filter = kzalloc(sizeof(*filter), GFP_KERNEL);
|
|
|
|
if (!filter)
|
2019-05-31 09:16:57 +02:00
|
|
|
return NULL;
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
if (ingress) {
|
|
|
|
filter->ingress_port_mask = BIT(port);
|
|
|
|
} else {
|
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
|
|
|
|
int key_length = vcap->keys[VCAP_ES0_EGR_PORT].length;
|
|
|
|
|
|
|
|
filter->egress_port.value = port;
|
|
|
|
filter->egress_port.mask = GENMASK(key_length - 1, 0);
|
|
|
|
}
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
return filter;
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
static int ocelot_vcap_dummy_filter_add(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
list_add(&filter->list, &ocelot->dummy_rules);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ocelot_vcap_dummy_filter_del(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
list_del(&filter->list);
|
|
|
|
kfree(filter);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 16:31:06 +02:00
|
|
|
int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
|
|
|
|
struct flow_cls_offload *f, bool ingress)
|
2019-05-31 09:16:57 +02:00
|
|
|
{
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
struct netlink_ext_ack *extack = f->common.extack;
|
2020-06-20 18:43:46 +03:00
|
|
|
struct ocelot_vcap_filter *filter;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
int chain = f->common.chain_index;
|
2019-05-31 09:16:57 +02:00
|
|
|
int ret;
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
if (chain && !ocelot_find_vcap_filter_that_points_at(ocelot, chain)) {
|
|
|
|
NL_SET_ERR_MSG_MOD(extack, "No default GOTO action points to this chain");
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
filter = ocelot_vcap_filter_create(ocelot, port, ingress, f);
|
2020-06-20 18:43:46 +03:00
|
|
|
if (!filter)
|
2019-05-31 09:16:57 +02:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2020-10-02 15:02:24 +03:00
|
|
|
ret = ocelot_flower_parse(ocelot, port, ingress, f, filter);
|
2019-05-31 09:16:57 +02:00
|
|
|
if (ret) {
|
2020-06-20 18:43:46 +03:00
|
|
|
kfree(filter);
|
2019-05-31 09:16:57 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
/* The non-optional GOTOs for the TCAM skeleton don't need
|
|
|
|
* to be actually offloaded.
|
|
|
|
*/
|
|
|
|
if (filter->type == OCELOT_VCAP_FILTER_DUMMY)
|
|
|
|
return ocelot_vcap_dummy_filter_add(ocelot, filter);
|
|
|
|
|
2020-06-20 18:43:46 +03:00
|
|
|
return ocelot_vcap_filter_add(ocelot, filter, f->common.extack);
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 16:31:06 +02:00
|
|
|
EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);
|
2019-05-31 09:16:57 +02:00
|
|
|
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 16:31:06 +02:00
|
|
|
int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
|
|
|
|
struct flow_cls_offload *f, bool ingress)
|
2019-05-31 09:16:57 +02:00
|
|
|
{
|
2020-09-30 01:27:33 +03:00
|
|
|
struct ocelot_vcap_filter *filter;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
struct ocelot_vcap_block *block;
|
|
|
|
int block_id;
|
|
|
|
|
|
|
|
block_id = ocelot_chain_to_block(f->common.chain_index, ingress);
|
|
|
|
if (block_id < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
block = &ocelot->block[block_id];
|
2019-05-31 09:16:57 +02:00
|
|
|
|
2020-09-30 01:27:33 +03:00
|
|
|
filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie);
|
|
|
|
if (!filter)
|
|
|
|
return 0;
|
2019-05-31 09:16:57 +02:00
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
if (filter->type == OCELOT_VCAP_FILTER_DUMMY)
|
|
|
|
return ocelot_vcap_dummy_filter_del(ocelot, filter);
|
|
|
|
|
2020-09-30 01:27:33 +03:00
|
|
|
return ocelot_vcap_filter_del(ocelot, filter);
|
2019-05-31 09:16:57 +02:00
|
|
|
}
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 16:31:06 +02:00
|
|
|
EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);
|
2019-05-31 09:16:57 +02:00
|
|
|
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 16:31:06 +02:00
|
|
|
int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
|
|
|
|
struct flow_cls_offload *f, bool ingress)
|
2019-05-31 09:16:57 +02:00
|
|
|
{
|
2020-09-30 01:27:33 +03:00
|
|
|
struct ocelot_vcap_filter *filter;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
struct ocelot_vcap_block *block;
|
|
|
|
int block_id, ret;
|
|
|
|
|
|
|
|
block_id = ocelot_chain_to_block(f->common.chain_index, ingress);
|
|
|
|
if (block_id < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
block = &ocelot->block[block_id];
|
2019-05-31 09:16:57 +02:00
|
|
|
|
2020-09-30 01:27:33 +03:00
|
|
|
filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie);
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 15:02:22 +03:00
|
|
|
if (!filter || filter->type == OCELOT_VCAP_FILTER_DUMMY)
|
2020-09-30 01:27:33 +03:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
ret = ocelot_vcap_filter_stats_update(ocelot, filter);
|
2019-05-31 09:16:57 +02:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2020-09-30 01:27:33 +03:00
|
|
|
flow_stats_update(&f->stats, 0x0, filter->stats.pkts, 0, 0x0,
|
2020-03-28 16:37:43 +01:00
|
|
|
FLOW_ACTION_HW_STATS_IMMEDIATE);
|
2019-05-31 09:16:57 +02:00
|
|
|
return 0;
|
|
|
|
}
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 16:31:06 +02:00
|
|
|
EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats);
|