drivers/net/ethernet/sfc/tc.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/tc.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sfc/tc.c
Extension
.c
Size
95191 bytes
Lines
3095
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

struct efx_tc_mangler_state {
	u8 dst_mac_32:1; /* eth->h_dest[0:3] */
	u8 dst_mac_16:1; /* eth->h_dest[4:5] */
	u8 src_mac_16:1; /* eth->h_source[0:1] */
	u8 src_mac_32:1; /* eth->h_source[2:5] */
	unsigned char dst_mac[ETH_ALEN];
	unsigned char src_mac[ETH_ALEN];
};

/** efx_tc_complete_mac_mangle() - pull complete field pedits out of @mung
 * @efx:	NIC we're installing a flow rule on
 * @act:	action set (cursor) to update
 * @mung:	accumulated partial mangles
 * @extack:	netlink extended ack for reporting errors
 *
 * Check @mung to find any combinations of partial mangles that can be
 * combined into a complete packet field edit, add that edit to @act,
 * and consume the partial mangles from @mung.
 */

static int efx_tc_complete_mac_mangle(struct efx_nic *efx,
				      struct efx_tc_action_set *act,
				      struct efx_tc_mangler_state *mung,
				      struct netlink_ext_ack *extack)
{
	struct efx_tc_mac_pedit_action *ped;

	if (mung->dst_mac_32 && mung->dst_mac_16) {
		ped = efx_tc_flower_get_mac(efx, mung->dst_mac, extack);
		if (IS_ERR(ped))
			return PTR_ERR(ped);

		/* Check that we have not already populated dst_mac */
		if (act->dst_mac)
			efx_tc_flower_put_mac(efx, act->dst_mac);

		act->dst_mac = ped;

		/* consume the incomplete state */
		mung->dst_mac_32 = 0;
		mung->dst_mac_16 = 0;
	}
	if (mung->src_mac_16 && mung->src_mac_32) {
		ped = efx_tc_flower_get_mac(efx, mung->src_mac, extack);
		if (IS_ERR(ped))
			return PTR_ERR(ped);

		/* Check that we have not already populated src_mac */
		if (act->src_mac)
			efx_tc_flower_put_mac(efx, act->src_mac);

		act->src_mac = ped;

		/* consume the incomplete state */
		mung->src_mac_32 = 0;
		mung->src_mac_16 = 0;
	}
	return 0;
}

static int efx_tc_pedit_add(struct efx_nic *efx, struct efx_tc_action_set *act,
			    const struct flow_action_entry *fa,
			    struct netlink_ext_ack *extack)
{
	switch (fa->mangle.htype) {
	case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
		switch (fa->mangle.offset) {
		case offsetof(struct iphdr, ttl):
			/* check that pedit applies to ttl only */
			if (fa->mangle.mask != ~EFX_TC_HDR_TYPE_TTL_MASK)
				break;

			/* Adding 0xff is equivalent to decrementing the ttl.
			 * Other added values are not supported.
			 */
			if ((fa->mangle.val & EFX_TC_HDR_TYPE_TTL_MASK) != U8_MAX)
				break;

			/* check that we do not decrement ttl twice */
			if (!efx_tc_flower_action_order_ok(act,
							   EFX_TC_AO_DEC_TTL)) {
				NL_SET_ERR_MSG_MOD(extack, "multiple dec ttl are not supported");
				return -EOPNOTSUPP;
			}
			act->do_ttl_dec = 1;
			return 0;
		default:
			break;
		}
		break;

Annotation

Implementation Notes