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 );
}
}
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+#include <ipxe/netdevice.h>
+
/** A VLAN header */
struct vlan_header {
/** Tag control information */
*/
#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 */
}
/**
- * 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 */
* @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;
.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 );
+}