Commit d8ce0275 authored by Louis Peens's avatar Louis Peens Committed by David S. Miller
Browse files

nfp: flower: fix pre_tun mask id allocation



pre_tun_rule flows does not follow the usual add-flow path, instead
they are used to update the pre_tun table on the firmware. This means
that if the mask-id gets allocated here the firmware will never see the
"NFP_FL_META_FLAG_MANAGE_MASK" flag for the specific mask id, which
triggers the allocation on the firmware side. This leads to the firmware
mask being corrupted and causing all sorts of strange behaviour.

Fixes: f12725d9 ("nfp: flower: offload pre-tunnel rules")
Signed-off-by: default avatarLouis Peens <louis.peens@corigine.com>
Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5c4f5e19
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -327,8 +327,14 @@ int nfp_compile_flow_metadata(struct nfp_app *app,
		goto err_free_ctx_entry;
	}

	/* Do net allocate a mask-id for pre_tun_rules. These flows are used to
	 * configure the pre_tun table and are never actually send to the
	 * firmware as an add-flow message. This causes the mask-id allocation
	 * on the firmware to get out of sync if allocated here.
	 */
	new_mask_id = 0;
	if (!nfp_check_mask_add(app, nfp_flow->mask_data,
	if (!nfp_flow->pre_tun_rule.dev &&
	    !nfp_check_mask_add(app, nfp_flow->mask_data,
				nfp_flow->meta.mask_len,
				&nfp_flow->meta.flags, &new_mask_id)) {
		NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot allocate a new mask id");
@@ -359,7 +365,8 @@ int nfp_compile_flow_metadata(struct nfp_app *app,
			goto err_remove_mask;
		}

		if (!nfp_check_mask_remove(app, nfp_flow->mask_data,
		if (!nfp_flow->pre_tun_rule.dev &&
		    !nfp_check_mask_remove(app, nfp_flow->mask_data,
					   nfp_flow->meta.mask_len,
					   NULL, &new_mask_id)) {
			NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot release mask id");
@@ -374,7 +381,9 @@ int nfp_compile_flow_metadata(struct nfp_app *app,
	return 0;

err_remove_mask:
	nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len,
	if (!nfp_flow->pre_tun_rule.dev)
		nfp_check_mask_remove(app, nfp_flow->mask_data,
				      nfp_flow->meta.mask_len,
				      NULL, &new_mask_id);
err_remove_rhash:
	WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table,
@@ -406,6 +415,7 @@ int nfp_modify_flow_metadata(struct nfp_app *app,

	__nfp_modify_flow_metadata(priv, nfp_flow);

	if (!nfp_flow->pre_tun_rule.dev)
		nfp_check_mask_remove(app, nfp_flow->mask_data,
				      nfp_flow->meta.mask_len, &nfp_flow->meta.flags,
				      &new_mask_id);