Skip to content

Commit 29486b6

Browse files
junfengganguy11
authored andcommitted
ice: add profile conflict check for AVF FDIR
Add profile conflict check while adding some FDIR rules to avoid unexpected flow behavior, rules may have conflict including: IPv4 <---> {IPv4_UDP, IPv4_TCP, IPv4_SCTP} IPv6 <---> {IPv6_UDP, IPv6_TCP, IPv6_SCTP} For example, when we create an FDIR rule for IPv4, this rule will work on packets including IPv4, IPv4_UDP, IPv4_TCP and IPv4_SCTP. But if we then create an FDIR rule for IPv4_UDP and then destroy it, the first FDIR rule for IPv4 cannot work on pkt IPv4_UDP then. To prevent this unexpected behavior, we add restriction in software when creating FDIR rules by adding necessary profile conflict check. Fixes: 1f7ea1c ("ice: Enable FDIR Configure for AVF") Signed-off-by: Junfeng Guo <[email protected]> Tested-by: Rafal Romanowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent d94dbdc commit 29486b6

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,72 @@ static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf)
541541
}
542542
}
543543

544+
/**
545+
* ice_vc_fdir_has_prof_conflict
546+
* @vf: pointer to the VF structure
547+
* @conf: FDIR configuration for each filter
548+
*
549+
* Check if @conf has conflicting profile with existing profiles
550+
*
551+
* Return: true on success, and false on error.
552+
*/
553+
static bool
554+
ice_vc_fdir_has_prof_conflict(struct ice_vf *vf,
555+
struct virtchnl_fdir_fltr_conf *conf)
556+
{
557+
struct ice_fdir_fltr *desc;
558+
559+
list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
560+
struct virtchnl_fdir_fltr_conf *existing_conf;
561+
enum ice_fltr_ptype flow_type_a, flow_type_b;
562+
struct ice_fdir_fltr *a, *b;
563+
564+
existing_conf = to_fltr_conf_from_desc(desc);
565+
a = &existing_conf->input;
566+
b = &conf->input;
567+
flow_type_a = a->flow_type;
568+
flow_type_b = b->flow_type;
569+
570+
/* No need to compare two rules with different tunnel types or
571+
* with the same protocol type.
572+
*/
573+
if (existing_conf->ttype != conf->ttype ||
574+
flow_type_a == flow_type_b)
575+
continue;
576+
577+
switch (flow_type_a) {
578+
case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
579+
case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
580+
case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
581+
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
582+
return true;
583+
break;
584+
case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
585+
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
586+
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
587+
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_SCTP)
588+
return true;
589+
break;
590+
case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
591+
case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
592+
case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
593+
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_OTHER)
594+
return true;
595+
break;
596+
case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
597+
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
598+
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
599+
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_SCTP)
600+
return true;
601+
break;
602+
default:
603+
break;
604+
}
605+
}
606+
607+
return false;
608+
}
609+
544610
/**
545611
* ice_vc_fdir_write_flow_prof
546612
* @vf: pointer to the VF structure
@@ -677,6 +743,13 @@ ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
677743
enum ice_fltr_ptype flow;
678744
int ret;
679745

746+
ret = ice_vc_fdir_has_prof_conflict(vf, conf);
747+
if (ret) {
748+
dev_dbg(dev, "Found flow profile conflict for VF %d\n",
749+
vf->vf_id);
750+
return ret;
751+
}
752+
680753
flow = input->flow_type;
681754
ret = ice_vc_fdir_alloc_prof(vf, flow);
682755
if (ret) {

0 commit comments

Comments
 (0)