From: Guolin Yang Date: Fri, 30 Aug 2013 16:57:13 +0000 (-0700) Subject: Fix a bug in conversion between flow/mask and flow key X-Git-Tag: sliver-openvswitch-2.0.90-1~16^2~41 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=6f8dbd272a7d1b4a0f5d8cd58467c162ae65135e;p=sliver-openvswitch.git Fix a bug in conversion between flow/mask and flow key In odp_flow_key_from_flow__(), when converting ICMPv6 flow/mask to flow/mask key, we should always use flow to check for whether ND informaition is present or not. In mask case, both type and code field should be masked, otherwise ND fields can be masked. Similarly in reverse conversion (parse_l2_5_onward()), we should have same check. Signed-off-by: Guolin Yang [blp@nicira.com changed && to || in parse_l2_5_onward() Signed-off-by: Ben Pfaff Acked-by: Andy Zhou --- diff --git a/lib/odp-util.c b/lib/odp-util.c index 15ad2be10..f20bd8a2c 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -2553,8 +2553,12 @@ odp_flow_key_from_flow__(struct ofpbuf *buf, const struct flow *data, icmpv6_key->icmpv6_type = ntohs(data->tp_src); icmpv6_key->icmpv6_code = ntohs(data->tp_dst); - if (icmpv6_key->icmpv6_type == ND_NEIGHBOR_SOLICIT - || icmpv6_key->icmpv6_type == ND_NEIGHBOR_ADVERT) { + if (flow->tp_dst == htons(0) && + (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || + flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) && + (!is_mask || (data->tp_src == htons(0xffff) && + data->tp_dst == htons(0xffff)))) { + struct ovs_key_nd *nd_key; nd_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ND, @@ -2965,8 +2969,9 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1], flow->tp_src = htons(icmpv6_key->icmpv6_type); flow->tp_dst = htons(icmpv6_key->icmpv6_code); expected_bit = OVS_KEY_ATTR_ICMPV6; - if (src_flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || - src_flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + if (src_flow->tp_dst == htons(0) && + (src_flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || + src_flow->tp_src == htons(ND_NEIGHBOR_ADVERT))) { if (!is_mask) { expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND; } @@ -2981,7 +2986,8 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1], if (is_mask) { if (!is_all_zeros((const uint8_t *) nd_key, sizeof *nd_key) && - flow->tp_src != htons(0xffff)) { + (flow->tp_src != htons(0xffff) || + flow->tp_dst != htons(0xffff))) { return ODP_FIT_ERROR; } else { expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND;