OSDN Git Service

nfp: flower-ct: fill ct metadata check function
authorLouis Peens <louis.peens@corigine.com>
Wed, 16 Jun 2021 10:02:06 +0000 (12:02 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Jun 2021 19:42:53 +0000 (12:42 -0700)
Fill in check_meta stub to check that ct_metadata action fields in
the nft flow matches the ct_match data of the post_ct flow.

Signed-off-by: Louis Peens <louis.peens@corigine.com>
Signed-off-by: Yinjun Zhang <yinjun.zhang@corigine.com>
Signed-off-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/flower/conntrack.c

index 8bab890..6aecaf4 100644 (file)
@@ -19,6 +19,9 @@ const struct rhashtable_params nfp_nft_ct_merge_params = {
        .automatic_shrinking    = true,
 };
 
+static struct flow_action_entry *get_flow_act(struct flow_rule *rule,
+                                             enum flow_action_id act_id);
+
 /**
  * get_hashentry() - Wrapper around hashtable lookup.
  * @ht:                hashtable where entry could be found
@@ -258,7 +261,31 @@ static int nfp_ct_merge_act_check(struct nfp_fl_ct_flow_entry *pre_ct_entry,
 static int nfp_ct_check_meta(struct nfp_fl_ct_flow_entry *post_ct_entry,
                             struct nfp_fl_ct_flow_entry *nft_entry)
 {
-       return 0;
+       struct flow_dissector *dissector = post_ct_entry->rule->match.dissector;
+       struct flow_action_entry *ct_met;
+       struct flow_match_ct ct;
+       int i;
+
+       ct_met = get_flow_act(nft_entry->rule, FLOW_ACTION_CT_METADATA);
+       if (ct_met && (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CT))) {
+               u32 *act_lbl;
+
+               act_lbl = ct_met->ct_metadata.labels;
+               flow_rule_match_ct(post_ct_entry->rule, &ct);
+               for (i = 0; i < 4; i++) {
+                       if ((ct.key->ct_labels[i] & ct.mask->ct_labels[i]) ^
+                           (act_lbl[i] & ct.mask->ct_labels[i]))
+                               return -EINVAL;
+               }
+
+               if ((ct.key->ct_mark & ct.mask->ct_mark) ^
+                   (ct_met->ct_metadata.mark & ct.mask->ct_mark))
+                       return -EINVAL;
+
+               return 0;
+       }
+
+       return -EINVAL;
 }
 
 static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry)
@@ -727,13 +754,13 @@ void nfp_fl_ct_clean_flow_entry(struct nfp_fl_ct_flow_entry *entry)
        kfree(entry);
 }
 
-static struct flow_action_entry *get_flow_act(struct flow_cls_offload *flow,
+static struct flow_action_entry *get_flow_act(struct flow_rule *rule,
                                              enum flow_action_id act_id)
 {
        struct flow_action_entry *act = NULL;
        int i;
 
-       flow_action_for_each(i, act, &flow->rule->action) {
+       flow_action_for_each(i, act, &rule->action) {
                if (act->id == act_id)
                        return act;
        }
@@ -791,14 +818,14 @@ int nfp_fl_ct_handle_pre_ct(struct nfp_flower_priv *priv,
        struct nfp_fl_ct_zone_entry *zt;
        int err;
 
-       ct_act = get_flow_act(flow, FLOW_ACTION_CT);
+       ct_act = get_flow_act(flow->rule, FLOW_ACTION_CT);
        if (!ct_act) {
                NL_SET_ERR_MSG_MOD(extack,
                                   "unsupported offload: Conntrack action empty in conntrack offload");
                return -EOPNOTSUPP;
        }
 
-       ct_goto = get_flow_act(flow, FLOW_ACTION_GOTO);
+       ct_goto = get_flow_act(flow->rule, FLOW_ACTION_GOTO);
        if (!ct_goto) {
                NL_SET_ERR_MSG_MOD(extack,
                                   "unsupported offload: Conntrack requires ACTION_GOTO");