--- lib/cfm.c | 4 +++- lib/compiler.h | 10 ++++++++++ lib/lacp.c | 6 ++++-- lib/packets.h | 18 ++++++++++++------ lib/stp.c | 9 ++++++--- ofproto/ofproto-dpif-ipfix.c | 30 ++++++++++++++++++++---------- 6 files changed, 55 insertions(+), 22 deletions(-)
diff --git a/lib/cfm.c b/lib/cfm.c index 06415fc..a76a3ec 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -61,6 +61,8 @@ static const uint8_t eth_addr_ccm_x[6] = { #define CCM_OPCODE 1 /* CFM message opcode meaning CCM. */ #define CCM_RDI_MASK 0x80 #define CFM_HEALTH_INTERVAL 6 + +OVS_PACKED( struct ccm { uint8_t mdlevel_version; /* MD Level and Version */ uint8_t opcode; @@ -78,7 +80,7 @@ struct ccm { /* TLV space. */ uint8_t end_tlv; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(CCM_LEN == sizeof(struct ccm)); struct cfm { diff --git a/lib/compiler.h b/lib/compiler.h index f3cbe96..34823b8 100644 --- a/lib/compiler.h +++ b/lib/compiler.h @@ -93,4 +93,14 @@ #define OVS_PACKED_ENUM #endif +#ifdef __GNUC__ +/* GCC implementations. */ +#define OVS_PACKED( __Declaration__ ) __Declaration__ __attribute__((__packed__)) + +#else +/* Generic implementations. */ +#define OVS_PACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) + +#endif + #endif /* compiler.h */ diff --git a/lib/lacp.c b/lib/lacp.c index 64cdbe7..5d90850 100644 --- a/lib/lacp.c +++ b/lib/lacp.c @@ -47,6 +47,7 @@ VLOG_DEFINE_THIS_MODULE(lacp); #define LACP_RX_MULTIPLIER 3 /* Multiply by TX rate to get RX rate. */ #define LACP_INFO_LEN 15 +OVS_PACKED( struct lacp_info { ovs_be16 sys_priority; /* System priority. */ uint8_t sys_id[ETH_ADDR_LEN]; /* System ID. */ @@ -54,10 +55,11 @@ struct lacp_info { ovs_be16 port_priority; /* Port priority. */ ovs_be16 port_id; /* Port ID. */ uint8_t state; /* State mask. See LACP_STATE macros. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(LACP_INFO_LEN == sizeof(struct lacp_info)); #define LACP_PDU_LEN 110 +OVS_PACKED( struct lacp_pdu { uint8_t subtype; /* Always 1. */ uint8_t version; /* Always 1. */ @@ -76,7 +78,7 @@ struct lacp_pdu { uint8_t collector_len; /* Always 16. */ ovs_be16 collector_delay; /* Maximum collector delay. Set to UINT16_MAX. */ uint8_t z3[64]; /* Combination of several fields. Always 0. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(LACP_PDU_LEN == sizeof(struct lacp_pdu)); /* Implementation. */ diff --git a/lib/packets.h b/lib/packets.h index cc9ab3d..e852761 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -217,11 +217,12 @@ static inline bool eth_type_mpls(ovs_be16 eth_type) #define ETH_TOTAL_MIN (ETH_HEADER_LEN + ETH_PAYLOAD_MIN) #define ETH_TOTAL_MAX (ETH_HEADER_LEN + ETH_PAYLOAD_MAX) #define ETH_VLAN_TOTAL_MAX (ETH_HEADER_LEN + VLAN_HEADER_LEN + ETH_PAYLOAD_MAX) +OVS_PACKED( struct eth_header { uint8_t eth_dst[ETH_ADDR_LEN]; uint8_t eth_src[ETH_ADDR_LEN]; ovs_be16 eth_type; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); #define LLC_DSAP_SNAP 0xaa @@ -229,27 +230,30 @@ BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); #define LLC_CNTL_SNAP 3 #define LLC_HEADER_LEN 3 +OVS_PACKED( struct llc_header { uint8_t llc_dsap; uint8_t llc_ssap; uint8_t llc_cntl; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(LLC_HEADER_LEN == sizeof(struct llc_header)); #define SNAP_ORG_ETHERNET "\0\0" /* The compiler adds a null byte, so sizeof(SNAP_ORG_ETHERNET) == 3. */ #define SNAP_HEADER_LEN 5 +OVS_PACKED( struct snap_header { uint8_t snap_org[3]; ovs_be16 snap_type; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(SNAP_HEADER_LEN == sizeof(struct snap_header)); #define LLC_SNAP_HEADER_LEN (LLC_HEADER_LEN + SNAP_HEADER_LEN) +OVS_PACKED( struct llc_snap_header { struct llc_header llc; struct snap_header snap; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); #define VLAN_VID_MASK 0x0fff @@ -293,13 +297,14 @@ struct vlan_header { BUILD_ASSERT_DECL(VLAN_HEADER_LEN == sizeof(struct vlan_header)); #define VLAN_ETH_HEADER_LEN (ETH_HEADER_LEN + VLAN_HEADER_LEN) +OVS_PACKED( struct vlan_eth_header { uint8_t veth_dst[ETH_ADDR_LEN]; uint8_t veth_src[ETH_ADDR_LEN]; ovs_be16 veth_type; /* Always htons(ETH_TYPE_VLAN). */ ovs_be16 veth_tci; /* Lowest 12 bits are VLAN ID. */ ovs_be16 veth_next_type; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); /* MPLS related definitions */ @@ -503,6 +508,7 @@ 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. */ @@ -516,7 +522,7 @@ struct arp_eth_header { ovs_be32 ar_spa; /* Sender protocol address. */ uint8_t ar_tha[ETH_ADDR_LEN]; /* Target hardware address. */ ovs_be32 ar_tpa; /* Target protocol address. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header)); /* The IPv6 flow label is in the lower 20 bits of the first 32-bit word. */ diff --git a/lib/stp.c b/lib/stp.c index 7bff624..0b32cb5 100644 --- a/lib/stp.c +++ b/lib/stp.c @@ -39,11 +39,12 @@ VLOG_DEFINE_THIS_MODULE(stp); #define STP_TYPE_CONFIG 0x00 #define STP_TYPE_TCN 0x80 +OVS_PACKED( struct stp_bpdu_header { ovs_be16 protocol_id; /* STP_PROTOCOL_ID. */ uint8_t protocol_version; /* STP_PROTOCOL_VERSION. */ uint8_t bpdu_type; /* One of STP_TYPE_*. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct stp_bpdu_header) == 4); enum stp_config_bpdu_flags { @@ -51,6 +52,7 @@ enum stp_config_bpdu_flags { STP_CONFIG_TOPOLOGY_CHANGE = 0x01 }; +OVS_PACKED( struct stp_config_bpdu { struct stp_bpdu_header header; /* Type STP_TYPE_CONFIG. */ uint8_t flags; /* STP_CONFIG_* flags. */ @@ -62,12 +64,13 @@ struct stp_config_bpdu { ovs_be16 max_age; /* 8.5.1.6: Timeout for received data. */ ovs_be16 hello_time; /* 8.5.1.7: Time between BPDU generation. */ ovs_be16 forward_delay; /* 8.5.1.8: State progression delay. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct stp_config_bpdu) == 35); +OVS_PACKED( struct stp_tcn_bpdu { struct stp_bpdu_header header; /* Type STP_TYPE_TCN. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct stp_tcn_bpdu) == 4); struct stp_timer { diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index ef0e980..8523afb 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -73,23 +73,25 @@ struct dpif_ipfix { #define IPFIX_TEMPLATE_INTERVAL 600 /* Cf. IETF RFC 5101 Section 3.1. */ +OVS_PACKED( struct ipfix_header { ovs_be16 version; /* IPFIX_VERSION. */ ovs_be16 length; /* Length in bytes including this header. */ ovs_be32 export_time; /* Seconds since the epoch. */ ovs_be32 seq_number; /* Message sequence number. */ ovs_be32 obs_domain_id; /* Observation Domain ID. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_header) == 16); #define IPFIX_SET_ID_TEMPLATE 2 #define IPFIX_SET_ID_OPTION_TEMPLATE 3 /* Cf. IETF RFC 5101 Section 3.3.2. */ +OVS_PACKED( struct ipfix_set_header { ovs_be16 set_id; /* IPFIX_SET_ID_* or valid template ID for Data Sets. */ ovs_be16 length; /* Length of the set in bytes including header. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_set_header) == 4); /* Alternatives for templates at each layer. A template is defined by @@ -115,10 +117,11 @@ enum ipfix_proto_l4 { #define IPFIX_TEMPLATE_ID_MIN 256 /* Cf. IETF RFC 5101 Section 3.4.1. */ +OVS_PACKED( struct ipfix_template_record_header { ovs_be16 template_id; ovs_be16 field_count; -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_template_record_header) == 4); enum ipfix_entity_id { @@ -131,14 +134,16 @@ enum ipfix_entity_size { #include "ofproto/ipfix-entities.def" }; +OVS_PACKED( struct ipfix_template_field_specifier { ovs_be16 element_id; /* IPFIX_ENTITY_ID_*. */ ovs_be16 field_length; /* Length of the field's value, in bytes. */ /* No Enterprise ID, since only standard element IDs are specified. */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_template_field_specifier) == 4); /* Part of data record for common metadata and Ethernet entities. */ +OVS_PACKED( struct ipfix_data_record_common { ovs_be32 observation_point_id; /* OBSERVATION_POINT_ID */ ovs_be64 packet_delta_count; /* PACKET_DELTA_COUNT */ @@ -148,18 +153,20 @@ struct ipfix_data_record_common { ovs_be16 ethernet_type; /* ETHERNET_TYPE */ ovs_be16 ethernet_total_length; /* ETHERNET_TOTAL_LENGTH */ uint8_t ethernet_header_length; /* ETHERNET_HEADER_LENGTH */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_common) == 37); /* Part of data record for VLAN entities. */ +OVS_PACKED( struct ipfix_data_record_vlan { ovs_be16 vlan_id; /* VLAN_ID */ ovs_be16 dot1q_vlan_id; /* DOT1Q_VLAN_ID */ uint8_t dot1q_priority; /* DOT1Q_PRIORITY */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_vlan) == 5); /* Part of data record for IP entities. */ +OVS_PACKED( struct ipfix_data_record_ip { uint8_t ip_version; /* IP_VERSION */ uint8_t ip_ttl; /* IP_TTL */ @@ -167,29 +174,32 @@ struct ipfix_data_record_ip { uint8_t ip_diff_serv_code_point; /* IP_DIFF_SERV_CODE_POINT */ uint8_t ip_precedence; /* IP_PRECEDENCE */ uint8_t ip_class_of_service; /* IP_CLASS_OF_SERVICE */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_ip) == 6); /* Part of data record for IPv4 entities. */ +OVS_PACKED( struct ipfix_data_record_ipv4 { ovs_be32 source_ipv4_address; /* SOURCE_IPV4_ADDRESS */ ovs_be32 destination_ipv4_address; /* DESTINATION_IPV4_ADDRESS */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_ipv4) == 8); /* Part of data record for IPv4 entities. */ +OVS_PACKED( struct ipfix_data_record_ipv6 { uint8_t source_ipv6_address[16]; /* SOURCE_IPV6_ADDRESS */ uint8_t destination_ipv6_address[16]; /* DESTINATION_IPV6_ADDRESS */ ovs_be32 flow_label_ipv6; /* FLOW_LABEL_IPV6 */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_ipv6) == 36); /* Part of data record for TCP/UDP entities. */ +OVS_PACKED( struct ipfix_data_record_tcpudp { ovs_be16 source_transport_port; /* SOURCE_TRANSPORT_PORT */ ovs_be16 destination_transport_port; /* DESTINATION_TRANSPORT_PORT */ -} __attribute__((packed)); +}); BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_tcpudp) == 4); static bool -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev