This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
2024-07-16 17:25:55 +08:00

158 lines
4.9 KiB
C

#ifndef _VXLAN_H
#define _VXLAN_H
#ifdef __cplusplus
extern "C"
{
#endif
#define __FAVOR_BSD 1
#include <netinet/udp.h>
#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 __cplusplus
}
#endif
#endif