diff options
-rw-r--r-- | net/openvswitch/datapath.c | 2 | ||||
-rw-r--r-- | net/openvswitch/flow.c | 21 | ||||
-rw-r--r-- | net/openvswitch/flow.h | 2 |
3 files changed, 14 insertions, 11 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 2aa13bd7f2b2..aa0a5f2794f1 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1266,7 +1266,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(acts)) goto error; - ovs_flow_key_mask(&masked_key, &key, &mask); + ovs_flow_key_mask(&masked_key, &key, true, &mask); error = validate_and_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &masked_key, 0, &acts); if (error) { diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 410db90db73d..b5d58cfa4fdc 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -373,18 +373,21 @@ static bool icmp6hdr_ok(struct sk_buff *skb) } void ovs_flow_key_mask(struct sw_flow_key *dst, const struct sw_flow_key *src, - const struct sw_flow_mask *mask) + bool full, const struct sw_flow_mask *mask) { - const long *m = (long *)((u8 *)&mask->key + mask->range.start); - const long *s = (long *)((u8 *)src + mask->range.start); - long *d = (long *)((u8 *)dst + mask->range.start); + int start = full ? 0 : mask->range.start; + int len = full ? sizeof *dst : range_n_bytes(&mask->range); + const long *m = (const long *)((const u8 *)&mask->key + start); + const long *s = (const long *)((const u8 *)src + start); + long *d = (long *)((u8 *)dst + start); int i; - /* The memory outside of the 'mask->range' are not set since - * further operations on 'dst' only uses contents within - * 'mask->range'. + /* If 'full' is true then all of 'dst' is fully initialized. Otherwise, + * if 'full' is false the memory outside of the 'mask->range' is left + * uninitialized. This can be used as an optimization when further + * operations on 'dst' only use contents within 'mask->range'. */ - for (i = 0; i < range_n_bytes(&mask->range); i += sizeof(long)) + for (i = 0; i < len; i += sizeof(long)) *d++ = *s++ & *m++; } @@ -1085,7 +1088,7 @@ static struct sw_flow *ovs_masked_flow_lookup(struct flow_table *table, u32 hash; struct sw_flow_key masked_key; - ovs_flow_key_mask(&masked_key, unmasked, mask); + ovs_flow_key_mask(&masked_key, unmasked, false, mask); hash = ovs_flow_hash(&masked_key, key_start, key_end); head = find_bucket(table, hash); hlist_for_each_entry_rcu(flow, head, hash_node[table->node_ver]) { diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 212fbf7510c4..a5da8e1ab854 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -255,5 +255,5 @@ void ovs_sw_flow_mask_insert(struct flow_table *, struct sw_flow_mask *); struct sw_flow_mask *ovs_sw_flow_mask_find(const struct flow_table *, const struct sw_flow_mask *); void ovs_flow_key_mask(struct sw_flow_key *dst, const struct sw_flow_key *src, - const struct sw_flow_mask *mask); + bool full, const struct sw_flow_mask *mask); #endif /* flow.h */ |