datapath: Allow TCP flags to be cleared.
authorJesse Gross <jesse@nicira.com>
Wed, 28 Oct 2009 21:36:52 +0000 (14:36 -0700)
committerJesse Gross <jesse@nicira.com>
Tue, 3 Nov 2009 00:12:21 +0000 (16:12 -0800)
When querying flow stats allow the TCP flags to be reset.  Since
the datapath ORs together all flags that have previously been
seen it is otherwise impossible to determine the set of flags from
after a particular time.

datapath/datapath.c
include/openvswitch/datapath-protocol.h

index 811b4ee996ba0b3f7c1223844b601f9f2a064a10..1b5f57f8b2d67d19e2d8b01b7d7e673bd7d79445 100644 (file)
@@ -978,13 +978,18 @@ static int put_actions(const struct sw_flow *flow, struct odp_flow __user *ufp)
        return 0;
 }
 
-static int answer_query(struct sw_flow *flow, struct odp_flow __user *ufp)
+static int answer_query(struct sw_flow *flow, u32 query_flags,
+                       struct odp_flow __user *ufp)
 {
        struct odp_flow_stats stats;
        unsigned long int flags;
 
        spin_lock_irqsave(&flow->lock, flags);
        get_stats(flow, &stats);
+
+       if (query_flags & ODPFF_ZERO_TCP_FLAGS) {
+               flow->tcp_flags = 0;
+       }
        spin_unlock_irqrestore(&flow->lock, flags);
 
        if (__copy_to_user(&ufp->stats, &stats, sizeof(struct odp_flow_stats)))
@@ -1022,10 +1027,10 @@ static int del_or_query_flow(struct datapath *dp,
                 * to make sure that we get completely accurate stats, but that
                 * blows our performance, badly. */
                dp->n_flows--;
-               error = answer_query(flow, ufp);
+               error = answer_query(flow, 0, ufp);
                flow_deferred_free(flow);
        } else {
-               error = answer_query(flow, ufp);
+               error = answer_query(flow, uf.flags, ufp);
        }
 
 error:
@@ -1051,7 +1056,7 @@ static int query_multiple_flows(struct datapath *dp,
                if (!flow)
                        error = __clear_user(&ufp->stats, sizeof ufp->stats);
                else
-                       error = answer_query(flow, ufp);
+                       error = answer_query(flow, 0, ufp);
                if (error)
                        return -EFAULT;
        }
@@ -1072,7 +1077,7 @@ static int list_flow(struct sw_flow *flow, void *cbdata_)
 
        if (__copy_to_user(&ufp->key, &flow->key, sizeof flow->key))
                return -EFAULT;
-       error = answer_query(flow, ufp);
+       error = answer_query(flow, 0, ufp);
        if (error)
                return error;
 
index bbc29f6d0e55753e560894a937c8952f211ef1c2..a532d71192e103c2e6b4f9f8e3a94667121ebbc9 100644 (file)
@@ -167,11 +167,15 @@ struct odp_flow_key {
     __u8   reserved;             /* Pad to 64 bits. */
 };
 
+/* Flags for ODP_FLOW. */
+#define ODPFF_ZERO_TCP_FLAGS (1 << 0) /* Zero the TCP flags. */
+
 struct odp_flow {
     struct odp_flow_stats stats;
     struct odp_flow_key key;
     union odp_action *actions;
     __u32 n_actions;
+    __u32 flags;
 };
 
 /* Flags for ODP_FLOW_PUT. */