From c17fcc0aed0bfb1651a1343eb0762a428c905ff3 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 2 Jul 2016 11:35:29 -0700 Subject: [PATCH] flow: New function is_nd(). This simplifies a few pieces of code and will acquire another user in an upcoming commit. Signed-off-by: Ben Pfaff --- lib/flow.h | 21 +++++++++++++++++++++ lib/meta-flow.c | 13 +++---------- lib/nx-match.c | 3 +-- lib/odp-util.c | 8 ++------ lib/tnl-neigh-cache.c | 5 +---- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/lib/flow.h b/lib/flow.h index 22b245c92..547967741 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -856,6 +857,26 @@ static inline bool is_icmpv6(const struct flow *flow, return false; } +static inline bool is_nd(const struct flow *flow, + struct flow_wildcards *wc) +{ + if (is_icmpv6(flow, wc)) { + if (wc) { + memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); + } + if (flow->tp_dst != htons(0)) { + return false; + } + + if (wc) { + memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); + } + return (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || + flow->tp_src == htons(ND_NEIGHBOR_ADVERT)); + } + return false; +} + static inline bool is_igmp(const struct flow *flow, struct flow_wildcards *wc) { if (flow->dl_type == htons(ETH_TYPE_IP)) { diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 136295d4a..e160de171 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -398,18 +398,11 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow) return is_icmpv6(flow, NULL); case MFP_ND: - return (is_icmpv6(flow, NULL) - && flow->tp_dst == htons(0) - && (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || - flow->tp_src == htons(ND_NEIGHBOR_ADVERT))); + return is_nd(flow, NULL); case MFP_ND_SOLICIT: - return (is_icmpv6(flow, NULL) - && flow->tp_dst == htons(0) - && (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT))); + return is_nd(flow, NULL) && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT); case MFP_ND_ADVERT: - return (is_icmpv6(flow, NULL) - && flow->tp_dst == htons(0) - && (flow->tp_src == htons(ND_NEIGHBOR_ADVERT))); + return is_nd(flow, NULL) && flow->tp_src == htons(ND_NEIGHBOR_ADVERT); } OVS_NOT_REACHED(); diff --git a/lib/nx-match.c b/lib/nx-match.c index aad6e02f2..9a2ada9dd 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -879,8 +879,7 @@ nxm_put_ip(struct ofpbuf *b, const struct match *match, enum ofp_version oxm) nxm_put_8(b, MFF_ICMPV6_CODE, oxm, ntohs(flow->tp_dst)); } - if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || - flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + if (is_nd(flow, NULL)) { nxm_put_ipv6(b, MFF_ND_TARGET, oxm, &flow->nd_target, &match->wc.masks.nd_target); if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { diff --git a/lib/odp-util.c b/lib/odp-util.c index d7b6a2d27..fd1ca9b5f 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -4420,9 +4420,7 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms, icmpv6_key->icmpv6_type = ntohs(data->tp_src); icmpv6_key->icmpv6_code = ntohs(data->tp_dst); - if (flow->tp_dst == htons(0) - && (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) - || flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) + if (is_nd(flow, NULL) /* Even though 'tp_src' and 'tp_dst' are 16 bits wide, ICMP * type and code are 8 bits wide. Therefore, an exact match * looks like htons(0xff), not htons(0xffff). See @@ -4957,9 +4955,7 @@ 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_dst == htons(0) && - (src_flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || - src_flow->tp_src == htons(ND_NEIGHBOR_ADVERT))) { + if (is_nd(src_flow, NULL)) { if (!is_mask) { expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND; } diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index e571980a1..f7d29f625 100644 --- a/lib/tnl-neigh-cache.c +++ b/lib/tnl-neigh-cache.c @@ -170,10 +170,7 @@ static int tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, const char name[IFNAMSIZ]) { - if (flow->dl_type != htons(ETH_TYPE_IPV6) || - flow->nw_proto != IPPROTO_ICMPV6 || - flow->tp_dst != htons(0) || - flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { + if (!is_nd(flow, NULL) || flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { return EINVAL; } /* - RFC4861 says Neighbor Advertisements sent in response to unicast Neighbor -- 2.39.5