packets: Fix misaligned data accesses for MPLS and SCTP fields.
[sliver-openvswitch.git] / lib / packets.h
index 30e4d13..eca24d5 100644 (file)
@@ -26,6 +26,7 @@
 #include "flow.h"
 #include "openvswitch/types.h"
 #include "random.h"
+#include "hash.h"
 #include "util.h"
 
 struct ofpbuf;
@@ -134,6 +135,11 @@ static inline uint64_t eth_addr_to_uint64(const uint8_t ea[ETH_ADDR_LEN])
             | ((uint64_t) ea[4] << 8)
             | ea[5]);
 }
+static inline uint64_t eth_addr_vlan_to_uint64(const uint8_t ea[ETH_ADDR_LEN],
+                                               uint16_t vlan)
+{
+    return (((uint64_t)vlan << 48) | eth_addr_to_uint64(ea));
+}
 static inline void eth_addr_from_uint64(uint64_t x, uint8_t ea[ETH_ADDR_LEN])
 {
     ea[0] = x >> 40;
@@ -165,6 +171,11 @@ static inline void eth_addr_nicira_random(uint8_t ea[ETH_ADDR_LEN])
     /* Set the top bit to indicate random Nicira address. */
     ea[3] |= 0x80;
 }
+static inline uint32_t hash_mac(const uint8_t ea[ETH_ADDR_LEN],
+                                const uint16_t vlan, const uint32_t basis)
+{
+    return hash_uint64_basis(eth_addr_vlan_to_uint64(ea, vlan), basis);
+}
 
 bool eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN]);
 bool eth_addr_from_string(const char *, uint8_t ea[ETH_ADDR_LEN]);
@@ -352,7 +363,7 @@ BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header));
 #define MPLS_HLEN           4
 
 struct mpls_hdr {
-    ovs_be32 mpls_lse;
+    ovs_16aligned_be32 mpls_lse;
 };
 BUILD_ASSERT_DECL(MPLS_HLEN == sizeof(struct mpls_hdr));
 
@@ -499,8 +510,8 @@ BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header));
 struct sctp_header {
     ovs_be16 sctp_src;
     ovs_be16 sctp_dst;
-    ovs_be32 sctp_vtag;
-    ovs_be32 sctp_csum;
+    ovs_16aligned_be32 sctp_vtag;
+    ovs_16aligned_be32 sctp_csum;
 };
 BUILD_ASSERT_DECL(SCTP_HEADER_LEN == sizeof(struct sctp_header));