drivers/net/ethernet/netronome/nfp/flower/conntrack.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/flower/conntrack.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/flower/conntrack.c
Extension
.c
Size
66144 bytes
Lines
2301
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (act->id == FLOW_ACTION_CT) {
			/* The pre_ct rule only have the ct or ct nat action, cannot
			 * contains other ct action e.g ct commit and so on.
			 */
			if ((!act->ct.action || act->ct.action == TCA_CT_ACT_NAT))
				return true;
			else
				return false;
		}
	}

	return false;
}

bool is_post_ct_flow(struct flow_cls_offload *flow)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(flow);
	struct flow_dissector *dissector = rule->match.dissector;
	struct flow_action_entry *act;
	bool exist_ct_clear = false;
	struct flow_match_ct ct;
	int i;

	if (dissector->used_keys & BIT_ULL(FLOW_DISSECTOR_KEY_CT)) {
		flow_rule_match_ct(rule, &ct);
		if (ct.key->ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED)
			return true;
	} else {
		/* post ct entry cannot contains any ct action except ct_clear. */
		flow_action_for_each(i, act, &flow->rule->action) {
			if (act->id == FLOW_ACTION_CT) {
				/* ignore ct clear action. */
				if (act->ct.action == TCA_CT_ACT_CLEAR) {
					exist_ct_clear = true;
					continue;
				}

				return false;
			}
		}
		/* when do nat with ct, the post ct entry ignore the ct status,
		 * will match the nat field(sip/dip) instead. In this situation,
		 * the flow chain index is not zero and contains ct clear action.
		 */
		if (flow->common.chain_index && exist_ct_clear)
			return true;
	}

	return false;
}

/**
 * get_mangled_key() - Mangle the key if mangle act exists
 * @rule:	rule that carries the actions
 * @buf:	pointer to key to be mangled
 * @offset:	used to adjust mangled offset in L2/L3/L4 header
 * @key_sz:	key size
 * @htype:	mangling type
 *
 * Returns buf where the mangled key stores.
 */
static void *get_mangled_key(struct flow_rule *rule, void *buf,
			     u32 offset, size_t key_sz,
			     enum flow_action_mangle_base htype)
{
	struct flow_action_entry *act;
	u32 *val = (u32 *)buf;
	u32 off, msk, key;
	int i;

	flow_action_for_each(i, act, &rule->action) {
		if (act->id == FLOW_ACTION_MANGLE &&
		    act->mangle.htype == htype) {
			off = act->mangle.offset - offset;
			msk = act->mangle.mask;
			key = act->mangle.val;

			/* Mangling is supposed to be u32 aligned */
			if (off % 4 || off >= key_sz)
				continue;

			val[off >> 2] &= msk;
			val[off >> 2] |= key;
		}
	}

	return buf;
}

/* Only tos and ttl are involved in flow_match_ip structure, which

Annotation

Implementation Notes