From 6cdd514560e16a294d09aa9d6bf5c8c7ac31e442 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Wed, 26 Jun 2013 16:37:16 -0700 Subject: [PATCH] flow: Only un-wildcard relevant IP headers. When determining the fields to un-wildcard, we need to be careful about only un-wildcarding fields that are relevant. Also, we didn't properly handle IPv6 addresses. Signed-off-by: Justin Pettit Acked-by: Ethan Jackson --- lib/bond.c | 4 ++-- lib/bundle.c | 2 +- lib/flow.c | 20 ++++++++++++++------ lib/flow.h | 3 ++- lib/multipath.c | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/bond.c b/lib/bond.c index 198db0f2b..183c37be1 100644 --- a/lib/bond.c +++ b/lib/bond.c @@ -1397,12 +1397,12 @@ choose_output_slave(const struct bond *bond, const struct flow *flow, return NULL; } if (wc) { - flow_mask_hash_fields(wc, NX_HASH_FIELDS_SYMMETRIC_L4); + flow_mask_hash_fields(flow, wc, NX_HASH_FIELDS_SYMMETRIC_L4); } /* Fall Through. */ case BM_SLB: if (wc) { - flow_mask_hash_fields(wc, NX_HASH_FIELDS_ETH_SRC); + flow_mask_hash_fields(flow, wc, NX_HASH_FIELDS_ETH_SRC); } e = lookup_bond_entry(bond, flow, vlan); if (!e->slave || !e->slave->enabled) { diff --git a/lib/bundle.c b/lib/bundle.c index d1834d0e9..78a297a78 100644 --- a/lib/bundle.c +++ b/lib/bundle.c @@ -60,7 +60,7 @@ execute_hrw(const struct ofpact_bundle *bundle, int best, i; if (bundle->n_slaves > 1) { - flow_mask_hash_fields(wc, bundle->fields); + flow_mask_hash_fields(flow, wc, bundle->fields); } flow_hash = flow_hash_fields(flow, bundle->fields, bundle->basis); diff --git a/lib/flow.c b/lib/flow.c index a42fea1e3..1a5084b60 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -781,7 +781,8 @@ flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis) /* Masks the fields in 'wc' that are used by the flow hash 'fields'. */ void -flow_mask_hash_fields(struct flow_wildcards *wc, enum nx_hash_fields fields) +flow_mask_hash_fields(const struct flow *flow, struct flow_wildcards *wc, + enum nx_hash_fields fields) { switch (fields) { case NX_HASH_FIELDS_ETH_SRC: @@ -791,11 +792,18 @@ flow_mask_hash_fields(struct flow_wildcards *wc, enum nx_hash_fields fields) case NX_HASH_FIELDS_SYMMETRIC_L4: memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src); memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst); - memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); - memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); - memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); - memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); - memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); + if (flow->dl_type == htons(ETH_TYPE_IP)) { + memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); + memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); + } else { + memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src); + memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst); + } + if (is_ip_any(flow)) { + memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); + memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); + memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); + } wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI); break; diff --git a/lib/flow.h b/lib/flow.h index 9a6e93781..7c3654b00 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -262,7 +262,8 @@ bool flow_wildcards_equal(const struct flow_wildcards *, const struct flow_wildcards *); uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis); -void flow_mask_hash_fields(struct flow_wildcards *, enum nx_hash_fields); +void flow_mask_hash_fields(const struct flow *, struct flow_wildcards *, + enum nx_hash_fields); uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields, uint16_t basis); const char *flow_hash_fields_to_str(enum nx_hash_fields); diff --git a/lib/multipath.c b/lib/multipath.c index dbd570446..1be69646f 100644 --- a/lib/multipath.c +++ b/lib/multipath.c @@ -113,7 +113,7 @@ multipath_execute(const struct ofpact_multipath *mp, struct flow *flow, uint16_t link = multipath_algorithm(hash, mp->algorithm, mp->max_link + 1, mp->arg); - flow_mask_hash_fields(wc, mp->fields); + flow_mask_hash_fields(flow, wc, mp->fields); nxm_reg_load(&mp->dst, link, flow); } -- 2.43.0