flow: New function is_nd().
authorBen Pfaff <blp@ovn.org>
Sat, 2 Jul 2016 18:35:29 +0000 (11:35 -0700)
committerBen Pfaff <blp@ovn.org>
Sat, 2 Jul 2016 18:35:55 +0000 (11:35 -0700)
This simplifies a few pieces of code and will acquire another user in an
upcoming commit.

Signed-off-by: Ben Pfaff <blp@ovn.org>
lib/flow.h
lib/meta-flow.c
lib/nx-match.c
lib/odp-util.c
lib/tnl-neigh-cache.c

index 22b245c..5479677 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <sys/types.h>
 #include <netinet/in.h>
+#include <netinet/icmp6.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
@@ -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)) {
index 136295d..e160de1 100644 (file)
@@ -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();
index aad6e02..9a2ada9 100644 (file)
@@ -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)) {
index d7b6a2d..fd1ca9b 100644 (file)
@@ -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;
                 }
index e571980..f7d29f6 100644 (file)
@@ -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