1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
4 * This module is not a complete tagger implementation. It only provides
5 * primitives for taggers that rely on 802.1Q VLAN tags to use.
7 #include <linux/if_vlan.h>
8 #include <linux/dsa/8021q.h>
13 #include "tag_8021q.h"
15 /* Binary structure of the fake 12-bit VID field (when the TPID is
18 * | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
19 * +-----------+-----+-----------------+-----------+-----------------------+
20 * | RSV | VBID| SWITCH_ID | VBID | PORT |
21 * +-----------+-----+-----------------+-----------+-----------------------+
24 * Reserved. Must be set to 3 (0b11).
26 * SWITCH_ID - VID[8:6]:
27 * Index of switch within DSA tree. Must be between 0 and 7.
29 * VBID - { VID[9], VID[5:4] }:
30 * Virtual bridge ID. If between 1 and 7, packet targets the broadcast
31 * domain of a bridge. If transmitted as zero, packet targets a single
35 * Index of switch port. Must be between 0 and 15.
38 #define DSA_8021Q_RSV_VAL 3
39 #define DSA_8021Q_RSV_SHIFT 10
40 #define DSA_8021Q_RSV_MASK GENMASK(11, 10)
41 #define DSA_8021Q_RSV ((DSA_8021Q_RSV_VAL << DSA_8021Q_RSV_SHIFT) & \
44 #define DSA_8021Q_SWITCH_ID_SHIFT 6
45 #define DSA_8021Q_SWITCH_ID_MASK GENMASK(8, 6)
46 #define DSA_8021Q_SWITCH_ID(x) (((x) << DSA_8021Q_SWITCH_ID_SHIFT) & \
47 DSA_8021Q_SWITCH_ID_MASK)
49 #define DSA_8021Q_VBID_HI_SHIFT 9
50 #define DSA_8021Q_VBID_HI_MASK GENMASK(9, 9)
51 #define DSA_8021Q_VBID_LO_SHIFT 4
52 #define DSA_8021Q_VBID_LO_MASK GENMASK(5, 4)
53 #define DSA_8021Q_VBID_HI(x) (((x) & GENMASK(2, 2)) >> 2)
54 #define DSA_8021Q_VBID_LO(x) ((x) & GENMASK(1, 0))
55 #define DSA_8021Q_VBID(x) \
56 (((DSA_8021Q_VBID_LO(x) << DSA_8021Q_VBID_LO_SHIFT) & \
57 DSA_8021Q_VBID_LO_MASK) | \
58 ((DSA_8021Q_VBID_HI(x) << DSA_8021Q_VBID_HI_SHIFT) & \
59 DSA_8021Q_VBID_HI_MASK))
61 #define DSA_8021Q_PORT_SHIFT 0
62 #define DSA_8021Q_PORT_MASK GENMASK(3, 0)
63 #define DSA_8021Q_PORT(x) (((x) << DSA_8021Q_PORT_SHIFT) & \
66 struct dsa_tag_8021q_vlan
{
67 struct list_head list
;
73 struct dsa_8021q_context
{
74 struct dsa_switch
*ds
;
75 struct list_head vlans
;
76 /* EtherType of RX VID, used for filtering on conduit interface */
80 u16
dsa_tag_8021q_bridge_vid(unsigned int bridge_num
)
82 /* The VBID value of 0 is reserved for precise TX, but it is also
83 * reserved/invalid for the bridge_num, so all is well.
85 return DSA_8021Q_RSV
| DSA_8021Q_VBID(bridge_num
);
87 EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_vid
);
89 /* Returns the VID that will be installed as pvid for this switch port, sent as
90 * tagged egress towards the CPU port and decoded by the rcv function.
92 u16
dsa_tag_8021q_standalone_vid(const struct dsa_port
*dp
)
94 return DSA_8021Q_RSV
| DSA_8021Q_SWITCH_ID(dp
->ds
->index
) |
95 DSA_8021Q_PORT(dp
->index
);
97 EXPORT_SYMBOL_GPL(dsa_tag_8021q_standalone_vid
);
99 /* Returns the decoded switch ID from the RX VID. */
100 int dsa_8021q_rx_switch_id(u16 vid
)
102 return (vid
& DSA_8021Q_SWITCH_ID_MASK
) >> DSA_8021Q_SWITCH_ID_SHIFT
;
104 EXPORT_SYMBOL_GPL(dsa_8021q_rx_switch_id
);
106 /* Returns the decoded port ID from the RX VID. */
107 int dsa_8021q_rx_source_port(u16 vid
)
109 return (vid
& DSA_8021Q_PORT_MASK
) >> DSA_8021Q_PORT_SHIFT
;
111 EXPORT_SYMBOL_GPL(dsa_8021q_rx_source_port
);
113 /* Returns the decoded VBID from the RX VID. */
114 static int dsa_tag_8021q_rx_vbid(u16 vid
)
116 u16 vbid_hi
= (vid
& DSA_8021Q_VBID_HI_MASK
) >> DSA_8021Q_VBID_HI_SHIFT
;
117 u16 vbid_lo
= (vid
& DSA_8021Q_VBID_LO_MASK
) >> DSA_8021Q_VBID_LO_SHIFT
;
119 return (vbid_hi
<< 2) | vbid_lo
;
122 bool vid_is_dsa_8021q(u16 vid
)
124 u16 rsv
= (vid
& DSA_8021Q_RSV_MASK
) >> DSA_8021Q_RSV_SHIFT
;
126 return rsv
== DSA_8021Q_RSV_VAL
;
128 EXPORT_SYMBOL_GPL(vid_is_dsa_8021q
);
130 static struct dsa_tag_8021q_vlan
*
131 dsa_tag_8021q_vlan_find(struct dsa_8021q_context
*ctx
, int port
, u16 vid
)
133 struct dsa_tag_8021q_vlan
*v
;
135 list_for_each_entry(v
, &ctx
->vlans
, list
)
136 if (v
->vid
== vid
&& v
->port
== port
)
142 static int dsa_port_do_tag_8021q_vlan_add(struct dsa_port
*dp
, u16 vid
,
145 struct dsa_8021q_context
*ctx
= dp
->ds
->tag_8021q_ctx
;
146 struct dsa_switch
*ds
= dp
->ds
;
147 struct dsa_tag_8021q_vlan
*v
;
148 int port
= dp
->index
;
151 /* No need to bother with refcounting for user ports */
152 if (!(dsa_port_is_cpu(dp
) || dsa_port_is_dsa(dp
)))
153 return ds
->ops
->tag_8021q_vlan_add(ds
, port
, vid
, flags
);
155 v
= dsa_tag_8021q_vlan_find(ctx
, port
, vid
);
157 refcount_inc(&v
->refcount
);
161 v
= kzalloc(sizeof(*v
), GFP_KERNEL
);
165 err
= ds
->ops
->tag_8021q_vlan_add(ds
, port
, vid
, flags
);
173 refcount_set(&v
->refcount
, 1);
174 list_add_tail(&v
->list
, &ctx
->vlans
);
179 static int dsa_port_do_tag_8021q_vlan_del(struct dsa_port
*dp
, u16 vid
)
181 struct dsa_8021q_context
*ctx
= dp
->ds
->tag_8021q_ctx
;
182 struct dsa_switch
*ds
= dp
->ds
;
183 struct dsa_tag_8021q_vlan
*v
;
184 int port
= dp
->index
;
187 /* No need to bother with refcounting for user ports */
188 if (!(dsa_port_is_cpu(dp
) || dsa_port_is_dsa(dp
)))
189 return ds
->ops
->tag_8021q_vlan_del(ds
, port
, vid
);
191 v
= dsa_tag_8021q_vlan_find(ctx
, port
, vid
);
195 if (!refcount_dec_and_test(&v
->refcount
))
198 err
= ds
->ops
->tag_8021q_vlan_del(ds
, port
, vid
);
200 refcount_inc(&v
->refcount
);
211 dsa_port_tag_8021q_vlan_match(struct dsa_port
*dp
,
212 struct dsa_notifier_tag_8021q_vlan_info
*info
)
214 return dsa_port_is_dsa(dp
) || dsa_port_is_cpu(dp
) || dp
== info
->dp
;
217 int dsa_switch_tag_8021q_vlan_add(struct dsa_switch
*ds
,
218 struct dsa_notifier_tag_8021q_vlan_info
*info
)
223 /* Since we use dsa_broadcast(), there might be other switches in other
224 * trees which don't support tag_8021q, so don't return an error.
225 * Or they might even support tag_8021q but have not registered yet to
226 * use it (maybe they use another tagger currently).
228 if (!ds
->ops
->tag_8021q_vlan_add
|| !ds
->tag_8021q_ctx
)
231 dsa_switch_for_each_port(dp
, ds
) {
232 if (dsa_port_tag_8021q_vlan_match(dp
, info
)) {
235 if (dsa_port_is_user(dp
))
236 flags
|= BRIDGE_VLAN_INFO_UNTAGGED
|
237 BRIDGE_VLAN_INFO_PVID
;
239 err
= dsa_port_do_tag_8021q_vlan_add(dp
, info
->vid
,
249 int dsa_switch_tag_8021q_vlan_del(struct dsa_switch
*ds
,
250 struct dsa_notifier_tag_8021q_vlan_info
*info
)
255 if (!ds
->ops
->tag_8021q_vlan_del
|| !ds
->tag_8021q_ctx
)
258 dsa_switch_for_each_port(dp
, ds
) {
259 if (dsa_port_tag_8021q_vlan_match(dp
, info
)) {
260 err
= dsa_port_do_tag_8021q_vlan_del(dp
, info
->vid
);
269 /* There are 2 ways of offloading tag_8021q VLANs.
271 * One is to use a hardware TCAM to push the port's standalone VLAN into the
272 * frame when forwarding it to the CPU, as an egress modification rule on the
273 * CPU port. This is preferable because it has no side effects for the
274 * autonomous forwarding path, and accomplishes tag_8021q's primary goal of
275 * identifying the source port of each packet based on VLAN ID.
277 * The other is to commit the tag_8021q VLAN as a PVID to the VLAN table, and
278 * to configure the port as VLAN-unaware. This is less preferable because
279 * unique source port identification can only be done for standalone ports;
280 * under a VLAN-unaware bridge, all ports share the same tag_8021q VLAN as
281 * PVID, and under a VLAN-aware bridge, packets received by software will not
282 * have tag_8021q VLANs appended, just bridge VLANs.
284 * For tag_8021q implementations of the second type, this method is used to
285 * replace the standalone tag_8021q VLAN of a port with the tag_8021q VLAN to
286 * be used for VLAN-unaware bridging.
288 int dsa_tag_8021q_bridge_join(struct dsa_switch
*ds
, int port
,
289 struct dsa_bridge bridge
, bool *tx_fwd_offload
,
290 struct netlink_ext_ack
*extack
)
292 struct dsa_port
*dp
= dsa_to_port(ds
, port
);
293 u16 standalone_vid
, bridge_vid
;
296 /* Delete the standalone VLAN of the port and replace it with a
299 standalone_vid
= dsa_tag_8021q_standalone_vid(dp
);
300 bridge_vid
= dsa_tag_8021q_bridge_vid(bridge
.num
);
302 err
= dsa_port_tag_8021q_vlan_add(dp
, bridge_vid
, true);
306 dsa_port_tag_8021q_vlan_del(dp
, standalone_vid
, false);
308 *tx_fwd_offload
= true;
312 EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_join
);
314 void dsa_tag_8021q_bridge_leave(struct dsa_switch
*ds
, int port
,
315 struct dsa_bridge bridge
)
317 struct dsa_port
*dp
= dsa_to_port(ds
, port
);
318 u16 standalone_vid
, bridge_vid
;
321 /* Delete the bridging VLAN of the port and replace it with a
324 standalone_vid
= dsa_tag_8021q_standalone_vid(dp
);
325 bridge_vid
= dsa_tag_8021q_bridge_vid(bridge
.num
);
327 err
= dsa_port_tag_8021q_vlan_add(dp
, standalone_vid
, false);
330 "Failed to delete tag_8021q standalone VLAN %d from port %d: %pe\n",
331 standalone_vid
, port
, ERR_PTR(err
));
334 dsa_port_tag_8021q_vlan_del(dp
, bridge_vid
, true);
336 EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_leave
);
338 /* Set up a port's standalone tag_8021q VLAN */
339 static int dsa_tag_8021q_port_setup(struct dsa_switch
*ds
, int port
)
341 struct dsa_8021q_context
*ctx
= ds
->tag_8021q_ctx
;
342 struct dsa_port
*dp
= dsa_to_port(ds
, port
);
343 u16 vid
= dsa_tag_8021q_standalone_vid(dp
);
344 struct net_device
*conduit
;
347 /* The CPU port is implicitly configured by
348 * configuring the front-panel ports
350 if (!dsa_port_is_user(dp
))
353 conduit
= dsa_port_to_conduit(dp
);
355 err
= dsa_port_tag_8021q_vlan_add(dp
, vid
, false);
358 "Failed to apply standalone VID %d to port %d: %pe\n",
359 vid
, port
, ERR_PTR(err
));
363 /* Add the VLAN to the conduit's RX filter. */
364 vlan_vid_add(conduit
, ctx
->proto
, vid
);
369 static void dsa_tag_8021q_port_teardown(struct dsa_switch
*ds
, int port
)
371 struct dsa_8021q_context
*ctx
= ds
->tag_8021q_ctx
;
372 struct dsa_port
*dp
= dsa_to_port(ds
, port
);
373 u16 vid
= dsa_tag_8021q_standalone_vid(dp
);
374 struct net_device
*conduit
;
376 /* The CPU port is implicitly configured by
377 * configuring the front-panel ports
379 if (!dsa_port_is_user(dp
))
382 conduit
= dsa_port_to_conduit(dp
);
384 dsa_port_tag_8021q_vlan_del(dp
, vid
, false);
386 vlan_vid_del(conduit
, ctx
->proto
, vid
);
389 static int dsa_tag_8021q_setup(struct dsa_switch
*ds
)
395 for (port
= 0; port
< ds
->num_ports
; port
++) {
396 err
= dsa_tag_8021q_port_setup(ds
, port
);
399 "Failed to setup VLAN tagging for port %d: %pe\n",
408 static void dsa_tag_8021q_teardown(struct dsa_switch
*ds
)
414 for (port
= 0; port
< ds
->num_ports
; port
++)
415 dsa_tag_8021q_port_teardown(ds
, port
);
418 int dsa_tag_8021q_register(struct dsa_switch
*ds
, __be16 proto
)
420 struct dsa_8021q_context
*ctx
;
423 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
430 INIT_LIST_HEAD(&ctx
->vlans
);
432 ds
->tag_8021q_ctx
= ctx
;
434 err
= dsa_tag_8021q_setup(ds
);
444 EXPORT_SYMBOL_GPL(dsa_tag_8021q_register
);
446 void dsa_tag_8021q_unregister(struct dsa_switch
*ds
)
448 struct dsa_8021q_context
*ctx
= ds
->tag_8021q_ctx
;
449 struct dsa_tag_8021q_vlan
*v
, *n
;
451 dsa_tag_8021q_teardown(ds
);
453 list_for_each_entry_safe(v
, n
, &ctx
->vlans
, list
) {
458 ds
->tag_8021q_ctx
= NULL
;
462 EXPORT_SYMBOL_GPL(dsa_tag_8021q_unregister
);
464 struct sk_buff
*dsa_8021q_xmit(struct sk_buff
*skb
, struct net_device
*netdev
,
467 /* skb->data points at the MAC header, which is fine
468 * for vlan_insert_tag().
470 return vlan_insert_tag(skb
, htons(tpid
), tci
);
472 EXPORT_SYMBOL_GPL(dsa_8021q_xmit
);
474 static struct net_device
*
475 dsa_tag_8021q_find_port_by_vbid(struct net_device
*conduit
, int vbid
)
477 struct dsa_port
*cpu_dp
= conduit
->dsa_ptr
;
478 struct dsa_switch_tree
*dst
= cpu_dp
->dst
;
484 dsa_tree_for_each_user_port(dp
, dst
) {
488 if (dp
->stp_state
!= BR_STATE_LEARNING
&&
489 dp
->stp_state
!= BR_STATE_FORWARDING
)
492 if (dp
->cpu_dp
!= cpu_dp
)
495 if (dsa_port_bridge_num_get(dp
) == vbid
)
502 struct net_device
*dsa_tag_8021q_find_user(struct net_device
*conduit
,
503 int source_port
, int switch_id
,
506 /* Always prefer precise source port information, if available */
507 if (source_port
!= -1 && switch_id
!= -1)
508 return dsa_conduit_find_user(conduit
, switch_id
, source_port
);
510 return dsa_tag_8021q_find_port_by_vbid(conduit
, vbid
);
512 return dsa_find_designated_bridge_port_by_vid(conduit
, vid
);
514 EXPORT_SYMBOL_GPL(dsa_tag_8021q_find_user
);
517 * dsa_8021q_rcv - Decode source information from tag_8021q header
518 * @skb: RX socket buffer
519 * @source_port: pointer to storage for precise source port information.
520 * If this is known already from outside tag_8021q, the pre-initialized
521 * value is preserved. If not known, pass -1.
522 * @switch_id: similar to source_port.
523 * @vbid: pointer to storage for imprecise bridge ID. Must be pre-initialized
524 * with -1. If a positive value is returned, the source_port and switch_id
526 * @vid: pointer to storage for original VID, in case tag_8021q decoding failed.
528 * If the packet has a tag_8021q header, decode it and set @source_port,
529 * @switch_id and @vbid, and strip the header. Otherwise set @vid and keep the
530 * header in the hwaccel area of the packet.
532 void dsa_8021q_rcv(struct sk_buff
*skb
, int *source_port
, int *switch_id
,
535 int tmp_source_port
, tmp_switch_id
, tmp_vbid
;
539 if (skb_vlan_tag_present(skb
)) {
540 vlan_proto
= skb
->vlan_proto
;
541 tci
= skb_vlan_tag_get(skb
);
542 __vlan_hwaccel_clear_tag(skb
);
544 struct vlan_ethhdr
*hdr
= vlan_eth_hdr(skb
);
546 vlan_proto
= hdr
->h_vlan_proto
;
547 skb_push_rcsum(skb
, ETH_HLEN
);
548 __skb_vlan_pop(skb
, &tci
);
549 skb_pull_rcsum(skb
, ETH_HLEN
);
552 tmp_vid
= tci
& VLAN_VID_MASK
;
553 if (!vid_is_dsa_8021q(tmp_vid
)) {
554 /* Not a tag_8021q frame, so return the VID to the
555 * caller for further processing, and put the tag back
560 __vlan_hwaccel_put_tag(skb
, vlan_proto
, tci
);
565 tmp_source_port
= dsa_8021q_rx_source_port(tmp_vid
);
566 tmp_switch_id
= dsa_8021q_rx_switch_id(tmp_vid
);
567 tmp_vbid
= dsa_tag_8021q_rx_vbid(tmp_vid
);
569 /* Precise source port information is unknown when receiving from a
570 * VLAN-unaware bridging domain, and tmp_source_port and tmp_switch_id
571 * are zeroes in this case.
573 * Preserve the source information from hardware-specific mechanisms,
574 * if available. This allows us to not overwrite a valid source port
575 * and switch ID with less precise values.
577 if (tmp_vbid
== 0 && *source_port
== -1)
578 *source_port
= tmp_source_port
;
579 if (tmp_vbid
== 0 && *switch_id
== -1)
580 *switch_id
= tmp_switch_id
;
585 skb
->priority
= (tci
& VLAN_PRIO_MASK
) >> VLAN_PRIO_SHIFT
;
588 EXPORT_SYMBOL_GPL(dsa_8021q_rcv
);