From 6f8dbd272a7d1b4a0f5d8cd58467c162ae65135e Mon Sep 17 00:00:00 2001 From: Guolin Yang Date: Fri, 30 Aug 2013 09:57:13 -0700 Subject: [PATCH] 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 --- lib/odp-util.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) 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; -- 2.43.0