|
@@ -280,20 +280,35 @@ struct net_protocol vlan_protocol __net_protocol = {
|
280
|
280
|
};
|
281
|
281
|
|
282
|
282
|
/**
|
283
|
|
- * Create VLAN device
|
|
283
|
+ * Check if network device can be used as a VLAN trunk device
|
284
|
284
|
*
|
285
|
285
|
* @v trunk Trunk network device
|
286
|
|
- * @v tag VLAN tag
|
287
|
|
- * @v priority Default VLAN priority
|
288
|
|
- * @ret rc Return status code
|
|
286
|
+ * @ret is_ok Trunk network device is usable
|
289
|
287
|
*
|
290
|
|
- * The VLAN device will be created as an Ethernet device. (We cannot
|
|
288
|
+ * VLAN devices will be created as Ethernet devices. (We cannot
|
291
|
289
|
* simply clone the link layer of the trunk network device, because
|
292
|
290
|
* this link layer may expect the network device structure to contain
|
293
|
291
|
* some link-layer-private data.) The trunk network device must
|
294
|
292
|
* therefore have a link layer that is in some sense 'compatible' with
|
295
|
293
|
* Ethernet; specifically, it must have link-layer addresses that are
|
296
|
294
|
* the same length as Ethernet link-layer addresses.
|
|
295
|
+ *
|
|
296
|
+ * As an additional check, and primarily to assist with the sanity of
|
|
297
|
+ * the FCoE code, we refuse to allow nested VLANs.
|
|
298
|
+ */
|
|
299
|
+int vlan_can_be_trunk ( struct net_device *trunk ) {
|
|
300
|
+
|
|
301
|
+ return ( ( trunk->ll_protocol->ll_addr_len == ETH_ALEN ) &&
|
|
302
|
+ ( trunk->op != &vlan_operations ) );
|
|
303
|
+}
|
|
304
|
+
|
|
305
|
+/**
|
|
306
|
+ * Create VLAN device
|
|
307
|
+ *
|
|
308
|
+ * @v trunk Trunk network device
|
|
309
|
+ * @v tag VLAN tag
|
|
310
|
+ * @v priority Default VLAN priority
|
|
311
|
+ * @ret rc Return status code
|
297
|
312
|
*/
|
298
|
313
|
int vlan_create ( struct net_device *trunk, unsigned int tag,
|
299
|
314
|
unsigned int priority ) {
|
|
@@ -313,9 +328,9 @@ int vlan_create ( struct net_device *trunk, unsigned int tag,
|
313
|
328
|
}
|
314
|
329
|
|
315
|
330
|
/* Sanity checks */
|
316
|
|
- if ( trunk->ll_protocol->ll_addr_len != ETH_ALEN ) {
|
317
|
|
- DBGC ( trunk, "VLAN %s cannot create VLAN for %s device\n",
|
318
|
|
- trunk->name, trunk->ll_protocol->name );
|
|
331
|
+ if ( ! vlan_can_be_trunk ( trunk ) ) {
|
|
332
|
+ DBGC ( trunk, "VLAN %s cannot create VLAN on non-trunk "
|
|
333
|
+ "device\n", trunk->name );
|
319
|
334
|
rc = -ENOTTY;
|
320
|
335
|
goto err_sanity;
|
321
|
336
|
}
|