datapath: fix a bug in SF_FLOW_KEY_PUT macro
[sliver-openvswitch.git] / datapath / flow.c
index a70b974..7f69538 100644 (file)
@@ -82,8 +82,9 @@ static void update_range__(struct sw_flow_match *match,
        do { \
                update_range__(match, offsetof(struct sw_flow_key, field),  \
                                     sizeof((match)->key->field), is_mask); \
-               if (is_mask && match->mask != NULL) {                       \
-                       (match)->mask->key.field = value;                   \
+               if (is_mask) {                                              \
+                       if ((match)->mask)                                  \
+                               (match)->mask->key.field = value;           \
                } else {                                                    \
                        (match)->key->field = value;                        \
                }                                                           \
@@ -93,8 +94,9 @@ static void update_range__(struct sw_flow_match *match,
        do { \
                update_range__(match, offsetof(struct sw_flow_key, field),  \
                                len, is_mask);                              \
-               if (is_mask && match->mask != NULL) {                       \
-                       memcpy(&(match)->mask->key.field, value_p, len);    \
+               if (is_mask) {                                              \
+                       if ((match)->mask)                                  \
+                               memcpy(&(match)->mask->key.field, value_p, len);\
                } else {                                                    \
                        memcpy(&(match)->key->field, value_p, len);         \
                }                                                           \
@@ -349,9 +351,8 @@ static bool icmp6hdr_ok(struct sk_buff *skb)
                                  sizeof(struct icmp6hdr));
 }
 
-static void flow_key_mask(struct sw_flow_key *dst,
-                         const struct sw_flow_key *src,
-                         const struct sw_flow_mask *mask)
+void ovs_flow_key_mask(struct sw_flow_key *dst, const struct sw_flow_key *src,
+                      const struct sw_flow_mask *mask)
 {
        u8 *m = (u8 *)&mask->key + mask->range.start;
        u8 *s = (u8 *)src + mask->range.start;
@@ -430,7 +431,7 @@ static struct flex_array *alloc_buckets(unsigned int n_buckets)
        struct flex_array *buckets;
        int i, err;
 
-       buckets = flex_array_alloc(sizeof(struct hlist_head *),
+       buckets = flex_array_alloc(sizeof(struct hlist_head),
                                   n_buckets, GFP_KERNEL);
        if (!buckets)
                return NULL;
@@ -490,7 +491,7 @@ static void __flow_tbl_destroy(struct flow_table *table)
                int ver = table->node_ver;
 
                hlist_for_each_entry_safe(flow, n, head, hash_node[ver]) {
-                       hlist_del_rcu(&flow->hash_node[ver]);
+                       hlist_del(&flow->hash_node[ver]);
                        ovs_flow_free(flow, false);
                }
        }
@@ -639,8 +640,7 @@ void ovs_flow_free(struct sw_flow *flow, bool deferred)
        if (!flow)
                return;
 
-       ovs_sw_flow_mask_del_ref((struct sw_flow_mask __force *)flow->mask,
-                                deferred);
+       ovs_sw_flow_mask_del_ref(flow->mask, deferred);
 
        if (deferred)
                call_rcu(&flow->rcu, rcu_free_flow_callback);
@@ -1045,11 +1045,12 @@ static struct sw_flow *ovs_masked_flow_lookup(struct flow_table *table,
        u32 hash;
        struct sw_flow_key masked_key;
 
-       flow_key_mask(&masked_key, flow_key, mask);
+       ovs_flow_key_mask(&masked_key, flow_key, mask);
        hash = ovs_flow_hash(&masked_key, key_start, key_len);
        head = find_bucket(table, hash);
        hlist_for_each_entry_rcu(flow, head, hash_node[table->node_ver]) {
-               if (__flow_cmp_key(flow, &masked_key, key_start, key_len))
+               if (flow->mask == mask &&
+                   __flow_cmp_key(flow, &masked_key, key_start, key_len))
                        return flow;
        }
        return NULL;
@@ -1071,14 +1072,10 @@ struct sw_flow *ovs_flow_lookup(struct flow_table *tbl,
 }
 
 
-void ovs_flow_insert(struct flow_table *table, struct sw_flow *flow,
-                        const struct sw_flow_key *key, int key_len)
+void ovs_flow_insert(struct flow_table *table, struct sw_flow *flow)
 {
-       flow->unmasked_key = *key;
-       flow_key_mask(&flow->key, &flow->unmasked_key, ovsl_dereference(flow->mask));
-       flow->hash = ovs_flow_hash(&flow->key,
-                       ovsl_dereference(flow->mask)->range.start,
-                       ovsl_dereference(flow->mask)->range.end);
+       flow->hash = ovs_flow_hash(&flow->key, flow->mask->range.start,
+                       flow->mask->range.end);
        __tbl_insert(table, flow);
 }
 
@@ -1260,7 +1257,7 @@ int ipv4_tun_from_nlattr(const struct nlattr *attr,
        }
 
        if (!ttl) {
-               OVS_NLERR("IPv4 tunnel TTL is zero.\n");
+               OVS_NLERR("IPv4 tunnel TTL not specified.\n");
                return -EINVAL;
        }