Commit 3a344f99 authored by Steen Hegelund's avatar Steen Hegelund Committed by David S. Miller

net: microchip: sparx5: Add support for TC flower ARP dissector

This add support for Sparx5 for dissecting TC ARP flower filter keys and
sets up the Sparx5 IS2 VCAP to generate the ARP keyset for ARP frames.
Signed-off-by: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 70ea86a0
...@@ -26,10 +26,24 @@ struct sparx5_tc_flower_parse_usage { ...@@ -26,10 +26,24 @@ struct sparx5_tc_flower_parse_usage {
*/ */
static u16 sparx5_tc_known_etypes[] = { static u16 sparx5_tc_known_etypes[] = {
ETH_P_ALL, ETH_P_ALL,
ETH_P_ARP,
ETH_P_IP, ETH_P_IP,
ETH_P_IPV6, ETH_P_IPV6,
}; };
enum sparx5_is2_arp_opcode {
SPX5_IS2_ARP_REQUEST,
SPX5_IS2_ARP_REPLY,
SPX5_IS2_RARP_REQUEST,
SPX5_IS2_RARP_REPLY,
};
enum tc_arp_opcode {
TC_ARP_OP_RESERVED,
TC_ARP_OP_REQUEST,
TC_ARP_OP_REPLY,
};
static bool sparx5_tc_is_known_etype(u16 etype) static bool sparx5_tc_is_known_etype(u16 etype)
{ {
int idx; int idx;
...@@ -404,6 +418,67 @@ sparx5_tc_flower_handler_tcp_usage(struct sparx5_tc_flower_parse_usage *st) ...@@ -404,6 +418,67 @@ sparx5_tc_flower_handler_tcp_usage(struct sparx5_tc_flower_parse_usage *st)
return err; return err;
} }
static int
sparx5_tc_flower_handler_arp_usage(struct sparx5_tc_flower_parse_usage *st)
{
struct flow_match_arp mt;
u16 value, mask;
u32 ipval, ipmsk;
int err;
flow_rule_match_arp(st->frule, &mt);
if (mt.mask->op) {
mask = 0x3;
if (st->l3_proto == ETH_P_ARP) {
value = mt.key->op == TC_ARP_OP_REQUEST ?
SPX5_IS2_ARP_REQUEST :
SPX5_IS2_ARP_REPLY;
} else { /* RARP */
value = mt.key->op == TC_ARP_OP_REQUEST ?
SPX5_IS2_RARP_REQUEST :
SPX5_IS2_RARP_REPLY;
}
err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ARP_OPCODE,
value, mask);
if (err)
goto out;
}
/* The IS2 ARP keyset does not support ARP hardware addresses */
if (!is_zero_ether_addr(mt.mask->sha) ||
!is_zero_ether_addr(mt.mask->tha))
goto out;
if (mt.mask->sip) {
ipval = be32_to_cpu((__force __be32)mt.key->sip);
ipmsk = be32_to_cpu((__force __be32)mt.mask->sip);
err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_SIP,
ipval, ipmsk);
if (err)
goto out;
}
if (mt.mask->tip) {
ipval = be32_to_cpu((__force __be32)mt.key->tip);
ipmsk = be32_to_cpu((__force __be32)mt.mask->tip);
err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_DIP,
ipval, ipmsk);
if (err)
goto out;
}
st->used_keys |= BIT(FLOW_DISSECTOR_KEY_ARP);
return err;
out:
NL_SET_ERR_MSG_MOD(st->fco->common.extack, "arp parse error");
return err;
}
static int static int
sparx5_tc_flower_handler_ip_usage(struct sparx5_tc_flower_parse_usage *st) sparx5_tc_flower_handler_ip_usage(struct sparx5_tc_flower_parse_usage *st)
{ {
...@@ -438,6 +513,7 @@ static int (*sparx5_tc_flower_usage_handlers[])(struct sparx5_tc_flower_parse_us ...@@ -438,6 +513,7 @@ static int (*sparx5_tc_flower_usage_handlers[])(struct sparx5_tc_flower_parse_us
[FLOW_DISSECTOR_KEY_BASIC] = sparx5_tc_flower_handler_basic_usage, [FLOW_DISSECTOR_KEY_BASIC] = sparx5_tc_flower_handler_basic_usage,
[FLOW_DISSECTOR_KEY_VLAN] = sparx5_tc_flower_handler_vlan_usage, [FLOW_DISSECTOR_KEY_VLAN] = sparx5_tc_flower_handler_vlan_usage,
[FLOW_DISSECTOR_KEY_TCP] = sparx5_tc_flower_handler_tcp_usage, [FLOW_DISSECTOR_KEY_TCP] = sparx5_tc_flower_handler_tcp_usage,
[FLOW_DISSECTOR_KEY_ARP] = sparx5_tc_flower_handler_arp_usage,
[FLOW_DISSECTOR_KEY_IP] = sparx5_tc_flower_handler_ip_usage, [FLOW_DISSECTOR_KEY_IP] = sparx5_tc_flower_handler_ip_usage,
}; };
......
...@@ -540,7 +540,7 @@ static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5, ...@@ -540,7 +540,7 @@ static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER, VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER,
VCAP_IS2_PS_IPV6_MC_IP_7TUPLE, VCAP_IS2_PS_IPV6_MC_IP_7TUPLE,
VCAP_IS2_PS_IPV6_UC_IP_7TUPLE, VCAP_IS2_PS_IPV6_UC_IP_7TUPLE,
VCAP_IS2_PS_ARP_MAC_ETYPE); VCAP_IS2_PS_ARP_ARP);
for (lookup = 0; lookup < admin->lookups; ++lookup) { for (lookup = 0; lookup < admin->lookups; ++lookup) {
for (portno = 0; portno < SPX5_PORTS; ++portno) { for (portno = 0; portno < SPX5_PORTS; ++portno) {
spx5_wr(keysel, sparx5, spx5_wr(keysel, sparx5,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment