mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 22:05:19 +00:00
dpif-netdev: Properly track whether there is a vlan header.
It looks to me like the current dpif-netdev implementation doesn't handle the case where a packet comes in without a VLAN and then is subjected to multiple ODPAT_SET_VLAN_* operations. dp_netdev_modify_vlan_tci() just checks the flow key each time to see whether there's a VLAN, but it doesn't update the flow key to note that there is now a VLAN. One fix would be to update the flow key, but it's "const" these days. Instead, add a check for whether the Ethernet type is ETH_TYPE_VLAN, which should be equivalent.
This commit is contained in:
@@ -1090,12 +1090,14 @@ dp_netdev_wait(void)
|
||||
* bits outside of 'mask'.
|
||||
*/
|
||||
static void
|
||||
dp_netdev_modify_vlan_tci(struct ofpbuf *packet, const flow_t *key,
|
||||
uint16_t tci, uint16_t mask)
|
||||
dp_netdev_modify_vlan_tci(struct ofpbuf *packet, uint16_t tci, uint16_t mask)
|
||||
{
|
||||
struct vlan_eth_header *veh;
|
||||
struct eth_header *eh;
|
||||
|
||||
if (key->dl_vlan != htons(ODP_VLAN_NONE)) {
|
||||
eh = packet->l2;
|
||||
if (packet->size >= sizeof(struct vlan_eth_header)
|
||||
&& eh->eth_type == htons(ETH_TYPE_VLAN)) {
|
||||
/* Clear 'mask' bits, but maintain other TCI bits. */
|
||||
veh = packet->l2;
|
||||
veh->veth_tci &= ~htons(mask);
|
||||
@@ -1292,14 +1294,14 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
|
||||
break;
|
||||
|
||||
case ODPAT_SET_VLAN_VID:
|
||||
dp_netdev_modify_vlan_tci(packet, key, ntohs(a->vlan_vid.vlan_vid),
|
||||
dp_netdev_modify_vlan_tci(packet, ntohs(a->vlan_vid.vlan_vid),
|
||||
VLAN_VID_MASK);
|
||||
break;
|
||||
|
||||
case ODPAT_SET_VLAN_PCP:
|
||||
dp_netdev_modify_vlan_tci(
|
||||
packet, key, a->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT,
|
||||
VLAN_PCP_MASK);
|
||||
dp_netdev_modify_vlan_tci(packet,
|
||||
a->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT,
|
||||
VLAN_PCP_MASK);
|
||||
break;
|
||||
|
||||
case ODPAT_STRIP_VLAN:
|
||||
|
Reference in New Issue
Block a user