Skip to content

Commit

Permalink
net: microchip: sparx5: Add support for TC flower ARP dissector
Browse files Browse the repository at this point in the history
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: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Steen Hegelund authored and David S. Miller committed Nov 14, 2022
1 parent 70ea86a commit 3a344f9
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
76 changes: 76 additions & 0 deletions drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,24 @@ struct sparx5_tc_flower_parse_usage {
*/
static u16 sparx5_tc_known_etypes[] = {
ETH_P_ALL,
ETH_P_ARP,
ETH_P_IP,
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)
{
int idx;
Expand Down Expand Up @@ -404,6 +418,67 @@ sparx5_tc_flower_handler_tcp_usage(struct sparx5_tc_flower_parse_usage *st)
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
sparx5_tc_flower_handler_ip_usage(struct sparx5_tc_flower_parse_usage *st)
{
Expand Down Expand Up @@ -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_VLAN] = sparx5_tc_flower_handler_vlan_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,
};

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_IPV6_MC_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 (portno = 0; portno < SPX5_PORTS; ++portno) {
spx5_wr(keysel, sparx5,
Expand Down

0 comments on commit 3a344f9

Please sign in to comment.