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
 				       struct ib_address_vector *source,
3207
 				       struct ib_address_vector *source,
3208
 				       struct io_buffer *iobuf, int rc ) {
3208
 				       struct io_buffer *iobuf, int rc ) {
3209
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
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
 	/* Hand off to network layer */
3215
 	/* Hand off to network layer */
3222
 	if ( rc == 0 ) {
3216
 	if ( rc == 0 ) {
3223
-		netdev_rx ( netdev, iobuf );
3217
+		vlan_netdev_rx ( netdev, tag, iobuf );
3224
 	} else {
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
 
10
 
11
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
12
 
12
 
13
+#include <ipxe/netdevice.h>
14
+
13
 /** A VLAN header */
15
 /** A VLAN header */
14
 struct vlan_header {
16
 struct vlan_header {
15
 	/** Tag control information */
17
 	/** Tag control information */
59
  */
61
  */
60
 #define VLAN_PRIORITY_IS_VALID( priority ) ( (priority) <= 7 )
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
 extern unsigned int vlan_tag ( struct net_device *netdev );
64
 extern unsigned int vlan_tag ( struct net_device *netdev );
65
 extern int vlan_can_be_trunk ( struct net_device *trunk );
65
 extern int vlan_can_be_trunk ( struct net_device *trunk );
66
 extern int vlan_create ( struct net_device *trunk, unsigned int tag,
66
 extern int vlan_create ( struct net_device *trunk, unsigned int tag,
67
 			 unsigned int priority );
67
 			 unsigned int priority );
68
 extern int vlan_destroy ( struct net_device *netdev );
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
 #endif /* _IPXE_VLAN_H */
74
 #endif /* _IPXE_VLAN_H */

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

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
 /** Networking stack process */
1160
 /** Networking stack process */

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

199
  * @v tag		VLAN tag
199
  * @v tag		VLAN tag
200
  * @ret netdev		VLAN device, if any
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
 	struct net_device *netdev;
204
 	struct net_device *netdev;
204
 	struct vlan_device *vlan;
205
 	struct vlan_device *vlan;
205
 
206
 
506
 	.notify = vlan_notify,
507
 	.notify = vlan_notify,
507
 	.remove = vlan_remove,
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