Zero-out invalid fields when extracting a "match" and transforming it into a "flow".
authorJustin Pettit <jpettit@nicira.com>
Fri, 9 May 2008 18:22:45 +0000 (11:22 -0700)
committerJustin Pettit <jpettit@nicira.com>
Fri, 9 May 2008 18:24:04 +0000 (11:24 -0700)
When the controller wishes to add a flow entry to the switch, it sends a request with a description of matching flows in a "match".  The switch was adding these exactly as described into the flow tables.  However, when packets arrived, all invalid fields (e.g., the TCP/UDP ports in a non-TCP/UDP packet) are set to zero.  If the rule being added by the controller had not set these invalid fields to zero, the packets would never match.  We now zero out these fields when extracing a "match".

-- Reported by Brandon H. --

datapath/flow.c
switch/switch-flow.c

index a755947bf2b31b1e590d4aec615aa07ce3f96dd0..d207bfa3fce79110fb46a526fbc0d6965f5292c6 100644 (file)
@@ -67,17 +67,38 @@ int flow_del_matches(const struct sw_flow_key *t, const struct sw_flow_key *d, i
 void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from)
 {
        to->wildcards = ntohs(from->wildcards) & OFPFW_ALL;
-       to->in_port   = from->in_port;
-       to->dl_vlan   = from->dl_vlan;
+       memset(to->pad, '\0', sizeof(to->pad));
+       to->in_port = from->in_port;
+       to->dl_vlan = from->dl_vlan;
        memcpy(to->dl_src, from->dl_src, ETH_ALEN);
        memcpy(to->dl_dst, from->dl_dst, ETH_ALEN);
-       to->dl_type   = from->dl_type;
-       to->nw_src        = from->nw_src;
-       to->nw_dst        = from->nw_dst;
-       to->nw_proto  = from->nw_proto;
-       to->tp_src        = from->tp_src;
-       to->tp_dst        = from->tp_dst;
-       memset(to->pad, '\0', sizeof(to->pad));
+       to->dl_type = from->dl_type;
+
+       if (likely(from->dl_type == htons(ETH_P_IP))) {
+               to->nw_src   = from->nw_src;
+               to->nw_dst   = from->nw_dst;
+               to->nw_proto = from->nw_proto;
+
+               if ((from->nw_proto != IPPROTO_TCP && from->nw_proto != IPPROTO_UDP)) {
+                       goto no_th;
+               }
+               to->tp_src = from->tp_src;
+               to->tp_dst = from->tp_dst;
+               return;
+       } else if (from->dl_type == htons(ETH_P_ARP)) {
+               to->nw_src = from->nw_src;
+               to->nw_dst = from->nw_dst;
+               to->nw_proto = 0;
+               goto no_th;
+       }
+
+       to->nw_src = 0;
+       to->nw_dst = 0;
+       to->nw_proto = 0;
+
+no_th:
+       to->tp_src = 0;
+       to->tp_dst = 0;
 }
 
 void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from)
index e146dbbbc83acb94840b31f5a136ecddb848306f..5a3533515a59936273856882b272593670ebce74 100644 (file)
@@ -81,17 +81,39 @@ int flow_del_matches(const struct sw_flow_key *t, const struct sw_flow_key *d, i
 void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from)
 {
     to->wildcards = ntohs(from->wildcards) & OFPFW_ALL;
-    to->flow.in_port   = from->in_port;
-    to->flow.dl_vlan   = from->dl_vlan;
+    to->flow.reserved = 0;
+    to->flow.in_port = from->in_port;
+    to->flow.dl_vlan = from->dl_vlan;
     memcpy(to->flow.dl_src, from->dl_src, ETH_ADDR_LEN);
     memcpy(to->flow.dl_dst, from->dl_dst, ETH_ADDR_LEN);
-    to->flow.dl_type   = from->dl_type;
-    to->flow.nw_src   = from->nw_src;
-    to->flow.nw_dst   = from->nw_dst;
-    to->flow.nw_proto  = from->nw_proto;
-    to->flow.tp_src   = from->tp_src;
-    to->flow.tp_dst   = from->tp_dst;
-    to->flow.reserved = 0;
+    to->flow.dl_type = from->dl_type;
+
+
+    if (from->dl_type == htons(ETH_TYPE_IP)) {
+        to->flow.nw_src   = from->nw_src;
+        to->flow.nw_dst   = from->nw_dst;
+        to->flow.nw_proto = from->nw_proto;
+
+        if ((from->nw_proto != IPPROTO_TCP && from->nw_proto != IPPROTO_UDP)) {
+            goto no_th;
+        }
+        to->flow.tp_src = from->tp_src;
+        to->flow.tp_dst = from->tp_dst;
+        return;
+    } else if (from->dl_type == htons(ETH_TYPE_ARP)) {
+        to->flow.nw_src = from->nw_src;
+        to->flow.nw_dst = from->nw_dst;
+        to->flow.nw_proto = 0;
+        goto no_th;
+    }
+
+    to->flow.nw_src = 0;
+    to->flow.nw_dst = 0;
+    to->flow.nw_proto = 0;
+
+no_th:
+    to->flow.tp_src = 0;
+    to->flow.tp_dst = 0;
 }
 
 void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from)