#ifndef _VXLAN_H #define _VXLAN_H #ifdef __cpluscplus extern "C" { #endif #define __FAVOR_BSD 1 #include #include "tuple.h" /* ****************************************************************************** * Standard VXLAN Header: ****************************************************************************** * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |R|R|R|R|I|R|R|R| Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VXLAN Network Identifier (VNI) | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Flags (8 bits): * where the I flag MUST be set to 1 for a valid VXLAN Network ID (VNI). * The other 7 bits (designated "R") are reserved fields and MUST be set * to zero on transmission and ignored on receipt. * Reserved fields (24 bits and 8 bits): * MUST be set to zero on transmission and ignored on receipt. * ****************************************************************************** * SCE VXLAN Header: ****************************************************************************** * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |R|R|R|R|I|R|R|R| Reserved |S| Traffic Link ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | high | type | low |D|T|SF index |T| Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Flags : 8 bits * Reserved : 7 bits * S (StateLess) : 1 bit * * Traffic Link ID : 16 bits * * vlan_id_half_high : 8 bits * link_layer_type : 4 bits // 二层报文封装格式 * vlan_id_half_low : 4 bits * * dir : 1 bit * traffic : 1 bit * sf_index : 5 bits // max value 32 * online_test : 1 bit * * Reserved : 8 bit */ struct vxlan_hdr { uint16_t flags_reserved; uint16_t link_id; uint16_t vlan_id; uint16_t user_ctx; } __attribute__((__packed__)); #define VXLAN_DEFAULT_FLAGS 0x8 #define VXLAN_DST_PORT 4789 #define VXLAN_FRAME_HDR_LEN ((int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct vxlan_hdr))) #define VXLAN_FLAGS_MASK 0xFF00 #define VXLAN_STATELESS_MASK 0x0001 #define VXLAN_DIR_MASK 0x8000 #define VXLAN_TRAFFIC_MASK 0x4000 #define VXLAN_SF_INDEX_MASK 0x3E00 static inline void vxlan_set_flags(struct vxlan_hdr *hdr, uint8_t flags) { hdr->flags_reserved = htons((ntohs(hdr->flags_reserved) & ~VXLAN_FLAGS_MASK) | (flags << 8)); } static inline void vxlan_set_dir(struct vxlan_hdr *hdr, uint8_t val) { hdr->user_ctx = htons((ntohs(hdr->user_ctx) & ~VXLAN_DIR_MASK) | ((!!val) << 15)); } static inline void vxlan_set_traffic(struct vxlan_hdr *hdr, uint8_t val) { hdr->user_ctx = htons((ntohs(hdr->user_ctx) & ~VXLAN_TRAFFIC_MASK) | ((!!val) << 14)); } static inline void vxlan_set_sf_index(struct vxlan_hdr *hdr, uint8_t val) { hdr->user_ctx = htons((ntohs(hdr->user_ctx) & ~VXLAN_SF_INDEX_MASK) | ((val & 0x1F) << 9)); } static inline void vxlan_set_link_id(struct vxlan_hdr *hdr, uint16_t val) { hdr->link_id = htons(val); } static inline void vxlan_set_stateless(struct vxlan_hdr *hdr, uint8_t val) { hdr->flags_reserved = htons((ntohs(hdr->flags_reserved) & ~VXLAN_STATELESS_MASK) | (!!val)); } static inline uint8_t vxlan_get_flags(struct vxlan_hdr *hdr) { return ((ntohs(hdr->flags_reserved) & VXLAN_FLAGS_MASK) >> 8); } static inline uint8_t vxlan_get_dir(struct vxlan_hdr *hdr) { return ((ntohs(hdr->user_ctx) & VXLAN_DIR_MASK) >> 15); } static inline uint8_t vxlan_get_traffic(struct vxlan_hdr *hdr) { return ((ntohs(hdr->user_ctx) & VXLAN_TRAFFIC_MASK) >> 14); } static inline uint8_t vxlan_get_sf_index(struct vxlan_hdr *hdr) { return ((ntohs(hdr->user_ctx) & VXLAN_SF_INDEX_MASK) >> 9); } static inline uint16_t vxlan_get_link_id(struct vxlan_hdr *hdr) { return ntohs(hdr->link_id); } static inline uint8_t vxlan_get_stateless(struct vxlan_hdr *hdr) { return ntohs(hdr->flags_reserved) & VXLAN_STATELESS_MASK; } // return 0 : success // return -1 : error int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, int len); void vxlan_frame_encode(char *buff, const u_char eth_src_mac[], const u_char eth_dst_mac[], const in_addr_t ip_src_addr, const in_addr_t ip_dst_addr, uint16_t ip_id, uint16_t udp_src_port, uint16_t udp_pld_len, uint8_t dir, uint8_t traffic, uint8_t sf_index, uint16_t link_id); uint16_t calculate_vxlan_source_port(struct four_tuple *innermost_tuple4); #ifdef __cpluscplus } #endif #endif