linux/net/dsa/tag_dsa.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Regular and Ethertype DSA tagging
 * Copyright (c) 2008-2009 Marvell Semiconductor
 *
 * Regular DSA
 * -----------

 * For untagged (in 802.1Q terms) packets, the switch will splice in
 * the tag between the SA and the ethertype of the original
 * packet. Tagged frames will instead have their outermost .1Q tag
 * converted to a DSA tag. It expects the same layout when receiving
 * packets from the CPU.
 *
 * Example:
 *
 *     .----.----.----.---------
 * Pu: | DA | SA | ET | Payload ...
 *     '----'----'----'---------
 *       6    6    2       N
 *     .----.----.--------.-----.----.---------
 * Pt: | DA | SA | 0x8100 | TCI | ET | Payload ...
 *     '----'----'--------'-----'----'---------
 *       6    6       2      2    2       N
 *     .----.----.-----.----.---------
 * Pd: | DA | SA | DSA | ET | Payload ...
 *     '----'----'-----'----'---------
 *       6    6     4    2       N
 *
 * No matter if a packet is received untagged (Pu) or tagged (Pt),
 * they will both have the same layout (Pd) when they are sent to the
 * CPU. This is done by ignoring 802.3, replacing the ethertype field
 * with more metadata, among which is a bit to signal if the original
 * packet was tagged or not.
 *
 * Ethertype DSA
 * -------------
 * Uses the exact same tag format as regular DSA, but also includes a
 * proper ethertype field (which the mv88e6xxx driver sets to
 * ETH_P_EDSA/0xdada) followed by two zero bytes:
 *
 * .----.----.--------.--------.-----.----.---------
 * | DA | SA | 0xdada | 0x0000 | DSA | ET | Payload ...
 * '----'----'--------'--------'-----'----'---------
 *   6    6       2        2      4    2       N
 */

#include <linux/dsa/mv88e6xxx.h>
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/slab.h>

#include "tag.h"

#define DSA_NAME
#define EDSA_NAME

#define DSA_HLEN

/**
 * enum dsa_cmd - DSA Command
 * @DSA_CMD_TO_CPU: Set on packets that were trapped or mirrored to
 *     the CPU port. This is needed to implement control protocols,
 *     e.g. STP and LLDP, that must not allow those control packets to
 *     be switched according to the normal rules.
 * @DSA_CMD_FROM_CPU: Used by the CPU to send a packet to a specific
 *     port, ignoring all the barriers that the switch normally
 *     enforces (VLANs, STP port states etc.). No source address
 *     learning takes place. "sudo send packet"
 * @DSA_CMD_TO_SNIFFER: Set on the copies of packets that matched some
 *     user configured ingress or egress monitor criteria. These are
 *     forwarded by the switch tree to the user configured ingress or
 *     egress monitor port, which can be set to the CPU port or a
 *     regular port. If the destination is a regular port, the tag
 *     will be removed before egressing the port. If the destination
 *     is the CPU port, the tag will not be removed.
 * @DSA_CMD_FORWARD: This tag is used on all bulk traffic passing
 *     through the switch tree, including the flows that are directed
 *     towards the CPU. Its device/port tuple encodes the original
 *     source port on which the packet ingressed. It can also be used
 *     on transmit by the CPU to defer the forwarding decision to the
 *     hardware, based on the current config of PVT/VTU/ATU
 *     etc. Source address learning takes places if enabled on the
 *     receiving DSA/CPU port.
 */
enum dsa_cmd {};

/**
 * enum dsa_code - TO_CPU Code
 *
 * @DSA_CODE_MGMT_TRAP: DA was classified as a management
 *     address. Typical examples include STP BPDUs and LLDP.
 * @DSA_CODE_FRAME2REG: Response to a "remote management" request.
 * @DSA_CODE_IGMP_MLD_TRAP: IGMP/MLD signaling.
 * @DSA_CODE_POLICY_TRAP: Frame matched some policy configuration on
 *     the device. Typical examples are matching on DA/SA/VID and DHCP
 *     snooping.
 * @DSA_CODE_ARP_MIRROR: The name says it all really.
 * @DSA_CODE_POLICY_MIRROR: Same as @DSA_CODE_POLICY_TRAP, but the
 *     particular policy was set to trigger a mirror instead of a
 *     trap.
 * @DSA_CODE_RESERVED_6: Unused on all devices up to at least 6393X.
 * @DSA_CODE_RESERVED_7: Unused on all devices up to at least 6393X.
 *
 * A 3-bit code is used to relay why a particular frame was sent to
 * the CPU. We only use this to determine if the packet was mirrored
 * or trapped, i.e. whether the packet has been forwarded by hardware
 * or not.
 *
 * This is the superset of all possible codes. Any particular device
 * may only implement a subset.
 */
enum dsa_code {};

static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
				   u8 extra)
{}

static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev,
				  u8 extra)
{}

#if IS_ENABLED(CONFIG_NET_DSA_TAG_DSA)

static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev)
{}

static const struct dsa_device_ops dsa_netdev_ops =;

DSA_TAG_DRIVER(dsa_netdev_ops);
MODULE_ALIAS_DSA_TAG_DRIVER();
#endif	/* CONFIG_NET_DSA_TAG_DSA */

#if IS_ENABLED(CONFIG_NET_DSA_TAG_EDSA)

#define EDSA_HLEN

static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev)
{}

static const struct dsa_device_ops edsa_netdev_ops =;

DSA_TAG_DRIVER(edsa_netdev_ops);
MODULE_ALIAS_DSA_TAG_DRIVER();
#endif	/* CONFIG_NET_DSA_TAG_EDSA */

static struct dsa_tag_driver *dsa_tag_drivers[] =;

module_dsa_tag_drivers(dsa_tag_drivers);

MODULE_DESCRIPTION();
MODULE_LICENSE();