@@ -26,10 +26,24 @@ struct sparx5_tc_flower_parse_usage {
2626 */
2727static u16 sparx5_tc_known_etypes [] = {
2828 ETH_P_ALL ,
29+ ETH_P_ARP ,
2930 ETH_P_IP ,
3031 ETH_P_IPV6 ,
3132};
3233
34+ enum sparx5_is2_arp_opcode {
35+ SPX5_IS2_ARP_REQUEST ,
36+ SPX5_IS2_ARP_REPLY ,
37+ SPX5_IS2_RARP_REQUEST ,
38+ SPX5_IS2_RARP_REPLY ,
39+ };
40+
41+ enum tc_arp_opcode {
42+ TC_ARP_OP_RESERVED ,
43+ TC_ARP_OP_REQUEST ,
44+ TC_ARP_OP_REPLY ,
45+ };
46+
3347static bool sparx5_tc_is_known_etype (u16 etype )
3448{
3549 int idx ;
@@ -404,6 +418,67 @@ sparx5_tc_flower_handler_tcp_usage(struct sparx5_tc_flower_parse_usage *st)
404418 return err ;
405419}
406420
421+ static int
422+ sparx5_tc_flower_handler_arp_usage (struct sparx5_tc_flower_parse_usage * st )
423+ {
424+ struct flow_match_arp mt ;
425+ u16 value , mask ;
426+ u32 ipval , ipmsk ;
427+ int err ;
428+
429+ flow_rule_match_arp (st -> frule , & mt );
430+
431+ if (mt .mask -> op ) {
432+ mask = 0x3 ;
433+ if (st -> l3_proto == ETH_P_ARP ) {
434+ value = mt .key -> op == TC_ARP_OP_REQUEST ?
435+ SPX5_IS2_ARP_REQUEST :
436+ SPX5_IS2_ARP_REPLY ;
437+ } else { /* RARP */
438+ value = mt .key -> op == TC_ARP_OP_REQUEST ?
439+ SPX5_IS2_RARP_REQUEST :
440+ SPX5_IS2_RARP_REPLY ;
441+ }
442+ err = vcap_rule_add_key_u32 (st -> vrule , VCAP_KF_ARP_OPCODE ,
443+ value , mask );
444+ if (err )
445+ goto out ;
446+ }
447+
448+ /* The IS2 ARP keyset does not support ARP hardware addresses */
449+ if (!is_zero_ether_addr (mt .mask -> sha ) ||
450+ !is_zero_ether_addr (mt .mask -> tha ))
451+ goto out ;
452+
453+ if (mt .mask -> sip ) {
454+ ipval = be32_to_cpu ((__force __be32 )mt .key -> sip );
455+ ipmsk = be32_to_cpu ((__force __be32 )mt .mask -> sip );
456+
457+ err = vcap_rule_add_key_u32 (st -> vrule , VCAP_KF_L3_IP4_SIP ,
458+ ipval , ipmsk );
459+ if (err )
460+ goto out ;
461+ }
462+
463+ if (mt .mask -> tip ) {
464+ ipval = be32_to_cpu ((__force __be32 )mt .key -> tip );
465+ ipmsk = be32_to_cpu ((__force __be32 )mt .mask -> tip );
466+
467+ err = vcap_rule_add_key_u32 (st -> vrule , VCAP_KF_L3_IP4_DIP ,
468+ ipval , ipmsk );
469+ if (err )
470+ goto out ;
471+ }
472+
473+ st -> used_keys |= BIT (FLOW_DISSECTOR_KEY_ARP );
474+
475+ return err ;
476+
477+ out :
478+ NL_SET_ERR_MSG_MOD (st -> fco -> common .extack , "arp parse error" );
479+ return err ;
480+ }
481+
407482static int
408483sparx5_tc_flower_handler_ip_usage (struct sparx5_tc_flower_parse_usage * st )
409484{
@@ -438,6 +513,7 @@ static int (*sparx5_tc_flower_usage_handlers[])(struct sparx5_tc_flower_parse_us
438513 [FLOW_DISSECTOR_KEY_BASIC ] = sparx5_tc_flower_handler_basic_usage ,
439514 [FLOW_DISSECTOR_KEY_VLAN ] = sparx5_tc_flower_handler_vlan_usage ,
440515 [FLOW_DISSECTOR_KEY_TCP ] = sparx5_tc_flower_handler_tcp_usage ,
516+ [FLOW_DISSECTOR_KEY_ARP ] = sparx5_tc_flower_handler_arp_usage ,
441517 [FLOW_DISSECTOR_KEY_IP ] = sparx5_tc_flower_handler_ip_usage ,
442518};
443519
0 commit comments