From 44a0d99fcf906b0a6bf0fc7fd92a2cbeb93a6fc8 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 68ac06889..21922a01f 100644 --- a/lib/bond.c +++ b/lib/bond.c @@ -1375,12 +1375,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 b3821e85b..037f43e76 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 f8f8e5dd0..d6b9f6943 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -777,7 +777,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: @@ -787,11 +788,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 f4e930a91..05c70bb5e 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -205,7 +205,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.20.1