xref: /openbmc/linux/net/dsa/tag.h (revision f0a9d563)
1bd954b82SVladimir Oltean /* SPDX-License-Identifier: GPL-2.0-or-later */
2bd954b82SVladimir Oltean 
3bd954b82SVladimir Oltean #ifndef __DSA_TAG_H
4bd954b82SVladimir Oltean #define __DSA_TAG_H
5bd954b82SVladimir Oltean 
6bd954b82SVladimir Oltean #include <linux/if_vlan.h>
7bd954b82SVladimir Oltean #include <linux/list.h>
8bd954b82SVladimir Oltean #include <linux/types.h>
9bd954b82SVladimir Oltean #include <net/dsa.h>
10bd954b82SVladimir Oltean 
11bd954b82SVladimir Oltean #include "port.h"
12bd954b82SVladimir Oltean #include "slave.h"
13bd954b82SVladimir Oltean 
14bd954b82SVladimir Oltean struct dsa_tag_driver {
15bd954b82SVladimir Oltean 	const struct dsa_device_ops *ops;
16bd954b82SVladimir Oltean 	struct list_head list;
17bd954b82SVladimir Oltean 	struct module *owner;
18bd954b82SVladimir Oltean };
19bd954b82SVladimir Oltean 
20bd954b82SVladimir Oltean extern struct packet_type dsa_pack_type;
21bd954b82SVladimir Oltean 
22bd954b82SVladimir Oltean const struct dsa_device_ops *dsa_tag_driver_get_by_id(int tag_protocol);
23bd954b82SVladimir Oltean const struct dsa_device_ops *dsa_tag_driver_get_by_name(const char *name);
24bd954b82SVladimir Oltean void dsa_tag_driver_put(const struct dsa_device_ops *ops);
25bd954b82SVladimir Oltean const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops);
26bd954b82SVladimir Oltean 
dsa_tag_protocol_overhead(const struct dsa_device_ops * ops)27bd954b82SVladimir Oltean static inline int dsa_tag_protocol_overhead(const struct dsa_device_ops *ops)
28bd954b82SVladimir Oltean {
29bd954b82SVladimir Oltean 	return ops->needed_headroom + ops->needed_tailroom;
30bd954b82SVladimir Oltean }
31bd954b82SVladimir Oltean 
dsa_master_find_slave(struct net_device * dev,int device,int port)32bd954b82SVladimir Oltean static inline struct net_device *dsa_master_find_slave(struct net_device *dev,
33bd954b82SVladimir Oltean 						       int device, int port)
34bd954b82SVladimir Oltean {
35bd954b82SVladimir Oltean 	struct dsa_port *cpu_dp = dev->dsa_ptr;
36bd954b82SVladimir Oltean 	struct dsa_switch_tree *dst = cpu_dp->dst;
37bd954b82SVladimir Oltean 	struct dsa_port *dp;
38bd954b82SVladimir Oltean 
39bd954b82SVladimir Oltean 	list_for_each_entry(dp, &dst->ports, list)
40bd954b82SVladimir Oltean 		if (dp->ds->index == device && dp->index == port &&
41bd954b82SVladimir Oltean 		    dp->type == DSA_PORT_TYPE_USER)
42bd954b82SVladimir Oltean 			return dp->slave;
43bd954b82SVladimir Oltean 
44bd954b82SVladimir Oltean 	return NULL;
45bd954b82SVladimir Oltean }
46bd954b82SVladimir Oltean 
47bd954b82SVladimir Oltean /* If under a bridge with vlan_filtering=0, make sure to send pvid-tagged
48bd954b82SVladimir Oltean  * frames as untagged, since the bridge will not untag them.
49bd954b82SVladimir Oltean  */
dsa_untag_bridge_pvid(struct sk_buff * skb)50bd954b82SVladimir Oltean static inline struct sk_buff *dsa_untag_bridge_pvid(struct sk_buff *skb)
51bd954b82SVladimir Oltean {
52bd954b82SVladimir Oltean 	struct dsa_port *dp = dsa_slave_to_port(skb->dev);
53bd954b82SVladimir Oltean 	struct net_device *br = dsa_port_bridge_dev_get(dp);
54bd954b82SVladimir Oltean 	struct net_device *dev = skb->dev;
55bd954b82SVladimir Oltean 	struct net_device *upper_dev;
56bd954b82SVladimir Oltean 	u16 vid, pvid, proto;
57bd954b82SVladimir Oltean 	int err;
58bd954b82SVladimir Oltean 
59bd954b82SVladimir Oltean 	if (!br || br_vlan_enabled(br))
60bd954b82SVladimir Oltean 		return skb;
61bd954b82SVladimir Oltean 
62bd954b82SVladimir Oltean 	err = br_vlan_get_proto(br, &proto);
63bd954b82SVladimir Oltean 	if (err)
64bd954b82SVladimir Oltean 		return skb;
65bd954b82SVladimir Oltean 
66bd954b82SVladimir Oltean 	/* Move VLAN tag from data to hwaccel */
67bd954b82SVladimir Oltean 	if (!skb_vlan_tag_present(skb) && skb->protocol == htons(proto)) {
68bd954b82SVladimir Oltean 		skb = skb_vlan_untag(skb);
69bd954b82SVladimir Oltean 		if (!skb)
70bd954b82SVladimir Oltean 			return NULL;
71bd954b82SVladimir Oltean 	}
72bd954b82SVladimir Oltean 
73bd954b82SVladimir Oltean 	if (!skb_vlan_tag_present(skb))
74bd954b82SVladimir Oltean 		return skb;
75bd954b82SVladimir Oltean 
76bd954b82SVladimir Oltean 	vid = skb_vlan_tag_get_id(skb);
77bd954b82SVladimir Oltean 
78bd954b82SVladimir Oltean 	/* We already run under an RCU read-side critical section since
79bd954b82SVladimir Oltean 	 * we are called from netif_receive_skb_list_internal().
80bd954b82SVladimir Oltean 	 */
81bd954b82SVladimir Oltean 	err = br_vlan_get_pvid_rcu(dev, &pvid);
82bd954b82SVladimir Oltean 	if (err)
83bd954b82SVladimir Oltean 		return skb;
84bd954b82SVladimir Oltean 
85bd954b82SVladimir Oltean 	if (vid != pvid)
86bd954b82SVladimir Oltean 		return skb;
87bd954b82SVladimir Oltean 
88bd954b82SVladimir Oltean 	/* The sad part about attempting to untag from DSA is that we
89bd954b82SVladimir Oltean 	 * don't know, unless we check, if the skb will end up in
90bd954b82SVladimir Oltean 	 * the bridge's data path - br_allowed_ingress() - or not.
91bd954b82SVladimir Oltean 	 * For example, there might be an 8021q upper for the
92bd954b82SVladimir Oltean 	 * default_pvid of the bridge, which will steal VLAN-tagged traffic
93bd954b82SVladimir Oltean 	 * from the bridge's data path. This is a configuration that DSA
94bd954b82SVladimir Oltean 	 * supports because vlan_filtering is 0. In that case, we should
95bd954b82SVladimir Oltean 	 * definitely keep the tag, to make sure it keeps working.
96bd954b82SVladimir Oltean 	 */
97bd954b82SVladimir Oltean 	upper_dev = __vlan_find_dev_deep_rcu(br, htons(proto), vid);
98bd954b82SVladimir Oltean 	if (upper_dev)
99bd954b82SVladimir Oltean 		return skb;
100bd954b82SVladimir Oltean 
101bd954b82SVladimir Oltean 	__vlan_hwaccel_clear_tag(skb);
102bd954b82SVladimir Oltean 
103bd954b82SVladimir Oltean 	return skb;
104bd954b82SVladimir Oltean }
105bd954b82SVladimir Oltean 
106bd954b82SVladimir Oltean /* For switches without hardware support for DSA tagging to be able
107bd954b82SVladimir Oltean  * to support termination through the bridge.
108bd954b82SVladimir Oltean  */
109bd954b82SVladimir Oltean static inline struct net_device *
dsa_find_designated_bridge_port_by_vid(struct net_device * master,u16 vid)110bd954b82SVladimir Oltean dsa_find_designated_bridge_port_by_vid(struct net_device *master, u16 vid)
111bd954b82SVladimir Oltean {
112bd954b82SVladimir Oltean 	struct dsa_port *cpu_dp = master->dsa_ptr;
113bd954b82SVladimir Oltean 	struct dsa_switch_tree *dst = cpu_dp->dst;
114bd954b82SVladimir Oltean 	struct bridge_vlan_info vinfo;
115bd954b82SVladimir Oltean 	struct net_device *slave;
116bd954b82SVladimir Oltean 	struct dsa_port *dp;
117bd954b82SVladimir Oltean 	int err;
118bd954b82SVladimir Oltean 
119bd954b82SVladimir Oltean 	list_for_each_entry(dp, &dst->ports, list) {
120bd954b82SVladimir Oltean 		if (dp->type != DSA_PORT_TYPE_USER)
121bd954b82SVladimir Oltean 			continue;
122bd954b82SVladimir Oltean 
123bd954b82SVladimir Oltean 		if (!dp->bridge)
124bd954b82SVladimir Oltean 			continue;
125bd954b82SVladimir Oltean 
126bd954b82SVladimir Oltean 		if (dp->stp_state != BR_STATE_LEARNING &&
127bd954b82SVladimir Oltean 		    dp->stp_state != BR_STATE_FORWARDING)
128bd954b82SVladimir Oltean 			continue;
129bd954b82SVladimir Oltean 
130bd954b82SVladimir Oltean 		/* Since the bridge might learn this packet, keep the CPU port
131bd954b82SVladimir Oltean 		 * affinity with the port that will be used for the reply on
132bd954b82SVladimir Oltean 		 * xmit.
133bd954b82SVladimir Oltean 		 */
134bd954b82SVladimir Oltean 		if (dp->cpu_dp != cpu_dp)
135bd954b82SVladimir Oltean 			continue;
136bd954b82SVladimir Oltean 
137bd954b82SVladimir Oltean 		slave = dp->slave;
138bd954b82SVladimir Oltean 
139bd954b82SVladimir Oltean 		err = br_vlan_get_info_rcu(slave, vid, &vinfo);
140bd954b82SVladimir Oltean 		if (err)
141bd954b82SVladimir Oltean 			continue;
142bd954b82SVladimir Oltean 
143bd954b82SVladimir Oltean 		return slave;
144bd954b82SVladimir Oltean 	}
145bd954b82SVladimir Oltean 
146bd954b82SVladimir Oltean 	return NULL;
147bd954b82SVladimir Oltean }
148bd954b82SVladimir Oltean 
149bd954b82SVladimir Oltean /* If the ingress port offloads the bridge, we mark the frame as autonomously
150bd954b82SVladimir Oltean  * forwarded by hardware, so the software bridge doesn't forward in twice, back
151bd954b82SVladimir Oltean  * to us, because we already did. However, if we're in fallback mode and we do
152bd954b82SVladimir Oltean  * software bridging, we are not offloading it, therefore the dp->bridge
153bd954b82SVladimir Oltean  * pointer is not populated, and flooding needs to be done by software (we are
154bd954b82SVladimir Oltean  * effectively operating in standalone ports mode).
155bd954b82SVladimir Oltean  */
dsa_default_offload_fwd_mark(struct sk_buff * skb)156bd954b82SVladimir Oltean static inline void dsa_default_offload_fwd_mark(struct sk_buff *skb)
157bd954b82SVladimir Oltean {
158bd954b82SVladimir Oltean 	struct dsa_port *dp = dsa_slave_to_port(skb->dev);
159bd954b82SVladimir Oltean 
160bd954b82SVladimir Oltean 	skb->offload_fwd_mark = !!(dp->bridge);
161bd954b82SVladimir Oltean }
162bd954b82SVladimir Oltean 
163bd954b82SVladimir Oltean /* Helper for removing DSA header tags from packets in the RX path.
164bd954b82SVladimir Oltean  * Must not be called before skb_pull(len).
165bd954b82SVladimir Oltean  *                                                                 skb->data
166bd954b82SVladimir Oltean  *                                                                         |
167bd954b82SVladimir Oltean  *                                                                         v
168bd954b82SVladimir Oltean  * |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
169bd954b82SVladimir Oltean  * +-----------------------+-----------------------+---------------+-------+
170bd954b82SVladimir Oltean  * |    Destination MAC    |      Source MAC       |  DSA header   | EType |
171bd954b82SVladimir Oltean  * +-----------------------+-----------------------+---------------+-------+
172bd954b82SVladimir Oltean  *                                                 |               |
173bd954b82SVladimir Oltean  * <----- len ----->                               <----- len ----->
174bd954b82SVladimir Oltean  *                 |
175bd954b82SVladimir Oltean  *       >>>>>>>   v
176bd954b82SVladimir Oltean  *       >>>>>>>   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
177bd954b82SVladimir Oltean  *       >>>>>>>   +-----------------------+-----------------------+-------+
178bd954b82SVladimir Oltean  *       >>>>>>>   |    Destination MAC    |      Source MAC       | EType |
179bd954b82SVladimir Oltean  *                 +-----------------------+-----------------------+-------+
180bd954b82SVladimir Oltean  *                                                                         ^
181bd954b82SVladimir Oltean  *                                                                         |
182bd954b82SVladimir Oltean  *                                                                 skb->data
183bd954b82SVladimir Oltean  */
dsa_strip_etype_header(struct sk_buff * skb,int len)184bd954b82SVladimir Oltean static inline void dsa_strip_etype_header(struct sk_buff *skb, int len)
185bd954b82SVladimir Oltean {
186bd954b82SVladimir Oltean 	memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - len, 2 * ETH_ALEN);
187bd954b82SVladimir Oltean }
188bd954b82SVladimir Oltean 
189bd954b82SVladimir Oltean /* Helper for creating space for DSA header tags in TX path packets.
190bd954b82SVladimir Oltean  * Must not be called before skb_push(len).
191bd954b82SVladimir Oltean  *
192bd954b82SVladimir Oltean  * Before:
193bd954b82SVladimir Oltean  *
194bd954b82SVladimir Oltean  *       <<<<<<<   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
195bd954b82SVladimir Oltean  * ^     <<<<<<<   +-----------------------+-----------------------+-------+
196bd954b82SVladimir Oltean  * |     <<<<<<<   |    Destination MAC    |      Source MAC       | EType |
197bd954b82SVladimir Oltean  * |               +-----------------------+-----------------------+-------+
198bd954b82SVladimir Oltean  * <----- len ----->
199bd954b82SVladimir Oltean  * |
200bd954b82SVladimir Oltean  * |
201bd954b82SVladimir Oltean  * skb->data
202bd954b82SVladimir Oltean  *
203bd954b82SVladimir Oltean  * After:
204bd954b82SVladimir Oltean  *
205bd954b82SVladimir Oltean  * |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
206bd954b82SVladimir Oltean  * +-----------------------+-----------------------+---------------+-------+
207bd954b82SVladimir Oltean  * |    Destination MAC    |      Source MAC       |  DSA header   | EType |
208bd954b82SVladimir Oltean  * +-----------------------+-----------------------+---------------+-------+
209bd954b82SVladimir Oltean  * ^                                               |               |
210bd954b82SVladimir Oltean  * |                                               <----- len ----->
211bd954b82SVladimir Oltean  * skb->data
212bd954b82SVladimir Oltean  */
dsa_alloc_etype_header(struct sk_buff * skb,int len)213bd954b82SVladimir Oltean static inline void dsa_alloc_etype_header(struct sk_buff *skb, int len)
214bd954b82SVladimir Oltean {
215bd954b82SVladimir Oltean 	memmove(skb->data, skb->data + len, 2 * ETH_ALEN);
216bd954b82SVladimir Oltean }
217bd954b82SVladimir Oltean 
218bd954b82SVladimir Oltean /* On RX, eth_type_trans() on the DSA master pulls ETH_HLEN bytes starting from
219bd954b82SVladimir Oltean  * skb_mac_header(skb), which leaves skb->data pointing at the first byte after
220bd954b82SVladimir Oltean  * what the DSA master perceives as the EtherType (the beginning of the L3
221bd954b82SVladimir Oltean  * protocol). Since DSA EtherType header taggers treat the EtherType as part of
222bd954b82SVladimir Oltean  * the DSA tag itself, and the EtherType is 2 bytes in length, the DSA header
223bd954b82SVladimir Oltean  * is located 2 bytes behind skb->data. Note that EtherType in this context
224bd954b82SVladimir Oltean  * means the first 2 bytes of the DSA header, not the encapsulated EtherType
225bd954b82SVladimir Oltean  * that will become visible after the DSA header is stripped.
226bd954b82SVladimir Oltean  */
dsa_etype_header_pos_rx(struct sk_buff * skb)227bd954b82SVladimir Oltean static inline void *dsa_etype_header_pos_rx(struct sk_buff *skb)
228bd954b82SVladimir Oltean {
229bd954b82SVladimir Oltean 	return skb->data - 2;
230bd954b82SVladimir Oltean }
231bd954b82SVladimir Oltean 
232*f0a9d563SVladimir Oltean /* On TX, skb->data points to the MAC header, which means that EtherType
233bd954b82SVladimir Oltean  * header taggers start exactly where the EtherType is (the EtherType is
234bd954b82SVladimir Oltean  * treated as part of the DSA header).
235bd954b82SVladimir Oltean  */
dsa_etype_header_pos_tx(struct sk_buff * skb)236bd954b82SVladimir Oltean static inline void *dsa_etype_header_pos_tx(struct sk_buff *skb)
237bd954b82SVladimir Oltean {
238bd954b82SVladimir Oltean 	return skb->data + 2 * ETH_ALEN;
239bd954b82SVladimir Oltean }
240bd954b82SVladimir Oltean 
241bd954b82SVladimir Oltean /* Create 2 modaliases per tagging protocol, one to auto-load the module
242bd954b82SVladimir Oltean  * given the ID reported by get_tag_protocol(), and the other by name.
243bd954b82SVladimir Oltean  */
244bd954b82SVladimir Oltean #define DSA_TAG_DRIVER_ALIAS "dsa_tag:"
245bd954b82SVladimir Oltean #define MODULE_ALIAS_DSA_TAG_DRIVER(__proto, __name) \
246bd954b82SVladimir Oltean 	MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __name); \
247bd954b82SVladimir Oltean 	MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS "id-" \
248bd954b82SVladimir Oltean 		     __stringify(__proto##_VALUE))
249bd954b82SVladimir Oltean 
250bd954b82SVladimir Oltean void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[],
251bd954b82SVladimir Oltean 			      unsigned int count,
252bd954b82SVladimir Oltean 			      struct module *owner);
253bd954b82SVladimir Oltean void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[],
254bd954b82SVladimir Oltean 				unsigned int count);
255bd954b82SVladimir Oltean 
256bd954b82SVladimir Oltean #define dsa_tag_driver_module_drivers(__dsa_tag_drivers_array, __count)	\
257bd954b82SVladimir Oltean static int __init dsa_tag_driver_module_init(void)			\
258bd954b82SVladimir Oltean {									\
259bd954b82SVladimir Oltean 	dsa_tag_drivers_register(__dsa_tag_drivers_array, __count,	\
260bd954b82SVladimir Oltean 				 THIS_MODULE);				\
261bd954b82SVladimir Oltean 	return 0;							\
262bd954b82SVladimir Oltean }									\
263bd954b82SVladimir Oltean module_init(dsa_tag_driver_module_init);				\
264bd954b82SVladimir Oltean 									\
265bd954b82SVladimir Oltean static void __exit dsa_tag_driver_module_exit(void)			\
266bd954b82SVladimir Oltean {									\
267bd954b82SVladimir Oltean 	dsa_tag_drivers_unregister(__dsa_tag_drivers_array, __count);	\
268bd954b82SVladimir Oltean }									\
269bd954b82SVladimir Oltean module_exit(dsa_tag_driver_module_exit)
270bd954b82SVladimir Oltean 
271bd954b82SVladimir Oltean /**
272bd954b82SVladimir Oltean  * module_dsa_tag_drivers() - Helper macro for registering DSA tag
273bd954b82SVladimir Oltean  * drivers
274bd954b82SVladimir Oltean  * @__ops_array: Array of tag driver structures
275bd954b82SVladimir Oltean  *
276bd954b82SVladimir Oltean  * Helper macro for DSA tag drivers which do not do anything special
277bd954b82SVladimir Oltean  * in module init/exit. Each module may only use this macro once, and
278bd954b82SVladimir Oltean  * calling it replaces module_init() and module_exit().
279bd954b82SVladimir Oltean  */
280bd954b82SVladimir Oltean #define module_dsa_tag_drivers(__ops_array)				\
281bd954b82SVladimir Oltean dsa_tag_driver_module_drivers(__ops_array, ARRAY_SIZE(__ops_array))
282bd954b82SVladimir Oltean 
283bd954b82SVladimir Oltean #define DSA_TAG_DRIVER_NAME(__ops) dsa_tag_driver ## _ ## __ops
284bd954b82SVladimir Oltean 
285bd954b82SVladimir Oltean /* Create a static structure we can build a linked list of dsa_tag
286bd954b82SVladimir Oltean  * drivers
287bd954b82SVladimir Oltean  */
288bd954b82SVladimir Oltean #define DSA_TAG_DRIVER(__ops)						\
289bd954b82SVladimir Oltean static struct dsa_tag_driver DSA_TAG_DRIVER_NAME(__ops) = {		\
290bd954b82SVladimir Oltean 	.ops = &__ops,							\
291bd954b82SVladimir Oltean }
292bd954b82SVladimir Oltean 
293bd954b82SVladimir Oltean /**
294bd954b82SVladimir Oltean  * module_dsa_tag_driver() - Helper macro for registering a single DSA tag
295bd954b82SVladimir Oltean  * driver
296bd954b82SVladimir Oltean  * @__ops: Single tag driver structures
297bd954b82SVladimir Oltean  *
298bd954b82SVladimir Oltean  * Helper macro for DSA tag drivers which do not do anything special
299bd954b82SVladimir Oltean  * in module init/exit. Each module may only use this macro once, and
300bd954b82SVladimir Oltean  * calling it replaces module_init() and module_exit().
301bd954b82SVladimir Oltean  */
302bd954b82SVladimir Oltean #define module_dsa_tag_driver(__ops)					\
303bd954b82SVladimir Oltean DSA_TAG_DRIVER(__ops);							\
304bd954b82SVladimir Oltean 									\
305bd954b82SVladimir Oltean static struct dsa_tag_driver *dsa_tag_driver_array[] =	{		\
306bd954b82SVladimir Oltean 	&DSA_TAG_DRIVER_NAME(__ops)					\
307bd954b82SVladimir Oltean };									\
308bd954b82SVladimir Oltean module_dsa_tag_drivers(dsa_tag_driver_array)
309bd954b82SVladimir Oltean 
310bd954b82SVladimir Oltean #endif
311