From 142181fcd734a2afff9fe13e54fe51c7a2c824d2 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 27 Jul 2010 17:00:54 -0700 Subject: [PATCH] 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. --- lib/dpif-netdev.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index ec971b13..c17b5257 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -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: -- 2.30.2