aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/vlan.c
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2019-04-27 20:12:01 +0100
committerMichael Brown <mcb30@ipxe.org>2019-04-27 20:25:00 +0100
commitfe680c8228563369804948010954128aacb7db74 (patch)
tree65e6035ee970a69550bb44ee2e07d47c1c85d314 /src/net/vlan.c
parentafee77d816f42c7e405c065395c6a7f4dc2aade1 (diff)
downloadipxe-fe680c8228563369804948010954128aacb7db74.tar.gz
[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>
Diffstat (limited to 'src/net/vlan.c')
-rw-r--r--src/net/vlan.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/src/net/vlan.c b/src/net/vlan.c
index f515c2dc9..90f2934de 100644
--- a/src/net/vlan.c
+++ b/src/net/vlan.c
@@ -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 );
+}