On Mon, Aug 29, 2016 at 11:58:14AM -0700, Jesse Gross wrote:
> When flows are read by ovs-ofctl (either from a switch or a file),
> tunnel metadata space is dynamically allocated since there isn't a
> preset table. This works well for single flows but doesn't handle
> groups of flows that must be compared to each other. In this case,
> each flow will have its own independent allocation making comparisons
> meaningless.
> 
> Even worse is that when these matches are later serialized (either
> for display or in NXM format), the metadata allocation has been
> stripped off of the matches. The serialization code then attempts to
> use the global table, which is also not available, leading to a
> dereference of a NULL pointer.
> 
> Solving this problem requires building an overall metadata table.
> Since we don't know the maximum size of a field (particularly for
> flows read from a file), it's necessary to do this in two passes.
> The first pass records the maximum size for each field as well as
> stores the received matches. The second pass creates a metadata
> table based on the sizes, adjusts the match layout based on the new
> allocation, and then replays the stored matches for comparison.
> Later serialization will used the generated table to output the
> flows.
> 
> Signed-off-by: Jesse Gross <je...@kernel.org>

Good catch.

Acked-by: Ben Pfaff <b...@ovn.org>

Suggested improvements:

--8<--------------------------cut here-------------------------->8--

diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index dbeeebf..803684c 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -3066,16 +3066,14 @@ generate_tun_metadata(struct fte_state *state)
 static void
 remap_match(struct match *match)
 {
-    struct tun_metadata flow, flow_mask;
     int i;
 
     if (!match->tun_md.valid) {
         return;
     }
 
-    memcpy(&flow, &match->flow.tunnel.metadata, sizeof flow);
-    memcpy(&flow_mask, &match->wc.masks.tunnel.metadata, sizeof flow_mask);
-
+    struct tun_metadata flow = match->flow.tunnel.metadata;
+    struct tun_metadata flow_mask = match->wc.masks.tunnel.metadata;
     memset(&match->flow.tunnel.metadata, 0, sizeof 
match->flow.tunnel.metadata);
     memset(&match->wc.masks.tunnel.metadata, 0,
            sizeof match->wc.masks.tunnel.metadata);
@@ -3105,7 +3103,7 @@ remap_match(struct match *match)
  * allocated space. In the case of flows coming from a file, we don't
  * even know the size of each field when we need to do the allocation.
  * When the flows come in, each flow has an individual allocation based
- * on it's own fields. However, this allocation is not the same across
+ * on its own fields. However, this allocation is not the same across
  * different flows and therefore fields are not directly comparable.
  *
  * In the first pass, we record the maximum size of each tunnel metadata
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to