[ovs-dev] [ofproto tests 20/29] unaligned: Add unaligned accessors for ovs_be<N> data.

Ben Pfaff blp at nicira.com
Tue Nov 16 19:21:10 UTC 2010


These accessors are semantically identical to the ones for uint<N>_t data,
but the names are more informative to readers, and the types provide
annotations for sparse.
---
 lib/flow.c              |    4 +-
 lib/nx-match.c          |   40 ++++++++++++++--------------
 lib/unaligned.h         |   68 +++++++++++++++++++++++++++++++----------------
 tests/test-classifier.c |    6 ++--
 4 files changed, 70 insertions(+), 48 deletions(-)

diff --git a/lib/flow.c b/lib/flow.c
index 0b6541f..0b73961 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -176,8 +176,8 @@ flow_extract(struct ofpbuf *packet, ovs_be32 tun_id, uint16_t in_port,
     if (flow->dl_type == htons(ETH_TYPE_IP)) {
         const struct ip_header *nh = pull_ip(&b);
         if (nh) {
-            flow->nw_src = get_unaligned_u32(&nh->ip_src);
-            flow->nw_dst = get_unaligned_u32(&nh->ip_dst);
+            flow->nw_src = get_unaligned_be32(&nh->ip_src);
+            flow->nw_dst = get_unaligned_be32(&nh->ip_dst);
             flow->nw_tos = nh->ip_tos & IP_DSCP_MASK;
             flow->nw_proto = nh->ip_proto;
             packet->l4 = b.data;
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 9f869a7..9ffb391 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -162,9 +162,9 @@ parse_nx_reg(const struct nxm_field *f,
     } else {
         flow_wildcards_set_reg_mask(wc, idx,
                                     (NXM_HASMASK(f->header)
-                                     ? ntohl(get_unaligned_u32(maskp))
+                                     ? ntohl(get_unaligned_be32(maskp))
                                      : UINT32_MAX));
-        flow->regs[idx] = ntohl(get_unaligned_u32(value));
+        flow->regs[idx] = ntohl(get_unaligned_be32(value));
         flow->regs[idx] &= wc->reg_masks[idx];
         return 0;
     }
@@ -180,7 +180,7 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
     switch (f->index) {
         /* Metadata. */
     case NFI_NXM_OF_IN_PORT:
-        flow->in_port = ntohs(get_unaligned_u16(value));
+        flow->in_port = ntohs(get_unaligned_be16(value));
         if (flow->in_port == OFPP_LOCAL) {
             flow->in_port = ODPP_LOCAL;
         }
@@ -220,16 +220,16 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
         memcpy(flow->dl_src, value, ETH_ADDR_LEN);
         return 0;
     case NFI_NXM_OF_ETH_TYPE:
-        flow->dl_type = get_unaligned_u16(value);
+        flow->dl_type = get_unaligned_be16(value);
         return 0;
 
         /* 802.1Q header. */
     case NFI_NXM_OF_VLAN_TCI:
-        return parse_tci(rule, get_unaligned_u16(value), htons(UINT16_MAX));
+        return parse_tci(rule, get_unaligned_be16(value), htons(UINT16_MAX));
 
     case NFI_NXM_OF_VLAN_TCI_W:
-        return parse_tci(rule, get_unaligned_u16(value),
-                         get_unaligned_u16(mask));
+        return parse_tci(rule, get_unaligned_be16(value),
+                         get_unaligned_be16(mask));
 
         /* IP header. */
     case NFI_NXM_OF_IP_TOS:
@@ -249,7 +249,7 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
         if (wc->nw_src_mask) {
             return NXM_DUP_TYPE;
         } else {
-            cls_rule_set_nw_src(rule, get_unaligned_u32(value));
+            cls_rule_set_nw_src(rule, get_unaligned_be32(value));
             return 0;
         }
     case NFI_NXM_OF_IP_SRC_W:
@@ -257,8 +257,8 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
         if (wc->nw_src_mask) {
             return NXM_DUP_TYPE;
         } else {
-            ovs_be32 ip = get_unaligned_u32(value);
-            ovs_be32 netmask = get_unaligned_u32(mask);
+            ovs_be32 ip = get_unaligned_be32(value);
+            ovs_be32 netmask = get_unaligned_be32(mask);
             if (!cls_rule_set_nw_src_masked(rule, ip, netmask)) {
                 return NXM_BAD_MASK;
             }
@@ -269,7 +269,7 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
         if (wc->nw_dst_mask) {
             return NXM_DUP_TYPE;
         } else {
-            cls_rule_set_nw_dst(rule, get_unaligned_u32(value));
+            cls_rule_set_nw_dst(rule, get_unaligned_be32(value));
             return 0;
         }
     case NFI_NXM_OF_IP_DST_W:
@@ -277,8 +277,8 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
         if (wc->nw_dst_mask) {
             return NXM_DUP_TYPE;
         } else {
-            ovs_be32 ip = get_unaligned_u32(value);
-            ovs_be32 netmask = get_unaligned_u32(mask);
+            ovs_be32 ip = get_unaligned_be32(value);
+            ovs_be32 netmask = get_unaligned_be32(mask);
             if (!cls_rule_set_nw_dst_masked(rule, ip, netmask)) {
                 return NXM_BAD_MASK;
             }
@@ -287,18 +287,18 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
 
         /* TCP header. */
     case NFI_NXM_OF_TCP_SRC:
-        flow->tp_src = get_unaligned_u16(value);
+        flow->tp_src = get_unaligned_be16(value);
         return 0;
     case NFI_NXM_OF_TCP_DST:
-        flow->tp_dst = get_unaligned_u16(value);
+        flow->tp_dst = get_unaligned_be16(value);
         return 0;
 
         /* UDP header. */
     case NFI_NXM_OF_UDP_SRC:
-        flow->tp_src = get_unaligned_u16(value);
+        flow->tp_src = get_unaligned_be16(value);
         return 0;
     case NFI_NXM_OF_UDP_DST:
-        flow->tp_dst = get_unaligned_u16(value);
+        flow->tp_dst = get_unaligned_be16(value);
         return 0;
 
         /* ICMP header. */
@@ -311,16 +311,16 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
 
         /* ARP header. */
     case NFI_NXM_OF_ARP_OP:
-        if (ntohs(get_unaligned_u16(value)) > 255) {
+        if (ntohs(get_unaligned_be16(value)) > 255) {
             return NXM_BAD_VALUE;
         } else {
-            flow->nw_proto = ntohs(get_unaligned_u16(value));
+            flow->nw_proto = ntohs(get_unaligned_be16(value));
             return 0;
         }
 
         /* Tunnel ID. */
     case NFI_NXM_NX_TUN_ID:
-        flow->tun_id = htonl(ntohll(get_unaligned_u64(value)));
+        flow->tun_id = htonl(ntohll(get_unaligned_be64(value)));
         return 0;
 
         /* Registers. */
diff --git a/lib/unaligned.h b/lib/unaligned.h
index 4540c31..ef08f4e 100644
--- a/lib/unaligned.h
+++ b/lib/unaligned.h
@@ -19,6 +19,7 @@
 
 #include <stdint.h>
 #include "byte-order.h"
+#include "openvswitch/types.h"
 
 /* Public API. */
 static inline uint16_t get_unaligned_u16(const uint16_t *);
@@ -28,33 +29,44 @@ static inline void put_unaligned_u16(uint16_t *, uint16_t);
 static inline void put_unaligned_u32(uint32_t *, uint32_t);
 static inline void put_unaligned_u64(uint64_t *, uint64_t);
 
+static inline ovs_be16 get_unaligned_be16(const ovs_be16 *);
+static inline ovs_be32 get_unaligned_be32(const ovs_be32 *);
+static inline ovs_be64 get_unaligned_be64(const ovs_be64 *);
+static inline void put_unaligned_be16(ovs_be16 *, ovs_be16);
+static inline void put_unaligned_be32(ovs_be32 *, ovs_be32);
+static inline void put_unaligned_be64(ovs_be64 *, ovs_be64);
+
 #ifdef __GNUC__
 /* GCC implementations. */
-#define GCC_UNALIGNED_ACCESSORS(SIZE)                       \
-struct unaligned_u##SIZE {                                  \
-    uint##SIZE##_t x __attribute__((__packed__));           \
-};                                                          \
-static inline struct unaligned_u##SIZE *                    \
-unaligned_u##SIZE(const uint##SIZE##_t *p)                  \
-{                                                           \
-    return (struct unaligned_u##SIZE *) p;                  \
-}                                                           \
-                                                            \
-static inline uint##SIZE##_t                                \
-get_unaligned_u##SIZE(const uint##SIZE##_t *p)              \
-{                                                           \
-    return unaligned_u##SIZE(p)->x;                         \
-}                                                           \
-                                                            \
-static inline void                                          \
-put_unaligned_u##SIZE(uint##SIZE##_t *p, uint##SIZE##_t x)  \
-{                                                           \
-    unaligned_u##SIZE(p)->x = x;                            \
+#define GCC_UNALIGNED_ACCESSORS(TYPE, ABBREV)   \
+struct unaligned_##ABBREV {                     \
+    TYPE x __attribute__((__packed__));         \
+};                                              \
+static inline struct unaligned_##ABBREV *       \
+unaligned_##ABBREV(const TYPE *p)               \
+{                                               \
+    return (struct unaligned_##ABBREV *) p;     \
+}                                               \
+                                                \
+static inline TYPE                              \
+get_unaligned_##ABBREV(const TYPE *p)           \
+{                                               \
+    return unaligned_##ABBREV(p)->x;            \
+}                                               \
+                                                \
+static inline void                              \
+put_unaligned_##ABBREV(TYPE *p, TYPE x)         \
+{                                               \
+    unaligned_##ABBREV(p)->x = x;               \
 }
 
-GCC_UNALIGNED_ACCESSORS(16);
-GCC_UNALIGNED_ACCESSORS(32);
-GCC_UNALIGNED_ACCESSORS(64);
+GCC_UNALIGNED_ACCESSORS(uint16_t, u16);
+GCC_UNALIGNED_ACCESSORS(uint32_t, u32);
+GCC_UNALIGNED_ACCESSORS(uint64_t, u64);
+
+GCC_UNALIGNED_ACCESSORS(ovs_be16, be16);
+GCC_UNALIGNED_ACCESSORS(ovs_be32, be32);
+GCC_UNALIGNED_ACCESSORS(ovs_be64, be64);
 #else
 /* Generic implementations. */
 
@@ -117,6 +129,16 @@ static inline void put_unaligned_u64(uint64_t *p_, uint64_t x_)
     p[6] = x >> 8;
     p[7] = x;
 }
+
+/* Only sparse cares about the difference between uint<N>_t and ovs_be<N>, and
+ * that takes the GCC branch, so there's no point in working too hard on these
+ * accessors. */
+#define get_unaligned_be16 get_unaligned_u16
+#define get_unaligned_be32 get_unaligned_u32
+#define get_unaligned_be64 get_unaligned_u64
+#define put_unaligned_be16 put_unaligned_u16
+#define put_unaligned_be32 put_unaligned_u32
+#define put_unaligned_be64 put_unaligned_u64
 #endif
 
 #endif /* unaligned.h */
diff --git a/tests/test-classifier.c b/tests/test-classifier.c
index 9af97a4..7bf6652 100644
--- a/tests/test-classifier.c
+++ b/tests/test-classifier.c
@@ -200,11 +200,11 @@ match(const struct cls_rule *wild, const struct flow *fixed)
         }
 
         if (wild->wc.wildcards & f->wildcards) {
-            uint32_t test = get_unaligned_u32(wild_field);
-            uint32_t ip = get_unaligned_u32(fixed_field);
+            ovs_be32 test = get_unaligned_be32(wild_field);
+            ovs_be32 ip = get_unaligned_be32(fixed_field);
             int shift = (f_idx == CLS_F_IDX_NW_SRC
                          ? OFPFW_NW_SRC_SHIFT : OFPFW_NW_DST_SHIFT);
-            uint32_t mask = flow_nw_bits_to_mask(wild->wc.wildcards, shift);
+            ovs_be32 mask = flow_nw_bits_to_mask(wild->wc.wildcards, shift);
             if (!((test ^ ip) & mask)) {
                 continue;
             }
-- 
1.7.1





More information about the dev mailing list