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 /* Binary structure of the fake 12-bit VID field (when the TPID is 15 * ETH_P_DSA_8021Q): 16 * 17 * | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 18 * +-----------+-----+-----------------+-----------+-----------------------+ 19 * | DIR | RSV | SWITCH_ID | RSV | PORT | 20 * +-----------+-----+-----------------+-----------+-----------------------+ 21 * 22 * DIR - VID[11:10]: 23 * Direction flags. 24 * * 1 (0b01) for RX VLAN, 25 * * 2 (0b10) for TX VLAN. 26 * These values make the special VIDs of 0, 1 and 4095 to be left 27 * unused by this coding scheme. 28 * 29 * RSV - VID[9]: 30 * To be used for further expansion of SWITCH_ID or for other purposes. 31 * Must be transmitted as zero and ignored on receive. 32 * 33 * SWITCH_ID - VID[8:6]: 34 * Index of switch within DSA tree. Must be between 0 and 35 * DSA_MAX_SWITCHES - 1. 36 * 37 * RSV - VID[5:4]: 38 * To be used for further expansion of PORT or for other purposes. 39 * Must be transmitted as zero and ignored on receive. 40 * 41 * PORT - VID[3:0]: 42 * Index of switch port. Must be between 0 and DSA_MAX_PORTS - 1. 43 */ 44 45 #define DSA_8021Q_DIR_SHIFT 10 46 #define DSA_8021Q_DIR_MASK GENMASK(11, 10) 47 #define DSA_8021Q_DIR(x) (((x) << DSA_8021Q_DIR_SHIFT) & \ 48 DSA_8021Q_DIR_MASK) 49 #define DSA_8021Q_DIR_RX DSA_8021Q_DIR(1) 50 #define DSA_8021Q_DIR_TX DSA_8021Q_DIR(2) 51 52 #define DSA_8021Q_SWITCH_ID_SHIFT 6 53 #define DSA_8021Q_SWITCH_ID_MASK GENMASK(8, 6) 54 #define DSA_8021Q_SWITCH_ID(x) (((x) << DSA_8021Q_SWITCH_ID_SHIFT) & \ 55 DSA_8021Q_SWITCH_ID_MASK) 56 57 #define DSA_8021Q_PORT_SHIFT 0 58 #define DSA_8021Q_PORT_MASK GENMASK(3, 0) 59 #define DSA_8021Q_PORT(x) (((x) << DSA_8021Q_PORT_SHIFT) & \ 60 DSA_8021Q_PORT_MASK) 61 62 /* Returns the VID to be inserted into the frame from xmit for switch steering 63 * instructions on egress. Encodes switch ID and port ID. 64 */ 65 u16 dsa_8021q_tx_vid(struct dsa_switch *ds, int port) 66 { 67 return DSA_8021Q_DIR_TX | DSA_8021Q_SWITCH_ID(ds->index) | 68 DSA_8021Q_PORT(port); 69 } 70 EXPORT_SYMBOL_GPL(dsa_8021q_tx_vid); 71 72 /* Returns the VID that will be installed as pvid for this switch port, sent as 73 * tagged egress towards the CPU port and decoded by the rcv function. 74 */ 75 u16 dsa_8021q_rx_vid(struct dsa_switch *ds, int port) 76 { 77 return DSA_8021Q_DIR_RX | DSA_8021Q_SWITCH_ID(ds->index) | 78 DSA_8021Q_PORT(port); 79 } 80 EXPORT_SYMBOL_GPL(dsa_8021q_rx_vid); 81 82 /* Returns the decoded switch ID from the RX VID. */ 83 int dsa_8021q_rx_switch_id(u16 vid) 84 { 85 return (vid & DSA_8021Q_SWITCH_ID_MASK) >> DSA_8021Q_SWITCH_ID_SHIFT; 86 } 87 EXPORT_SYMBOL_GPL(dsa_8021q_rx_switch_id); 88 89 /* Returns the decoded port ID from the RX VID. */ 90 int dsa_8021q_rx_source_port(u16 vid) 91 { 92 return (vid & DSA_8021Q_PORT_MASK) >> DSA_8021Q_PORT_SHIFT; 93 } 94 EXPORT_SYMBOL_GPL(dsa_8021q_rx_source_port); 95 96 static int dsa_8021q_restore_pvid(struct dsa_switch *ds, int port) 97 { 98 struct bridge_vlan_info vinfo; 99 struct net_device *slave; 100 u16 pvid; 101 int err; 102 103 if (!dsa_is_user_port(ds, port)) 104 return 0; 105 106 slave = ds->ports[port].slave; 107 108 err = br_vlan_get_pvid(slave, &pvid); 109 if (!pvid || err < 0) 110 /* There is no pvid on the bridge for this port, which is 111 * perfectly valid. Nothing to restore, bye-bye! 112 */ 113 return 0; 114 115 err = br_vlan_get_info(slave, pvid, &vinfo); 116 if (err < 0) { 117 dev_err(ds->dev, "Couldn't determine PVID attributes\n"); 118 return err; 119 } 120 121 return dsa_port_vid_add(&ds->ports[port], pvid, vinfo.flags); 122 } 123 124 /* If @enabled is true, installs @vid with @flags into the switch port's HW 125 * filter. 126 * If @enabled is false, deletes @vid (ignores @flags) from the port. Had the 127 * user explicitly configured this @vid through the bridge core, then the @vid 128 * is installed again, but this time with the flags from the bridge layer. 129 */ 130 static int dsa_8021q_vid_apply(struct dsa_switch *ds, int port, u16 vid, 131 u16 flags, bool enabled) 132 { 133 struct dsa_port *dp = &ds->ports[port]; 134 struct bridge_vlan_info vinfo; 135 int err; 136 137 if (enabled) 138 return dsa_port_vid_add(dp, vid, flags); 139 140 err = dsa_port_vid_del(dp, vid); 141 if (err < 0) 142 return err; 143 144 /* Nothing to restore from the bridge for a non-user port. 145 * The CPU port VLANs are restored implicitly with the user ports, 146 * similar to how the bridge does in dsa_slave_vlan_add and 147 * dsa_slave_vlan_del. 148 */ 149 if (!dsa_is_user_port(ds, port)) 150 return 0; 151 152 err = br_vlan_get_info(dp->slave, vid, &vinfo); 153 /* Couldn't determine bridge attributes for this vid, 154 * it means the bridge had not configured it. 155 */ 156 if (err < 0) 157 return 0; 158 159 /* Restore the VID from the bridge */ 160 err = dsa_port_vid_add(dp, vid, vinfo.flags); 161 if (err < 0) 162 return err; 163 164 vinfo.flags &= ~BRIDGE_VLAN_INFO_PVID; 165 166 return dsa_port_vid_add(dp->cpu_dp, vid, vinfo.flags); 167 } 168 169 /* RX VLAN tagging (left) and TX VLAN tagging (right) setup shown for a single 170 * front-panel switch port (here swp0). 171 * 172 * Port identification through VLAN (802.1Q) tags has different requirements 173 * for it to work effectively: 174 * - On RX (ingress from network): each front-panel port must have a pvid 175 * that uniquely identifies it, and the egress of this pvid must be tagged 176 * towards the CPU port, so that software can recover the source port based 177 * on the VID in the frame. But this would only work for standalone ports; 178 * if bridged, this VLAN setup would break autonomous forwarding and would 179 * force all switched traffic to pass through the CPU. So we must also make 180 * the other front-panel ports members of this VID we're adding, albeit 181 * we're not making it their PVID (they'll still have their own). 182 * By the way - just because we're installing the same VID in multiple 183 * switch ports doesn't mean that they'll start to talk to one another, even 184 * while not bridged: the final forwarding decision is still an AND between 185 * the L2 forwarding information (which is limiting forwarding in this case) 186 * and the VLAN-based restrictions (of which there are none in this case, 187 * since all ports are members). 188 * - On TX (ingress from CPU and towards network) we are faced with a problem. 189 * If we were to tag traffic (from within DSA) with the port's pvid, all 190 * would be well, assuming the switch ports were standalone. Frames would 191 * have no choice but to be directed towards the correct front-panel port. 192 * But because we also want the RX VLAN to not break bridging, then 193 * inevitably that means that we have to give them a choice (of what 194 * front-panel port to go out on), and therefore we cannot steer traffic 195 * based on the RX VID. So what we do is simply install one more VID on the 196 * front-panel and CPU ports, and profit off of the fact that steering will 197 * work just by virtue of the fact that there is only one other port that's 198 * a member of the VID we're tagging the traffic with - the desired one. 199 * 200 * So at the end, each front-panel port will have one RX VID (also the PVID), 201 * the RX VID of all other front-panel ports, and one TX VID. Whereas the CPU 202 * port will have the RX and TX VIDs of all front-panel ports, and on top of 203 * that, is also tagged-input and tagged-output (VLAN trunk). 204 * 205 * CPU port CPU port 206 * +-------------+-----+-------------+ +-------------+-----+-------------+ 207 * | RX VID | | | | TX VID | | | 208 * | of swp0 | | | | of swp0 | | | 209 * | +-----+ | | +-----+ | 210 * | ^ T | | | Tagged | 211 * | | | | | ingress | 212 * | +-------+---+---+-------+ | | +-----------+ | 213 * | | | | | | | | Untagged | 214 * | | U v U v U v | | v egress | 215 * | +-----+ +-----+ +-----+ +-----+ | | +-----+ +-----+ +-----+ +-----+ | 216 * | | | | | | | | | | | | | | | | | | | | 217 * | |PVID | | | | | | | | | | | | | | | | | | 218 * +-+-----+-+-----+-+-----+-+-----+-+ +-+-----+-+-----+-+-----+-+-----+-+ 219 * swp0 swp1 swp2 swp3 swp0 swp1 swp2 swp3 220 */ 221 int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, int port, bool enabled) 222 { 223 int upstream = dsa_upstream_port(ds, port); 224 u16 rx_vid = dsa_8021q_rx_vid(ds, port); 225 u16 tx_vid = dsa_8021q_tx_vid(ds, port); 226 int i, err; 227 228 /* The CPU port is implicitly configured by 229 * configuring the front-panel ports 230 */ 231 if (!dsa_is_user_port(ds, port)) 232 return 0; 233 234 /* Add this user port's RX VID to the membership list of all others 235 * (including itself). This is so that bridging will not be hindered. 236 * L2 forwarding rules still take precedence when there are no VLAN 237 * restrictions, so there are no concerns about leaking traffic. 238 */ 239 for (i = 0; i < ds->num_ports; i++) { 240 u16 flags; 241 242 if (i == upstream) 243 continue; 244 else if (i == port) 245 /* The RX VID is pvid on this port */ 246 flags = BRIDGE_VLAN_INFO_UNTAGGED | 247 BRIDGE_VLAN_INFO_PVID; 248 else 249 /* The RX VID is a regular VLAN on all others */ 250 flags = BRIDGE_VLAN_INFO_UNTAGGED; 251 252 err = dsa_8021q_vid_apply(ds, i, rx_vid, flags, enabled); 253 if (err) { 254 dev_err(ds->dev, "Failed to apply RX VID %d to port %d: %d\n", 255 rx_vid, port, err); 256 return err; 257 } 258 } 259 260 /* CPU port needs to see this port's RX VID 261 * as tagged egress. 262 */ 263 err = dsa_8021q_vid_apply(ds, upstream, rx_vid, 0, enabled); 264 if (err) { 265 dev_err(ds->dev, "Failed to apply RX VID %d to port %d: %d\n", 266 rx_vid, port, err); 267 return err; 268 } 269 270 /* Finally apply the TX VID on this port and on the CPU port */ 271 err = dsa_8021q_vid_apply(ds, port, tx_vid, BRIDGE_VLAN_INFO_UNTAGGED, 272 enabled); 273 if (err) { 274 dev_err(ds->dev, "Failed to apply TX VID %d on port %d: %d\n", 275 tx_vid, port, err); 276 return err; 277 } 278 err = dsa_8021q_vid_apply(ds, upstream, tx_vid, 0, enabled); 279 if (err) { 280 dev_err(ds->dev, "Failed to apply TX VID %d on port %d: %d\n", 281 tx_vid, upstream, err); 282 return err; 283 } 284 285 if (!enabled) 286 err = dsa_8021q_restore_pvid(ds, port); 287 288 return err; 289 } 290 EXPORT_SYMBOL_GPL(dsa_port_setup_8021q_tagging); 291 292 struct sk_buff *dsa_8021q_xmit(struct sk_buff *skb, struct net_device *netdev, 293 u16 tpid, u16 tci) 294 { 295 /* skb->data points at skb_mac_header, which 296 * is fine for vlan_insert_tag. 297 */ 298 return vlan_insert_tag(skb, htons(tpid), tci); 299 } 300 EXPORT_SYMBOL_GPL(dsa_8021q_xmit); 301 302 static const struct dsa_device_ops dsa_8021q_netdev_ops = { 303 .name = "8021q", 304 .proto = DSA_TAG_PROTO_8021Q, 305 .overhead = VLAN_HLEN, 306 }; 307 308 MODULE_LICENSE("GPL v2"); 309 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_8021Q); 310 311 module_dsa_tag_driver(dsa_8021q_netdev_ops);