packets: Mask out CFI bit in eth_push_vlan().
authorEthan Jackson <ethan@nicira.com>
Tue, 3 Jan 2012 18:42:56 +0000 (10:42 -0800)
committerEthan Jackson <ethan@nicira.com>
Tue, 10 Jan 2012 22:30:01 +0000 (14:30 -0800)
We should never push a VLAN tag with the CFI bit set.  This patch
defensively enforces this invariant.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
lib/dpif-netdev.c
lib/flow.c
lib/packets.c

index 742d00c..4ef2e3b 100644 (file)
@@ -1315,7 +1315,7 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
 
         case OVS_ACTION_ATTR_PUSH_VLAN:
             vlan = nl_attr_get(a);
-            eth_push_vlan(packet, vlan->vlan_tci & ~htons(VLAN_CFI));
+            eth_push_vlan(packet, vlan->vlan_tci);
             break;
 
         case OVS_ACTION_ATTR_POP_VLAN:
index 5d18212..cffb59f 100644 (file)
@@ -995,7 +995,7 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
     }
 
     if (flow->vlan_tci & htons(VLAN_CFI)) {
-        eth_push_vlan(b, flow->vlan_tci & ~htons(VLAN_CFI));
+        eth_push_vlan(b, flow->vlan_tci);
     }
 
     if (flow->dl_type == htons(ETH_TYPE_IP)) {
index b9f37bb..2548174 100644 (file)
@@ -77,7 +77,7 @@ compose_benign_packet(struct ofpbuf *b, const char *tag, uint16_t snap_type,
 }
 
 /* Insert VLAN header according to given TCI. Packet passed must be Ethernet
- * packet.
+ * packet.  Ignores the CFI bit of 'tci' using 0 instead.
  *
  * Also sets 'packet->l2' to point to the new Ethernet header. */
 void
@@ -91,7 +91,7 @@ eth_push_vlan(struct ofpbuf *packet, ovs_be16 tci)
     memcpy(tmp.veth_dst, eh->eth_dst, ETH_ADDR_LEN);
     memcpy(tmp.veth_src, eh->eth_src, ETH_ADDR_LEN);
     tmp.veth_type = htons(ETH_TYPE_VLAN);
-    tmp.veth_tci = tci;
+    tmp.veth_tci = tci & htons(~VLAN_CFI);
     tmp.veth_next_type = eh->eth_type;
 
     veh = ofpbuf_push_uninit(packet, VLAN_HEADER_LEN);