]> git.proxmox.com Git - mirror_ovs.git/blame - datapath/linux/compat/include/net/udp_tunnel.h
datapath: Add support for lwtunnel
[mirror_ovs.git] / datapath / linux / compat / include / net / udp_tunnel.h
CommitLineData
eb6eebd2
JG
1#ifndef __NET_UDP_TUNNEL_WRAPPER_H
2#define __NET_UDP_TUNNEL_WRAPPER_H
3
4#include <linux/version.h>
5#include <linux/kconfig.h>
6
e23775f2
PS
7#include <net/dst_metadata.h>
8#include <linux/netdev_features.h>
9#ifdef HAVE_UDP_TUNNEL_IPV6
eb6eebd2 10#include_next <net/udp_tunnel.h>
a42ec67e
JG
11
12static inline struct sk_buff *
13rpl_udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum,
e23775f2 14 int type, bool is_vxlan)
a42ec67e
JG
15{
16 if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
17 kfree_skb(skb);
18 return ERR_PTR(-ENOSYS);
19 }
20 return udp_tunnel_handle_offloads(skb, udp_csum);
21}
22#define udp_tunnel_handle_offloads rpl_udp_tunnel_handle_offloads
23
eb6eebd2
JG
24#else
25
a42ec67e
JG
26#include <net/ip_tunnels.h>
27#include <net/udp.h>
28
eb6eebd2
JG
29struct udp_port_cfg {
30 u8 family;
31
32 /* Used only for kernel-created sockets */
33 union {
34 struct in_addr local_ip;
35#if IS_ENABLED(CONFIG_IPV6)
36 struct in6_addr local_ip6;
37#endif
38 };
39
40 union {
41 struct in_addr peer_ip;
42#if IS_ENABLED(CONFIG_IPV6)
43 struct in6_addr peer_ip6;
44#endif
45 };
46
47 __be16 local_udp_port;
48 __be16 peer_udp_port;
49 unsigned int use_udp_checksums:1,
50 use_udp6_tx_checksums:1,
e23775f2
PS
51 use_udp6_rx_checksums:1,
52 ipv6_v6only:1;
eb6eebd2
JG
53};
54
4adb03cb 55#define udp_sock_create rpl_udp_sock_create
bedf02f4
AW
56int rpl_udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
57 struct socket **sockp);
eb6eebd2 58
a42ec67e
JG
59typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
60typedef void (*udp_tunnel_encap_destroy_t)(struct sock *sk);
61
62struct udp_tunnel_sock_cfg {
63 void *sk_user_data; /* user data used by encap_rcv call back */
64 /* Used for setting up udp_sock fields, see udp.h for details */
65 __u8 encap_type;
66 udp_tunnel_encap_rcv_t encap_rcv;
67 udp_tunnel_encap_destroy_t encap_destroy;
68};
69
70/* Setup the given (UDP) sock to receive UDP encapsulated packets */
bedf02f4
AW
71#define setup_udp_tunnel_sock rpl_setup_udp_tunnel_sock
72void rpl_setup_udp_tunnel_sock(struct net *net, struct socket *sock,
73 struct udp_tunnel_sock_cfg *sock_cfg);
a42ec67e
JG
74
75/* Transmit the skb using UDP encapsulation. */
bedf02f4 76#define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
c0cddcec
JS
77int rpl_udp_tunnel_xmit_skb(struct rtable *rt,
78 struct sock *sk, struct sk_buff *skb,
bedf02f4
AW
79 __be32 src, __be32 dst, __u8 tos, __u8 ttl,
80 __be16 df, __be16 src_port, __be16 dst_port,
81 bool xnet, bool nocheck);
7bdcee3e 82
a42ec67e 83
bedf02f4
AW
84#define udp_tunnel_sock_release rpl_udp_tunnel_sock_release
85void rpl_udp_tunnel_sock_release(struct socket *sock);
a42ec67e
JG
86
87void ovs_udp_gso(struct sk_buff *skb);
88void ovs_udp_csum_gso(struct sk_buff *skb);
89
e23775f2 90#define udp_tunnel_encap_enable(sock) udp_encap_enable()
a42ec67e
JG
91static inline struct sk_buff *udp_tunnel_handle_offloads(struct sk_buff *skb,
92 bool udp_csum,
e23775f2 93 int type,
a42ec67e
JG
94 bool is_vxlan)
95{
a42ec67e
JG
96 void (*fix_segment)(struct sk_buff *);
97
e23775f2
PS
98 if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
99 kfree_skb(skb);
100 return ERR_PTR(-ENOSYS);
101 }
102
103 type |= udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
a42ec67e
JG
104 if (!udp_csum)
105 fix_segment = ovs_udp_gso;
106 else
107 fix_segment = ovs_udp_csum_gso;
108
109#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
110 if (!is_vxlan)
111 type = 0;
112#endif
113
114 return ovs_iptunnel_handle_offloads(skb, udp_csum, type, fix_segment);
115}
116
e23775f2
PS
117#if IS_ENABLED(CONFIG_IPV6)
118#define udp_tunnel6_xmit_skb rpl_udp_tunnel6_xmit_skb
119int rpl_udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
120 struct sk_buff *skb,
121 struct net_device *dev, struct in6_addr *saddr,
122 struct in6_addr *daddr,
123 __u8 prio, __u8 ttl, __be16 src_port,
124 __be16 dst_port, bool nocheck);
125#endif
126
127static inline void udp_tunnel_gro_complete(struct sk_buff *skb, int nhoff)
128{
129 struct udphdr *uh;
130
131 uh = (struct udphdr *)(skb->data + nhoff - sizeof(struct udphdr));
132 skb_shinfo(skb)->gso_type |= uh->check ?
133 SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
134}
135#endif
136
137static inline void ovs_udp_tun_rx_dst(struct ip_tunnel_info *info,
138 struct sk_buff *skb,
139 unsigned short family,
140 __be16 flags, __be64 tunnel_id, int md_size)
141{
142 if (family == AF_INET)
143 ovs_ip_tun_rx_dst(info, skb, flags, tunnel_id, md_size);
144
145 info->key.tp_src = udp_hdr(skb)->source;
146 info->key.tp_dst = udp_hdr(skb)->dest;
147 if (udp_hdr(skb)->check)
148 info->key.tun_flags |= TUNNEL_CSUM;
149}
a42ec67e 150
eb6eebd2 151#endif