mirror of https://gitee.com/openkylin/ipxe.git
Strip 802.1Q VLAN 0 priority tags iPXE was unable to receive priority tagged packets specified in the 802.1Q standard and supported by all major networking stacks. This commit adds a new function net_pull_tags which is called by all consumers of incoming packets after stripping their link-layer headers.
Origin: vendor, https://git.centos.org/blob/rpms!ipxe.git/c7/SOURCES!0009-Strip-802.1Q-VLAN-0-priority-tags.patch Bug-Ubuntu: https://bugs.launchpad.net/bugs/1805920 Gbp-Pq: Name 0005-strip-802.1Q-VLAN-0-priority-tags.patch
This commit is contained in:
parent
d427549178
commit
ec7ca7fdea
|
@ -976,6 +976,12 @@ static PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
|
||||||
}
|
}
|
||||||
ll_hlen = ( len - iob_len ( iobuf ) );
|
ll_hlen = ( len - iob_len ( iobuf ) );
|
||||||
|
|
||||||
|
/* Strip link-layer-independent headers */
|
||||||
|
if ( ( rc = net_pull_tags ( iobuf, pxe_netdev, &net_proto ) ) != 0 ) {
|
||||||
|
/* Assume unknown net_proto */
|
||||||
|
net_proto = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine network-layer protocol */
|
/* Determine network-layer protocol */
|
||||||
switch ( net_proto ) {
|
switch ( net_proto ) {
|
||||||
case htons ( ETH_P_IP ):
|
case htons ( ETH_P_IP ):
|
||||||
|
|
|
@ -726,6 +726,8 @@ extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
uint16_t net_proto, const void *ll_dest,
|
uint16_t net_proto, const void *ll_dest,
|
||||||
const void *ll_source, unsigned int flags );
|
const void *ll_source, unsigned int flags );
|
||||||
|
extern int net_pull_tags ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
|
uint16_t *net_proto );
|
||||||
extern void net_poll ( void );
|
extern void net_poll ( void );
|
||||||
extern struct net_device_configurator *
|
extern struct net_device_configurator *
|
||||||
find_netdev_configurator ( const char *name );
|
find_netdev_configurator ( const char *name );
|
||||||
|
|
|
@ -813,6 +813,13 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
|
||||||
goto out_bad_ll_header;
|
goto out_bad_ll_header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Strip link-layer-independent headers */
|
||||||
|
if ( ( rc = net_pull_tags ( iobuf, snpdev->netdev, &iob_net_proto ) ) ) {
|
||||||
|
DBGC ( snpdev, "SNPDEV %p could not parse tags: %s\n",
|
||||||
|
snpdev, strerror ( rc ) );
|
||||||
|
goto out_bad_ll_header;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return link-layer header parameters to caller, if required */
|
/* Return link-layer header parameters to caller, if required */
|
||||||
if ( ll_header_len )
|
if ( ll_header_len )
|
||||||
*ll_header_len = ll_protocol->ll_header_len;
|
*ll_header_len = ll_protocol->ll_header_len;
|
||||||
|
|
|
@ -1043,6 +1043,44 @@ int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip extra link-layer-independent tags from a received packet
|
||||||
|
*
|
||||||
|
* @v iobuf I/O buffer
|
||||||
|
* @v netdev Network device
|
||||||
|
* @v net_proto Network-layer protocol, in network-byte order
|
||||||
|
* @ret rc Return status code
|
||||||
|
*
|
||||||
|
* This function should be called after stripping link-layer headers but
|
||||||
|
* before inspecting the network-layer protocol.
|
||||||
|
*/
|
||||||
|
int net_pull_tags ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
|
uint16_t *net_proto ) {
|
||||||
|
struct vlan_header *vlanhdr;
|
||||||
|
uint16_t tag;
|
||||||
|
|
||||||
|
/* Strip 802.1Q VLAN 0 priority tags if present */
|
||||||
|
while ( *net_proto == htons ( ETH_P_8021Q ) ) {
|
||||||
|
if ( iob_len ( iobuf ) < sizeof ( *vlanhdr ) ) {
|
||||||
|
DBG ( "VLAN header too short at %zd bytes (min %zd bytes)\n",
|
||||||
|
iob_len ( iobuf ), sizeof ( *vlanhdr ) );
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
vlanhdr = ( struct vlan_header * ) iobuf->data;
|
||||||
|
tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
|
||||||
|
|
||||||
|
if ( tag == 0 && ! vlan_find ( netdev, tag ) ) {
|
||||||
|
/* VLAN 0, strip and continue */
|
||||||
|
*net_proto = vlanhdr->net_proto;
|
||||||
|
iob_pull ( iobuf, sizeof ( *vlanhdr ) );
|
||||||
|
} else {
|
||||||
|
/* Real VLAN tag, leave it alone */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Poll the network stack
|
* Poll the network stack
|
||||||
*
|
*
|
||||||
|
@ -1094,6 +1132,12 @@ void net_poll ( void ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove link-layer-independent headers */
|
||||||
|
if ( ( rc = net_pull_tags ( iobuf, netdev, &net_proto ) ) ) {
|
||||||
|
free_iob ( iobuf );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Hand packet to network layer */
|
/* Hand packet to network layer */
|
||||||
if ( ( rc = net_rx ( iob_disown ( iobuf ), netdev,
|
if ( ( rc = net_rx ( iob_disown ( iobuf ), netdev,
|
||||||
net_proto, ll_dest,
|
net_proto, ll_dest,
|
||||||
|
|
Loading…
Reference in New Issue