xref: /linux/include/net/udp_tunnel.h (revision 84a73014d86fd660822a20c032625e3afe99ca58)
18024e028STom Herbert #ifndef __NET_UDP_TUNNEL_H
28024e028STom Herbert #define __NET_UDP_TUNNEL_H
38024e028STom Herbert 
46a93cc90SAndy Zhou #include <net/ip_tunnels.h>
56a93cc90SAndy Zhou #include <net/udp.h>
66a93cc90SAndy Zhou 
76a93cc90SAndy Zhou #if IS_ENABLED(CONFIG_IPV6)
86a93cc90SAndy Zhou #include <net/ipv6.h>
96a93cc90SAndy Zhou #include <net/addrconf.h>
106a93cc90SAndy Zhou #endif
116a93cc90SAndy Zhou 
128024e028STom Herbert struct udp_port_cfg {
138024e028STom Herbert 	u8			family;
148024e028STom Herbert 
158024e028STom Herbert 	/* Used only for kernel-created sockets */
168024e028STom Herbert 	union {
178024e028STom Herbert 		struct in_addr		local_ip;
188024e028STom Herbert #if IS_ENABLED(CONFIG_IPV6)
198024e028STom Herbert 		struct in6_addr		local_ip6;
208024e028STom Herbert #endif
218024e028STom Herbert 	};
228024e028STom Herbert 
238024e028STom Herbert 	union {
248024e028STom Herbert 		struct in_addr		peer_ip;
258024e028STom Herbert #if IS_ENABLED(CONFIG_IPV6)
268024e028STom Herbert 		struct in6_addr		peer_ip6;
278024e028STom Herbert #endif
288024e028STom Herbert 	};
298024e028STom Herbert 
308024e028STom Herbert 	__be16			local_udp_port;
318024e028STom Herbert 	__be16			peer_udp_port;
328024e028STom Herbert 	unsigned int		use_udp_checksums:1,
338024e028STom Herbert 				use_udp6_tx_checksums:1,
34a43a9ef6SJiri Benc 				use_udp6_rx_checksums:1,
35a43a9ef6SJiri Benc 				ipv6_v6only:1;
368024e028STom Herbert };
378024e028STom Herbert 
38fd384412SAndy Zhou int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
398024e028STom Herbert 		     struct socket **sockp);
408024e028STom Herbert 
41fd384412SAndy Zhou #if IS_ENABLED(CONFIG_IPV6)
42fd384412SAndy Zhou int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
43fd384412SAndy Zhou 		     struct socket **sockp);
44fd384412SAndy Zhou #else
45fd384412SAndy Zhou static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
46fd384412SAndy Zhou 				   struct socket **sockp)
47fd384412SAndy Zhou {
48fd384412SAndy Zhou 	return 0;
49fd384412SAndy Zhou }
50fd384412SAndy Zhou #endif
51fd384412SAndy Zhou 
52fd384412SAndy Zhou static inline int udp_sock_create(struct net *net,
53fd384412SAndy Zhou 				  struct udp_port_cfg *cfg,
54fd384412SAndy Zhou 				  struct socket **sockp)
55fd384412SAndy Zhou {
56fd384412SAndy Zhou 	if (cfg->family == AF_INET)
57fd384412SAndy Zhou 		return udp_sock_create4(net, cfg, sockp);
58fd384412SAndy Zhou 
59fd384412SAndy Zhou 	if (cfg->family == AF_INET6)
60fd384412SAndy Zhou 		return udp_sock_create6(net, cfg, sockp);
61fd384412SAndy Zhou 
62fd384412SAndy Zhou 	return -EPFNOSUPPORT;
63fd384412SAndy Zhou }
64fd384412SAndy Zhou 
656a93cc90SAndy Zhou typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
666a93cc90SAndy Zhou typedef void (*udp_tunnel_encap_destroy_t)(struct sock *sk);
676a93cc90SAndy Zhou 
686a93cc90SAndy Zhou struct udp_tunnel_sock_cfg {
696a93cc90SAndy Zhou 	void *sk_user_data;     /* user data used by encap_rcv call back */
706a93cc90SAndy Zhou 	/* Used for setting up udp_sock fields, see udp.h for details */
716a93cc90SAndy Zhou 	__u8  encap_type;
726a93cc90SAndy Zhou 	udp_tunnel_encap_rcv_t encap_rcv;
736a93cc90SAndy Zhou 	udp_tunnel_encap_destroy_t encap_destroy;
746a93cc90SAndy Zhou };
756a93cc90SAndy Zhou 
766a93cc90SAndy Zhou /* Setup the given (UDP) sock to receive UDP encapsulated packets */
776a93cc90SAndy Zhou void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
786a93cc90SAndy Zhou 			   struct udp_tunnel_sock_cfg *sock_cfg);
796a93cc90SAndy Zhou 
806a93cc90SAndy Zhou /* Transmit the skb using UDP encapsulation. */
8179b16aadSDavid Miller int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
82d998f8efSTom Herbert 			__be32 src, __be32 dst, __u8 tos, __u8 ttl,
83d998f8efSTom Herbert 			__be16 df, __be16 src_port, __be16 dst_port,
84d998f8efSTom Herbert 			bool xnet, bool nocheck);
856a93cc90SAndy Zhou 
866a93cc90SAndy Zhou #if IS_ENABLED(CONFIG_IPV6)
8779b16aadSDavid Miller int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
8879b16aadSDavid Miller 			 struct sk_buff *skb,
89d998f8efSTom Herbert 			 struct net_device *dev, struct in6_addr *saddr,
90d998f8efSTom Herbert 			 struct in6_addr *daddr,
916a93cc90SAndy Zhou 			 __u8 prio, __u8 ttl, __be16 src_port,
92d998f8efSTom Herbert 			 __be16 dst_port, bool nocheck);
936a93cc90SAndy Zhou #endif
946a93cc90SAndy Zhou 
956a93cc90SAndy Zhou void udp_tunnel_sock_release(struct socket *sock);
966a93cc90SAndy Zhou 
97c29a70d2SPravin B Shelar struct metadata_dst *udp_tun_rx_dst(struct sk_buff *skb, unsigned short family,
98c29a70d2SPravin B Shelar 				    __be16 flags, __be64 tunnel_id,
99c29a70d2SPravin B Shelar 				    int md_size);
100c29a70d2SPravin B Shelar 
1016a93cc90SAndy Zhou static inline struct sk_buff *udp_tunnel_handle_offloads(struct sk_buff *skb,
1026a93cc90SAndy Zhou 							 bool udp_csum)
1036a93cc90SAndy Zhou {
1046a93cc90SAndy Zhou 	int type = udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
1056a93cc90SAndy Zhou 
1066a93cc90SAndy Zhou 	return iptunnel_handle_offloads(skb, udp_csum, type);
1076a93cc90SAndy Zhou }
1086a93cc90SAndy Zhou 
109cfdf1e1bSJesse Gross static inline void udp_tunnel_gro_complete(struct sk_buff *skb, int nhoff)
110cfdf1e1bSJesse Gross {
111cfdf1e1bSJesse Gross 	struct udphdr *uh;
112cfdf1e1bSJesse Gross 
113cfdf1e1bSJesse Gross 	uh = (struct udphdr *)(skb->data + nhoff - sizeof(struct udphdr));
114cfdf1e1bSJesse Gross 	skb_shinfo(skb)->gso_type |= uh->check ?
115cfdf1e1bSJesse Gross 				SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
116cfdf1e1bSJesse Gross }
117cfdf1e1bSJesse Gross 
1186a93cc90SAndy Zhou static inline void udp_tunnel_encap_enable(struct socket *sock)
1196a93cc90SAndy Zhou {
1206a93cc90SAndy Zhou #if IS_ENABLED(CONFIG_IPV6)
1216a93cc90SAndy Zhou 	if (sock->sk->sk_family == PF_INET6)
1226a93cc90SAndy Zhou 		ipv6_stub->udpv6_encap_enable();
1236a93cc90SAndy Zhou 	else
1246a93cc90SAndy Zhou #endif
1256a93cc90SAndy Zhou 		udp_encap_enable();
1266a93cc90SAndy Zhou }
1276a93cc90SAndy Zhou 
1288024e028STom Herbert #endif
129