On Mon, Aug 11, 2014 at 09:15:00AM -0700, Jarno Rajahalme wrote: > Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
The amount of redundancy in the code at this point is starting to give me a headache. How about a pattern like this (provided as an incremental)? diff --git a/lib/odp-util.c b/lib/odp-util.c index b9b6e2a..b4ea27f 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -3649,47 +3649,62 @@ commit_odp_tunnel_action(const struct flow *flow, struct flow *base, } } -static void -commit_set_ether_addr_action(const struct flow *flow, struct flow *base, - struct ofpbuf *odp_actions, - struct flow_wildcards *wc, - bool use_masked) +static bool +commit(enum ovs_key_attr attr, bool use_masked_set, + const void *key, void *base, void *mask, size_t size, + struct ofpbuf *odp_actions) { - struct ovs_key_ethernet key, mask; - bool fully_masked; - - /* Mask bits are set when we have either read or set the corresponding - * values. Masked bits will be exact-matched, no need to set them - * if the value did not actually change. */ - if (eth_addr_equals(flow->dl_src, base->dl_src) && - eth_addr_equals(flow->dl_dst, base->dl_dst)) { - return; + if (memcmp(key, base, size)) { + bool fully_masked = is_all_ones(mask, size); + if (use_masked_set && !fully_masked) { + commit_masked_set_action(odp_actions, attr, key, mask, size); + } else { + if (!fully_masked) { + memset(mask, 0xff, size); + } + commit_set_action(odp_actions, attr, key, size); + } + memcpy(base, key, size); + return true; + } else { + /* Mask bits are set when we have either read or set the corresponding + * values. Masked bits will be exact-matched, no need to set them + * if the value did not actually change. */ + return false; } +} - memcpy(key.eth_src, flow->dl_src, ETH_ADDR_LEN); - memcpy(key.eth_dst, flow->dl_dst, ETH_ADDR_LEN); +static void +get_ethernet_key(const struct flow *flow, struct ovs_key_ethernet *eth) +{ + memcpy(eth->eth_src, flow->dl_src, ETH_ADDR_LEN); + memcpy(eth->eth_dst, flow->dl_dst, ETH_ADDR_LEN); +} - fully_masked = eth_mask_is_exact(wc->masks.dl_src) - && eth_mask_is_exact(wc->masks.dl_dst); +static void +put_ethernet_key(const struct ovs_key_ethernet *eth, struct flow *flow) +{ + memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN); + memcpy(flow->dl_dst, eth->eth_dst, ETH_ADDR_LEN); +} - if (use_masked && !fully_masked) { - memcpy(mask.eth_src, wc->masks.dl_src, ETH_ADDR_LEN); - memcpy(mask.eth_dst, wc->masks.dl_dst, ETH_ADDR_LEN); +static void +commit_set_ether_addr_action(const struct flow *flow, struct flow *base_flow, + struct ofpbuf *odp_actions, + struct flow_wildcards *wc, + bool use_masked) +{ + struct ovs_key_ethernet key, base, mask; - commit_masked_set_action(odp_actions, OVS_KEY_ATTR_ETHERNET, &key, - &mask, sizeof key); - } else { - if (!fully_masked) { - memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src); - memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst); - } + get_ethernet_key(flow, &key); + get_ethernet_key(base_flow, &base); + get_ethernet_key(&wc->masks, &mask); - commit_set_action(odp_actions, OVS_KEY_ATTR_ETHERNET, &key, - sizeof key); + if (commit(OVS_KEY_ATTR_ETHERNET, use_masked, + &key, &base, &mask, sizeof key, odp_actions)) { + put_ethernet_key(&base, base_flow); + put_ethernet_key(&mask, &wc->masks); } - - memcpy(base->dl_src, flow->dl_src, ETH_ADDR_LEN); - memcpy(base->dl_dst, flow->dl_dst, ETH_ADDR_LEN); } static void @@ -3791,61 +3806,52 @@ commit_mpls_action(const struct flow *flow, struct flow *base, } static void -commit_set_ipv4_action(const struct flow *flow, struct flow *base, - struct ofpbuf *odp_actions, struct flow_wildcards *wc, - bool use_masked) +get_ipv4_key(const struct flow *flow, struct ovs_key_ipv4 *ipv4) { - struct ovs_key_ipv4 key, mask; - - /* Check that non-masked bits are intact, and that nw_proto and nw_frag - * remain unchanged. */ - ovs_assert(!((flow->nw_src ^ base->nw_src) & ~wc->masks.nw_src) - && !((flow->nw_dst ^ base->nw_dst) & ~wc->masks.nw_dst) - && !((flow->nw_tos ^ base->nw_tos) & ~wc->masks.nw_tos) - && !((flow->nw_ttl ^ base->nw_ttl) & ~wc->masks.nw_ttl) - && flow->nw_proto == base->nw_proto - && flow->nw_frag == base->nw_frag); + ipv4->ipv4_src = flow->nw_src; + ipv4->ipv4_dst = flow->nw_dst; + ipv4->ipv4_proto = flow->nw_proto; + ipv4->ipv4_tos = flow->nw_tos; + ipv4->ipv4_ttl = flow->nw_ttl; + ipv4->ipv4_frag = ovs_to_odp_frag(flow->nw_frag); +} - /* Mask bits are set when we have either read or set the corresponding - * values. Masked bits will be exact-matched, no need to set them - * if the value did not actually change. */ - if ((flow->nw_src == base->nw_src) && (flow->nw_dst == base->nw_dst) && - (flow->nw_tos == base->nw_tos) && (flow->nw_ttl == base->nw_ttl)) { - return; +static void +put_ipv4_key(const struct ovs_key_ipv4 *ipv4, struct flow *flow) +{ + flow->nw_src = ipv4->ipv4_src; + flow->nw_dst = ipv4->ipv4_dst; + flow->nw_proto = ipv4->ipv4_proto; + flow->nw_tos = ipv4->ipv4_tos; + flow->nw_ttl = ipv4->ipv4_ttl; + if (ipv4->ipv4_frag == 0xff) { + flow->nw_frag = 0xff; + } else { + odp_to_ovs_frag(ipv4->ipv4_frag, flow); } +} + +static void +commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow, + struct ofpbuf *odp_actions, struct flow_wildcards *wc, + bool use_masked) +{ + struct ovs_key_ipv4 key, mask, base; - key.ipv4_src = flow->nw_src; - key.ipv4_dst = flow->nw_dst; - key.ipv4_tos = flow->nw_tos; - key.ipv4_ttl = flow->nw_ttl; - key.ipv4_proto = base->nw_proto; - key.ipv4_frag = ovs_to_odp_frag(base->nw_frag); + /* Check that nw_proto and nw_frag remain unchanged. */ + ovs_assert(flow->nw_proto == base_flow->nw_proto && + flow->nw_frag == base_flow->nw_frag); - if (use_masked) { - mask.ipv4_src = wc->masks.nw_src; - mask.ipv4_dst = wc->masks.nw_dst; - mask.ipv4_tos = wc->masks.nw_tos; - mask.ipv4_ttl = wc->masks.nw_ttl; - mask.ipv4_proto = 0; /* Not writeable. */ - mask.ipv4_frag = 0; /* Not writeable. */ - - commit_masked_set_action(odp_actions, OVS_KEY_ATTR_IPV4, &key, &mask, - sizeof key); - } else { - 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.nw_tos, 0xff, sizeof wc->masks.nw_tos); - memset(&wc->masks.nw_ttl, 0xff, sizeof wc->masks.nw_ttl); - memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); - memset(&wc->masks.nw_frag, 0xff, sizeof wc->masks.nw_frag); + get_ipv4_key(flow, &key); + get_ipv4_key(base_flow, &base); + get_ipv4_key(&wc->masks, &mask); + mask.ipv4_frag = 0; /* Not writable. */ - commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4, &key, sizeof key); + if (commit(OVS_KEY_ATTR_IPV4, use_masked, &key, &base, &mask, sizeof key, + odp_actions)) { + put_ipv4_key(&base, base_flow); + put_ipv4_key(&mask, &wc->masks); } - - base->nw_src = flow->nw_src; - base->nw_dst = flow->nw_dst; - base->nw_tos = flow->nw_tos; - base->nw_ttl = flow->nw_ttl; } static void _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev