#ifndef _VXLAN_H #define _VXLAN_H #ifdef __cpluscplus extern "C" { #endif #define __FAVOR_BSD 1 #include #include "tuple.h" /* * 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. */ struct vxlan_hdr { uint8_t flags; uint8_t reserved[3]; // VNI 3 Bytes uint8_t vlan_id_half_high; uint8_t link_layer_type : 4; // 二层报文封装格式 uint8_t vlan_id_half_low : 4; uint8_t dir : 1; uint8_t traffic : 1; uint8_t sf_index : 5; // max value 32 uint8_t online_test : 1; // Reserved 1 Bytes uint8_t r7 : 1; uint8_t r6 : 1; uint8_t r5 : 1; uint8_t r4 : 1; uint8_t vni_flag : 1; uint8_t r2 : 1; uint8_t r1 : 1; uint8_t r0 : 1; } __attribute__((__packed__)); enum vni_opt { VNI_OPT_DIR = 0x80, VNI_OPT_TRAFFIC = 0x40, VNI_OPT_SFINDEX = 0x3f, }; #define VXLAN_FLAGS 0x8 #define VXLAN_DST_PORT 4789 #define VXLAN_FRAME_HDR_LEN (sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct vxlan_hdr)) void vxlan_set_opt(struct vxlan_hdr *hdr, enum vni_opt opt, uint8_t val); uint8_t vxlan_get_opt(struct vxlan_hdr *hdr, enum vni_opt opt); // return 0 : success // return -1 : error int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, uint16_t 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 vni_opt_dir, uint8_t vni_opt_traffic, uint8_t vni_opt_sf_index); uint16_t calculate_vxlan_source_port(struct four_tuple *innermost_tuple4); #ifdef __cpluscplus } #endif #endif