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 a755947..d207bfa 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 e146dbb..5a35335 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)