net/dsa/tag_dsa.c

Source file repositories/reference/linux-study-clean/net/dsa/tag_dsa.c

File Facts

System
Linux kernel
Corpus path
net/dsa/tag_dsa.c
Extension
.c
Size
12032 bytes
Lines
411
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (extra) {
			skb_push(skb, extra);
			dsa_alloc_etype_header(skb, extra);
		}

		/* Construct tagged DSA tag from 802.1Q tag. */
		dsa_header = dsa_etype_header_pos_tx(skb) + extra;
		dsa_header[0] = (cmd << 6) | 0x20 | tag_dev;
		dsa_header[1] = tag_port << 3;

		/* Move CFI field from byte 2 to byte 1. */
		if (dsa_header[2] & 0x10) {
			dsa_header[1] |= 0x01;
			dsa_header[2] &= ~0x10;
		}
	} else {
		u16 vid;

		vid = br_dev ? MV88E6XXX_VID_BRIDGED : MV88E6XXX_VID_STANDALONE;

		skb_push(skb, DSA_HLEN + extra);
		dsa_alloc_etype_header(skb, DSA_HLEN + extra);

		/* Construct DSA header from untagged frame. */
		dsa_header = dsa_etype_header_pos_tx(skb) + extra;

		dsa_header[0] = (cmd << 6) | tag_dev;
		dsa_header[1] = tag_port << 3;
		dsa_header[2] = vid >> 8;
		dsa_header[3] = vid & 0xff;
	}

	return skb;
}

static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev,
				  u8 extra)
{
	bool trap = false, trunk = false;
	int source_device, source_port;
	enum dsa_code code;
	enum dsa_cmd cmd;
	u8 *dsa_header;

	/* The ethertype field is part of the DSA header. */
	dsa_header = dsa_etype_header_pos_rx(skb);

	cmd = dsa_header[0] >> 6;
	switch (cmd) {
	case DSA_CMD_FORWARD:
		trunk = !!(dsa_header[1] & 4);
		break;

	case DSA_CMD_TO_CPU:
		code = (dsa_header[1] & 0x6) | ((dsa_header[2] >> 4) & 1);

		switch (code) {
		case DSA_CODE_FRAME2REG:
			/* Remote management is not implemented yet,
			 * drop.
			 */
			return NULL;
		case DSA_CODE_ARP_MIRROR:
		case DSA_CODE_POLICY_MIRROR:
			/* Mark mirrored packets to notify any upper
			 * device (like a bridge) that forwarding has
			 * already been done by hardware.
			 */
			break;
		case DSA_CODE_MGMT_TRAP:
		case DSA_CODE_IGMP_MLD_TRAP:
		case DSA_CODE_POLICY_TRAP:
			/* Traps have, by definition, not been
			 * forwarded by hardware, so don't mark them.
			 */
			trap = true;
			break;
		default:
			/* Reserved code, this could be anything. Drop
			 * seems like the safest option.
			 */
			return NULL;
		}

		break;

	default:
		return NULL;
	}

Annotation

Implementation Notes