]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[vlan] Provide vlan_netdev_rx() and vlan_netdev_rx_err()
authorMichael Brown <mcb30@ipxe.org>
Sat, 27 Apr 2019 19:12:01 +0000 (20:12 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sat, 27 Apr 2019 19:25:00 +0000 (20:25 +0100)
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>
src/drivers/infiniband/hermon.c
src/include/ipxe/vlan.h
src/net/netdevice.c
src/net/vlan.c

index a1d2a3bd585240a330fac730dd86feafd73fe3f8..9675c156b666f82507b238963b4a17a957a1d7b5 100644 (file)
@@ -3207,22 +3207,16 @@ static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
                                       struct ib_address_vector *source,
                                       struct io_buffer *iobuf, int rc ) {
        struct net_device *netdev = ib_qp_get_ownerdata ( qp );
-       struct net_device *vlan;
-
-       /* Find VLAN device, if applicable */
-       if ( source->vlan_present ) {
-               if ( ( vlan = vlan_find ( netdev, source->vlan ) ) != NULL ) {
-                       netdev = vlan;
-               } else if ( rc == 0 ) {
-                       rc = -ENODEV;
-               }
-       }
+       unsigned int tag;
+
+       /* Identify VLAN tag, if applicable */
+       tag = ( source->vlan_present ? source->vlan : 0 );
 
        /* Hand off to network layer */
        if ( rc == 0 ) {
-               netdev_rx ( netdev, iobuf );
+               vlan_netdev_rx ( netdev, tag, iobuf );
        } else {
-               netdev_rx_err ( netdev, iobuf, rc );
+               vlan_netdev_rx_err ( netdev, tag, iobuf, rc );
        }
 }
 
index 439e0c16d2c2f65f50304118085ffe6fd6f8cad1..7f93439b364e4d0a4e5352e0537138d9b172ca41 100644 (file)
@@ -10,6 +10,8 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
+#include <ipxe/netdevice.h>
+
 /** A VLAN header */
 struct vlan_header {
        /** Tag control information */
@@ -59,12 +61,14 @@ struct vlan_header {
  */
 #define VLAN_PRIORITY_IS_VALID( priority ) ( (priority) <= 7 )
 
-extern struct net_device * vlan_find ( struct net_device *trunk,
-                                      unsigned int tag );
 extern unsigned int vlan_tag ( struct net_device *netdev );
 extern int vlan_can_be_trunk ( struct net_device *trunk );
 extern int vlan_create ( struct net_device *trunk, unsigned int tag,
                         unsigned int priority );
 extern int vlan_destroy ( struct net_device *netdev );
+extern void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
+                            struct io_buffer *iobuf );
+extern void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
+                                struct io_buffer *iobuf, int rc );
 
 #endif /* _IPXE_VLAN_H */
index 71a37eccc900b76828023ae7b3e57bc9a2d33d53..3b02e64bd6647b86333e2dadf4ff708c5d01f45c 100644 (file)
@@ -1126,15 +1126,35 @@ __weak unsigned int vlan_tag ( struct net_device *netdev __unused ) {
 }
 
 /**
- * Identify VLAN device (when VLAN support is not present)
+ * Add VLAN tag-stripped packet to queue (when VLAN support is not present)
  *
- * @v trunk            Trunk network device
- * @v tag              VLAN tag
- * @ret netdev         VLAN device, if any
+ * @v netdev           Network device
+ * @v tag              VLAN tag, or zero
+ * @v iobuf            I/O buffer
  */
-__weak struct net_device * vlan_find ( struct net_device *trunk __unused,
-                                      unsigned int tag __unused ) {
-       return NULL;
+__weak void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
+                            struct io_buffer *iobuf ) {
+
+       if ( tag == 0 ) {
+               netdev_rx ( netdev, iobuf );
+       } else {
+               netdev_rx_err ( netdev, iobuf, -ENODEV );
+       }
+}
+
+/**
+ * Discard received VLAN tag-stripped packet (when VLAN support is not present)
+ *
+ * @v netdev           Network device
+ * @v tag              VLAN tag, or zero
+ * @v iobuf            I/O buffer, or NULL
+ * @v rc               Packet status code
+ */
+__weak void vlan_netdev_rx_err ( struct net_device *netdev,
+                                unsigned int tag __unused,
+                                struct io_buffer *iobuf, int rc ) {
+
+       netdev_rx_err ( netdev, iobuf, rc );
 }
 
 /** Networking stack process */
index f515c2dc917365197e3fe40aba639bc4c0fe256a..90f2934dec9f144a850fcf33b0fc2b8dd3dfbd15 100644 (file)
@@ -199,7 +199,8 @@ static void vlan_sync ( struct net_device *netdev ) {
  * @v tag              VLAN tag
  * @ret netdev         VLAN device, if any
  */
-struct net_device * vlan_find ( struct net_device *trunk, unsigned int tag ) {
+static struct net_device * vlan_find ( struct net_device *trunk,
+                                      unsigned int tag ) {
        struct net_device *netdev;
        struct vlan_device *vlan;
 
@@ -506,3 +507,47 @@ struct net_driver vlan_driver __net_driver = {
        .notify = vlan_notify,
        .remove = vlan_remove,
 };
+
+/**
+ * Add VLAN tag-stripped packet to receive queue
+ *
+ * @v netdev           Network device
+ * @v tag              VLAN tag, or zero
+ * @v iobuf            I/O buffer
+ */
+void vlan_netdev_rx ( struct net_device *netdev, unsigned int tag,
+                     struct io_buffer *iobuf ) {
+       struct net_device *vlan;
+
+       /* Identify VLAN device, if applicable */
+       if ( tag ) {
+               if ( ( vlan = vlan_find ( netdev, tag ) ) == NULL ) {
+                       netdev_rx_err ( netdev, iobuf, -ENODEV );
+                       return;
+               }
+               netdev = vlan;
+       }
+
+       /* Hand off to network device */
+       netdev_rx ( netdev, iobuf );
+}
+
+/**
+ * Discard received VLAN tag-stripped packet
+ *
+ * @v netdev           Network device
+ * @v tag              VLAN tag, or zero
+ * @v iobuf            I/O buffer, or NULL
+ * @v rc               Packet status code
+ */
+void vlan_netdev_rx_err ( struct net_device *netdev, unsigned int tag,
+                         struct io_buffer *iobuf, int rc ) {
+       struct net_device *vlan;
+
+       /* Identify VLAN device, if applicable */
+       if ( tag && ( ( vlan = vlan_find ( netdev, tag ) ) != NULL ) )
+               netdev = vlan;
+
+       /* Hand off to network device */
+       netdev_rx_err ( netdev, iobuf, rc );
+}