1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> 3 * 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. The 6 * dsa_8021q_netdev_ops is registered for API compliance and not used 7 * directly by callers. 8 */ 9 #include <linux/if_bridge.h> 10 #include <linux/if_vlan.h> 11 12 #include "dsa_priv.h" 13 14 /* Allocating two VLAN tags per port - one for the RX VID and 15 * the other for the TX VID - see below 16 */ 17 #define DSA_8021Q_VID_RANGE (DSA_MAX_SWITCHES * DSA_MAX_PORTS) 18 #define DSA_8021Q_VID_BASE (VLAN_N_VID - 2 * DSA_8021Q_VID_RANGE - 1) 19 #define DSA_8021Q_RX_VID_BASE (DSA_8021Q_VID_BASE) 20 #define DSA_8021Q_TX_VID_BASE (DSA_8021Q_VID_BASE + DSA_8021Q_VID_RANGE) 21 22 /* Returns the VID to be inserted into the frame from xmit for switch steering 23 * instructions on egress. Encodes switch ID and port ID. 24 */ 25 u16 dsa_8021q_tx_vid(struct dsa_switch *ds, int port) 26 { 27 return DSA_8021Q_TX_VID_BASE + (DSA_MAX_PORTS * ds->index) + port; 28 } 29 EXPORT_SYMBOL_GPL(dsa_8021q_tx_vid); 30 31 /* Returns the VID that will be installed as pvid for this switch port, sent as 32 * tagged egress towards the CPU port and decoded by the rcv function. 33 */ 34 u16 dsa_8021q_rx_vid(struct dsa_switch *ds, int port) 35 { 36 return DSA_8021Q_RX_VID_BASE + (DSA_MAX_PORTS * ds->index) + port; 37 } 38 EXPORT_SYMBOL_GPL(dsa_8021q_rx_vid); 39 40 /* Returns the decoded switch ID from the RX VID. */ 41 int dsa_8021q_rx_switch_id(u16 vid) 42 { 43 return ((vid - DSA_8021Q_RX_VID_BASE) / DSA_MAX_PORTS); 44 } 45 EXPORT_SYMBOL_GPL(dsa_8021q_rx_switch_id); 46 47 /* Returns the decoded port ID from the RX VID. */ 48 int dsa_8021q_rx_source_port(u16 vid) 49 { 50 return ((vid - DSA_8021Q_RX_VID_BASE) % DSA_MAX_PORTS); 51 } 52 EXPORT_SYMBOL_GPL(dsa_8021q_rx_source_port); 53 54 /* RX VLAN tagging (left) and TX VLAN tagging (right) setup shown for a single 55 * front-panel switch port (here swp0). 56 * 57 * Port identification through VLAN (802.1Q) tags has different requirements 58 * for it to work effectively: 59 * - On RX (ingress from network): each front-panel port must have a pvid 60 * that uniquely identifies it, and the egress of this pvid must be tagged 61 * towards the CPU port, so that software can recover the source port based 62 * on the VID in the frame. But this would only work for standalone ports; 63 * if bridged, this VLAN setup would break autonomous forwarding and would 64 * force all switched traffic to pass through the CPU. So we must also make 65 * the other front-panel ports members of this VID we're adding, albeit 66 * we're not making it their PVID (they'll still have their own). 67 * By the way - just because we're installing the same VID in multiple 68 * switch ports doesn't mean that they'll start to talk to one another, even 69 * while not bridged: the final forwarding decision is still an AND between 70 * the L2 forwarding information (which is limiting forwarding in this case) 71 * and the VLAN-based restrictions (of which there are none in this case, 72 * since all ports are members). 73 * - On TX (ingress from CPU and towards network) we are faced with a problem. 74 * If we were to tag traffic (from within DSA) with the port's pvid, all 75 * would be well, assuming the switch ports were standalone. Frames would 76 * have no choice but to be directed towards the correct front-panel port. 77 * But because we also want the RX VLAN to not break bridging, then 78 * inevitably that means that we have to give them a choice (of what 79 * front-panel port to go out on), and therefore we cannot steer traffic 80 * based on the RX VID. So what we do is simply install one more VID on the 81 * front-panel and CPU ports, and profit off of the fact that steering will 82 * work just by virtue of the fact that there is only one other port that's 83 * a member of the VID we're tagging the traffic with - the desired one. 84 * 85 * So at the end, each front-panel port will have one RX VID (also the PVID), 86 * the RX VID of all other front-panel ports, and one TX VID. Whereas the CPU 87 * port will have the RX and TX VIDs of all front-panel ports, and on top of 88 * that, is also tagged-input and tagged-output (VLAN trunk). 89 * 90 * CPU port CPU port 91 * +-------------+-----+-------------+ +-------------+-----+-------------+ 92 * | RX VID | | | | TX VID | | | 93 * | of swp0 | | | | of swp0 | | | 94 * | +-----+ | | +-----+ | 95 * | ^ T | | | Tagged | 96 * | | | | | ingress | 97 * | +-------+---+---+-------+ | | +-----------+ | 98 * | | | | | | | | Untagged | 99 * | | U v U v U v | | v egress | 100 * | +-----+ +-----+ +-----+ +-----+ | | +-----+ +-----+ +-----+ +-----+ | 101 * | | | | | | | | | | | | | | | | | | | | 102 * | |PVID | | | | | | | | | | | | | | | | | | 103 * +-+-----+-+-----+-+-----+-+-----+-+ +-+-----+-+-----+-+-----+-+-----+-+ 104 * swp0 swp1 swp2 swp3 swp0 swp1 swp2 swp3 105 */ 106 int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int port, bool enabled) 107 { 108 int upstream = dsa_upstream_port(ds, port); 109 struct dsa_port *dp = &ds->ports[port]; 110 struct dsa_port *upstream_dp = &ds->ports[upstream]; 111 u16 rx_vid = dsa_8021q_rx_vid(ds, port); 112 u16 tx_vid = dsa_8021q_tx_vid(ds, port); 113 int i, err; 114 115 /* The CPU port is implicitly configured by 116 * configuring the front-panel ports 117 */ 118 if (!dsa_is_user_port(ds, port)) 119 return 0; 120 121 /* Add this user port's RX VID to the membership list of all others 122 * (including itself). This is so that bridging will not be hindered. 123 * L2 forwarding rules still take precedence when there are no VLAN 124 * restrictions, so there are no concerns about leaking traffic. 125 */ 126 for (i = 0; i < ds->num_ports; i++) { 127 struct dsa_port *other_dp = &ds->ports[i]; 128 u16 flags; 129 130 if (i == upstream) 131 /* CPU port needs to see this port's RX VID 132 * as tagged egress. 133 */ 134 flags = 0; 135 else if (i == port) 136 /* The RX VID is pvid on this port */ 137 flags = BRIDGE_VLAN_INFO_UNTAGGED | 138 BRIDGE_VLAN_INFO_PVID; 139 else 140 /* The RX VID is a regular VLAN on all others */ 141 flags = BRIDGE_VLAN_INFO_UNTAGGED; 142 143 if (enabled) 144 err = dsa_port_vid_add(other_dp, rx_vid, flags); 145 else 146 err = dsa_port_vid_del(other_dp, rx_vid); 147 if (err) { 148 dev_err(ds->dev, "Failed to apply RX VID %d to port %d: %d\n", 149 rx_vid, port, err); 150 return err; 151 } 152 } 153 /* Finally apply the TX VID on this port and on the CPU port */ 154 if (enabled) 155 err = dsa_port_vid_add(dp, tx_vid, BRIDGE_VLAN_INFO_UNTAGGED); 156 else 157 err = dsa_port_vid_del(dp, tx_vid); 158 if (err) { 159 dev_err(ds->dev, "Failed to apply TX VID %d on port %d: %d\n", 160 tx_vid, port, err); 161 return err; 162 } 163 if (enabled) 164 err = dsa_port_vid_add(upstream_dp, tx_vid, 0); 165 else 166 err = dsa_port_vid_del(upstream_dp, tx_vid); 167 if (err) { 168 dev_err(ds->dev, "Failed to apply TX VID %d on port %d: %d\n", 169 tx_vid, upstream, err); 170 return err; 171 } 172 173 return 0; 174 } 175 EXPORT_SYMBOL_GPL(dsa_port_setup_8021q_tagging); 176 177 struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev, 178 u16 tpid, u16 tci) 179 { 180 /* skb->data points at skb_mac_header, which 181 * is fine for vlan_insert_tag. 182 */ 183 return vlan_insert_tag(skb, htons(tpid), tci); 184 } 185 EXPORT_SYMBOL_GPL(dsa_8021q_xmit); 186 187 struct sk_buff *dsa_8021q_rcv(struct sk_buff *skb, struct net_device *netdev, 188 struct packet_type *pt, u16 *tpid, u16 *tci) 189 { 190 struct vlan_ethhdr *tag; 191 192 if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) 193 return NULL; 194 195 tag = vlan_eth_hdr(skb); 196 *tpid = ntohs(tag->h_vlan_proto); 197 *tci = ntohs(tag->h_vlan_TCI); 198 199 /* skb->data points in the middle of the VLAN tag, 200 * after tpid and before tci. This is because so far, 201 * ETH_HLEN (DMAC, SMAC, EtherType) bytes were pulled. 202 * There are 2 bytes of VLAN tag left in skb->data, and upper 203 * layers expect the 'real' EtherType to be consumed as well. 204 * Coincidentally, a VLAN header is also of the same size as 205 * the number of bytes that need to be pulled. 206 */ 207 skb_pull_rcsum(skb, VLAN_HLEN); 208 209 return skb; 210 } 211 EXPORT_SYMBOL_GPL(dsa_8021q_rcv); 212 213 static const struct dsa_device_ops dsa_8021q_netdev_ops = { 214 .name = "8021q", 215 .proto = DSA_TAG_PROTO_8021Q, 216 .overhead = VLAN_HLEN, 217 }; 218 219 MODULE_LICENSE("GPL v2"); 220 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_8021Q); 221 222 module_dsa_tag_driver(dsa_8021q_netdev_ops); 223