Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / packets.h
index e852761..b776914 100644 (file)
@@ -44,6 +44,9 @@ static const uint8_t eth_addr_stp[ETH_ADDR_LEN] OVS_UNUSED
 static const uint8_t eth_addr_lacp[ETH_ADDR_LEN] OVS_UNUSED
     = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 };
 
+static const uint8_t eth_addr_bfd[ETH_ADDR_LEN] OVS_UNUSED
+    = { 0x00, 0x23, 0x20, 0x00, 0x00, 0x01 };
+
 static inline bool eth_addr_is_broadcast(const uint8_t ea[6])
 {
     return (ea[0] & ea[1] & ea[2] & ea[3] & ea[4] & ea[5]) == 0xff;
@@ -443,8 +446,8 @@ struct ip_header {
     uint8_t ip_ttl;
     uint8_t ip_proto;
     ovs_be16 ip_csum;
-    ovs_be32 ip_src;
-    ovs_be32 ip_dst;
+    ovs_16aligned_be32 ip_src;
+    ovs_16aligned_be32 ip_dst;
 };
 BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header));
 
@@ -462,12 +465,21 @@ struct icmp_header {
             ovs_be16 empty;
             ovs_be16 mtu;
         } frag;
-        ovs_be32 gateway;
+        ovs_16aligned_be32 gateway;
     } icmp_fields;
     uint8_t icmp_data[0];
 };
 BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header));
 
+#define SCTP_HEADER_LEN 12
+struct sctp_header {
+    ovs_be16 sctp_src;
+    ovs_be16 sctp_dst;
+    ovs_be32 sctp_vtag;
+    ovs_be32 sctp_csum;
+};
+BUILD_ASSERT_DECL(SCTP_HEADER_LEN == sizeof(struct sctp_header));
+
 #define UDP_HEADER_LEN 8
 struct udp_header {
     ovs_be16 udp_src;
@@ -492,8 +504,8 @@ BUILD_ASSERT_DECL(UDP_HEADER_LEN == sizeof(struct udp_header));
 struct tcp_header {
     ovs_be16 tcp_src;
     ovs_be16 tcp_dst;
-    ovs_be32 tcp_seq;
-    ovs_be32 tcp_ack;
+    ovs_16aligned_be32 tcp_seq;
+    ovs_16aligned_be32 tcp_ack;
     ovs_be16 tcp_ctl;
     ovs_be16 tcp_winsz;
     ovs_be16 tcp_csum;
@@ -508,7 +520,6 @@ BUILD_ASSERT_DECL(TCP_HEADER_LEN == sizeof(struct tcp_header));
 #define ARP_OP_RARP 3
 
 #define ARP_ETH_HEADER_LEN 28
-OVS_PACKED(
 struct arp_eth_header {
     /* Generic members. */
     ovs_be16 ar_hrd;           /* Hardware type. */
@@ -519,12 +530,44 @@ struct arp_eth_header {
 
     /* Ethernet+IPv4 specific members. */
     uint8_t ar_sha[ETH_ADDR_LEN]; /* Sender hardware address. */
-    ovs_be32 ar_spa;           /* Sender protocol address. */
+    ovs_16aligned_be32 ar_spa;           /* Sender protocol address. */
     uint8_t ar_tha[ETH_ADDR_LEN]; /* Target hardware address. */
-    ovs_be32 ar_tpa;           /* Target protocol address. */
-});
+    ovs_16aligned_be32 ar_tpa;           /* Target protocol address. */
+};
 BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header));
 
+/* Like struct in6_addr, but whereas that struct requires 32-bit alignment on
+ * most implementations, this one only requires 16-bit alignment. */
+union ovs_16aligned_in6_addr {
+    ovs_be16 be16[8];
+    ovs_16aligned_be32 be32[4];
+};
+
+/* Like struct in6_hdr, but whereas that struct requires 32-bit alignment, this
+ * one only requires 16-bit alignment. */
+struct ovs_16aligned_ip6_hdr {
+    union {
+        struct ovs_16aligned_ip6_hdrctl {
+            ovs_16aligned_be32 ip6_un1_flow;
+            ovs_be16 ip6_un1_plen;
+            uint8_t ip6_un1_nxt;
+            uint8_t ip6_un1_hlim;
+        } ip6_un1;
+        uint8_t ip6_un2_vfc;
+    } ip6_ctlun;
+    union ovs_16aligned_in6_addr ip6_src;
+    union ovs_16aligned_in6_addr ip6_dst;
+};
+
+/* Like struct in6_frag, but whereas that struct requires 32-bit alignment,
+ * this one only requires 16-bit alignment. */
+struct ovs_16aligned_ip6_frag {
+    uint8_t ip6f_nxt;
+    uint8_t ip6f_reserved;
+    ovs_be16 ip6f_offlg;
+    ovs_16aligned_be32 ip6f_ident;
+};
+
 /* The IPv6 flow label is in the lower 20 bits of the first 32-bit word. */
 #define IPV6_LABEL_MASK 0x000fffff
 
@@ -598,6 +641,7 @@ void packet_set_ipv6(struct ofpbuf *, uint8_t proto, const ovs_be32 src[4],
                      ovs_be32 fl, uint8_t hlmit);
 void packet_set_tcp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst);
 void packet_set_udp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst);
+void packet_set_sctp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst);
 
 uint8_t packet_get_tcp_flags(const struct ofpbuf *, const struct flow *);
 void packet_format_tcp_flags(struct ds *, uint8_t);