1012a5729SPravin B Shelar #ifndef __NET_VXLAN_H 2012a5729SPravin B Shelar #define __NET_VXLAN_H 1 3012a5729SPravin B Shelar 45f35227eSJesse Gross #include <linux/ip.h> 55f35227eSJesse Gross #include <linux/ipv6.h> 65f35227eSJesse Gross #include <linux/if_vlan.h> 7012a5729SPravin B Shelar #include <linux/skbuff.h> 8012a5729SPravin B Shelar #include <linux/netdevice.h> 9012a5729SPravin B Shelar #include <linux/udp.h> 10012a5729SPravin B Shelar 11012a5729SPravin B Shelar #define VNI_HASH_BITS 10 12012a5729SPravin B Shelar #define VNI_HASH_SIZE (1<<VNI_HASH_BITS) 13012a5729SPravin B Shelar 1411bf7828SJoe Stringer /* VXLAN protocol header */ 1511bf7828SJoe Stringer struct vxlanhdr { 1611bf7828SJoe Stringer __be32 vx_flags; 1711bf7828SJoe Stringer __be32 vx_vni; 1811bf7828SJoe Stringer }; 1911bf7828SJoe Stringer 203bf39475STom Herbert /* VXLAN header flags. */ 213bf39475STom Herbert #define VXLAN_HF_VNI 0x08000000 22dfd8645eSTom Herbert #define VXLAN_HF_RCO 0x00200000 23dfd8645eSTom Herbert 24dfd8645eSTom Herbert /* Remote checksum offload header option */ 25dfd8645eSTom Herbert #define VXLAN_RCO_MASK 0x7f /* Last byte of vni field */ 26dfd8645eSTom Herbert #define VXLAN_RCO_UDP 0x80 /* Indicate UDP RCO (TCP when not set *) */ 27dfd8645eSTom Herbert #define VXLAN_RCO_SHIFT 1 /* Left shift of start */ 28dfd8645eSTom Herbert #define VXLAN_RCO_SHIFT_MASK ((1 << VXLAN_RCO_SHIFT) - 1) 29dfd8645eSTom Herbert #define VXLAN_MAX_REMCSUM_START (VXLAN_RCO_MASK << VXLAN_RCO_SHIFT) 303bf39475STom Herbert 313bf39475STom Herbert #define VXLAN_N_VID (1u << 24) 323bf39475STom Herbert #define VXLAN_VID_MASK (VXLAN_N_VID - 1) 333bf39475STom Herbert #define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr)) 343bf39475STom Herbert 35012a5729SPravin B Shelar struct vxlan_sock; 36012a5729SPravin B Shelar typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key); 37012a5729SPravin B Shelar 38012a5729SPravin B Shelar /* per UDP socket information */ 39012a5729SPravin B Shelar struct vxlan_sock { 40012a5729SPravin B Shelar struct hlist_node hlist; 41012a5729SPravin B Shelar vxlan_rcv_t *rcv; 42012a5729SPravin B Shelar void *data; 43012a5729SPravin B Shelar struct work_struct del_work; 44012a5729SPravin B Shelar struct socket *sock; 45012a5729SPravin B Shelar struct rcu_head rcu; 46012a5729SPravin B Shelar struct hlist_head vni_list[VNI_HASH_SIZE]; 47012a5729SPravin B Shelar atomic_t refcnt; 48dc01e7d3SOr Gerlitz struct udp_offload udp_offloads; 49dfd8645eSTom Herbert u32 flags; 50012a5729SPravin B Shelar }; 51012a5729SPravin B Shelar 52359a0ea9STom Herbert #define VXLAN_F_LEARN 0x01 53359a0ea9STom Herbert #define VXLAN_F_PROXY 0x02 54359a0ea9STom Herbert #define VXLAN_F_RSC 0x04 55359a0ea9STom Herbert #define VXLAN_F_L2MISS 0x08 56359a0ea9STom Herbert #define VXLAN_F_L3MISS 0x10 57359a0ea9STom Herbert #define VXLAN_F_IPV6 0x20 58359a0ea9STom Herbert #define VXLAN_F_UDP_CSUM 0x40 59359a0ea9STom Herbert #define VXLAN_F_UDP_ZERO_CSUM6_TX 0x80 60359a0ea9STom Herbert #define VXLAN_F_UDP_ZERO_CSUM6_RX 0x100 61dfd8645eSTom Herbert #define VXLAN_F_REMCSUM_TX 0x200 62dfd8645eSTom Herbert #define VXLAN_F_REMCSUM_RX 0x400 63359a0ea9STom Herbert 64012a5729SPravin B Shelar struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port, 65012a5729SPravin B Shelar vxlan_rcv_t *rcv, void *data, 66359a0ea9STom Herbert bool no_share, u32 flags); 67012a5729SPravin B Shelar 68012a5729SPravin B Shelar void vxlan_sock_release(struct vxlan_sock *vs); 6949560532SPravin B Shelar 7011796187SNicolas Dichtel int vxlan_xmit_skb(struct vxlan_sock *vs, 7149560532SPravin B Shelar struct rtable *rt, struct sk_buff *skb, 7249560532SPravin B Shelar __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, 73f01ec1c0SNicolas Dichtel __be16 src_port, __be16 dst_port, __be32 vni, bool xnet); 7449560532SPravin B Shelar 755f35227eSJesse Gross static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, 765f35227eSJesse Gross netdev_features_t features) 7711bf7828SJoe Stringer { 785f35227eSJesse Gross u8 l4_hdr = 0; 795f35227eSJesse Gross 805f35227eSJesse Gross if (!skb->encapsulation) 815f35227eSJesse Gross return features; 825f35227eSJesse Gross 835f35227eSJesse Gross switch (vlan_get_protocol(skb)) { 845f35227eSJesse Gross case htons(ETH_P_IP): 855f35227eSJesse Gross l4_hdr = ip_hdr(skb)->protocol; 865f35227eSJesse Gross break; 875f35227eSJesse Gross case htons(ETH_P_IPV6): 885f35227eSJesse Gross l4_hdr = ipv6_hdr(skb)->nexthdr; 895f35227eSJesse Gross break; 905f35227eSJesse Gross default: 915f35227eSJesse Gross return features;; 925f35227eSJesse Gross } 935f35227eSJesse Gross 945f35227eSJesse Gross if ((l4_hdr == IPPROTO_UDP) && 9511bf7828SJoe Stringer (skb->inner_protocol_type != ENCAP_TYPE_ETHER || 9611bf7828SJoe Stringer skb->inner_protocol != htons(ETH_P_TEB) || 9711bf7828SJoe Stringer (skb_inner_mac_header(skb) - skb_transport_header(skb) != 9811bf7828SJoe Stringer sizeof(struct udphdr) + sizeof(struct vxlanhdr)))) 995f35227eSJesse Gross return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); 10011bf7828SJoe Stringer 1015f35227eSJesse Gross return features; 10211bf7828SJoe Stringer } 10323e62de3SJoe Stringer 104e6cd988cSJoseph Gasparakis /* IP header + UDP + VXLAN + Ethernet header */ 105e6cd988cSJoseph Gasparakis #define VXLAN_HEADROOM (20 + 8 + 8 + 14) 106e6cd988cSJoseph Gasparakis /* IPv6 header + UDP + VXLAN + Ethernet header */ 107e6cd988cSJoseph Gasparakis #define VXLAN6_HEADROOM (40 + 8 + 8 + 14) 108e6cd988cSJoseph Gasparakis 109e6cd988cSJoseph Gasparakis #if IS_ENABLED(CONFIG_VXLAN) 11053cf5275SJoseph Gasparakis void vxlan_get_rx_port(struct net_device *netdev); 111e6cd988cSJoseph Gasparakis #else 112e6cd988cSJoseph Gasparakis static inline void vxlan_get_rx_port(struct net_device *netdev) 113e6cd988cSJoseph Gasparakis { 114e6cd988cSJoseph Gasparakis } 115e6cd988cSJoseph Gasparakis #endif 116012a5729SPravin B Shelar #endif 117