Browse Source

[vlan] Provide vlan_netdev_rx() and vlan_netdev_rx_err()

The Hermon driver uses vlan_find() to identify the appropriate VLAN
device for packets that are received with the VLAN tag already
stripped out by the hardware.  Generalise this capability and expose
it for use by other network card drivers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 5 years ago
parent
commit
fe680c8228
4 changed files with 85 additions and 22 deletions
  1. 6
    12
      src/drivers/infiniband/hermon.c
  2. 6
    2
      src/include/ipxe/vlan.h
  3. 27
    7
      src/net/netdevice.c
  4. 46
    1
      src/net/vlan.c

+ 6
- 12
src/drivers/infiniband/hermon.c View File

@@ -3207,22 +3207,16 @@ static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
3207 3207
 				       struct ib_address_vector *source,
3208 3208
 				       struct io_buffer *iobuf, int rc ) {
3209 3209
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
3210
-	struct net_device *vlan;
3211
-
3212
-	/* Find VLAN device, if applicable */
3213
-	if ( source->vlan_present ) {
3214
-		if ( ( vlan = vlan_find ( netdev, source->vlan ) ) != NULL ) {
3215
-			netdev = vlan;
3216
-		} else if ( rc == 0 ) {
3217
-			rc = -ENODEV;
3218
-		}
3219
-	}
3210
+	unsigned int tag;
3211
+
3212
+	/* Identify VLAN tag, if applicable */
3213
+	tag = ( source->vlan_present ? source->vlan : 0 );
3220 3214
 
3221 3215
 	/* Hand off to network layer */
3222 3216
 	if ( rc == 0 ) {
3223
-		netdev_rx ( netdev, iobuf );
3217
+		vlan_netdev_rx ( netdev, tag, iobuf );
3224 3218
 	} else {
3225
-		netdev_rx_err ( netdev, iobuf, rc );
3219
+		vlan_netdev_rx_err ( netdev, tag, iobuf, rc );
3226 3220
 	}
3227 3221
 }
3228 3222
 

+ 6
- 2
src/include/ipxe/vlan.h View File

@@ -10,6 +10,8 @@
10 10
 
11 11
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
12 12
 
13
+#include <ipxe/netdevice.h>
14
+
13 15
 /** A VLAN header */
14 16
 struct vlan_header {
15 17
 	/** Tag control information */
@@ -59,12 +61,14 @@ struct vlan_header {
59 61
  */
60 62
 #define VLAN_PRIORITY_IS_VALID( priority ) ( (priority) <= 7 )
61 63
 
62
-extern struct net_device * vlan_find ( struct net_device *trunk,
63
-				       unsigned int tag );
64 64
 extern unsigned int vlan_tag ( struct net_device *netdev );
65 65
 extern int vlan_can_be_trunk ( struct net_device *trunk );
66 66
 extern int vlan_create ( struct net_device *trunk, unsigned int tag,
67 67
 			 unsigned int priority );
68 68
 extern int vlan_destroy ( struct net_device *netdev );
69
+extern void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
70
+			     struct io_buffer *iobuf );
71
+extern void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
72
+				 struct io_buffer *iobuf, int rc );
69 73
 
70 74
 #endif /* _IPXE_VLAN_H */

+ 27
- 7
src/net/netdevice.c View File

@@ -1126,15 +1126,35 @@ __weak unsigned int vlan_tag ( struct net_device *netdev __unused ) {
1126 1126
 }
1127 1127
 
1128 1128
 /**
1129
- * Identify VLAN device (when VLAN support is not present)
1129
+ * Add VLAN tag-stripped packet to queue (when VLAN support is not present)
1130 1130
  *
1131
- * @v trunk		Trunk network device
1132
- * @v tag		VLAN tag
1133
- * @ret netdev		VLAN device, if any
1131
+ * @v netdev		Network device
1132
+ * @v tag		VLAN tag, or zero
1133
+ * @v iobuf		I/O buffer
1134 1134
  */
1135
-__weak struct net_device * vlan_find ( struct net_device *trunk __unused,
1136
-				       unsigned int tag __unused ) {
1137
-	return NULL;
1135
+__weak void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
1136
+			     struct io_buffer *iobuf ) {
1137
+
1138
+	if ( tag == 0 ) {
1139
+		netdev_rx ( netdev, iobuf );
1140
+	} else {
1141
+		netdev_rx_err ( netdev, iobuf, -ENODEV );
1142
+	}
1143
+}
1144
+
1145
+/**
1146
+ * Discard received VLAN tag-stripped packet (when VLAN support is not present)
1147
+ *
1148
+ * @v netdev		Network device
1149
+ * @v tag		VLAN tag, or zero
1150
+ * @v iobuf		I/O buffer, or NULL
1151
+ * @v rc		Packet status code
1152
+ */
1153
+__weak void vlan_netdev_rx_err ( struct net_device *netdev,
1154
+				 unsigned int tag __unused,
1155
+				 struct io_buffer *iobuf, int rc ) {
1156
+
1157
+	netdev_rx_err ( netdev, iobuf, rc );
1138 1158
 }
1139 1159
 
1140 1160
 /** Networking stack process */

+ 46
- 1
src/net/vlan.c View File

@@ -199,7 +199,8 @@ static void vlan_sync ( struct net_device *netdev ) {
199 199
  * @v tag		VLAN tag
200 200
  * @ret netdev		VLAN device, if any
201 201
  */
202
-struct net_device * vlan_find ( struct net_device *trunk, unsigned int tag ) {
202
+static struct net_device * vlan_find ( struct net_device *trunk,
203
+				       unsigned int tag ) {
203 204
 	struct net_device *netdev;
204 205
 	struct vlan_device *vlan;
205 206
 
@@ -506,3 +507,47 @@ struct net_driver vlan_driver __net_driver = {
506 507
 	.notify = vlan_notify,
507 508
 	.remove = vlan_remove,
508 509
 };
510
+
511
+/**
512
+ * Add VLAN tag-stripped packet to receive queue
513
+ *
514
+ * @v netdev		Network device
515
+ * @v tag		VLAN tag, or zero
516
+ * @v iobuf		I/O buffer
517
+ */
518
+void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
519
+		      struct io_buffer *iobuf ) {
520
+	struct net_device *vlan;
521
+
522
+	/* Identify VLAN device, if applicable */
523
+	if ( tag ) {
524
+		if ( ( vlan = vlan_find ( netdev, tag ) ) == NULL ) {
525
+			netdev_rx_err ( netdev, iobuf, -ENODEV );
526
+			return;
527
+		}
528
+		netdev = vlan;
529
+	}
530
+
531
+	/* Hand off to network device */
532
+	netdev_rx ( netdev, iobuf );
533
+}
534
+
535
+/**
536
+ * Discard received VLAN tag-stripped packet
537
+ *
538
+ * @v netdev		Network device
539
+ * @v tag		VLAN tag, or zero
540
+ * @v iobuf		I/O buffer, or NULL
541
+ * @v rc		Packet status code
542
+ */
543
+void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
544
+			  struct io_buffer *iobuf, int rc ) {
545
+	struct net_device *vlan;
546
+
547
+	/* Identify VLAN device, if applicable */
548
+	if ( tag && ( ( vlan = vlan_find ( netdev, tag ) ) != NULL ) )
549
+		netdev = vlan;
550
+
551
+	/* Hand off to network device */
552
+	netdev_rx_err ( netdev, iobuf, rc );
553
+}

Loading…
Cancel
Save