]> git.proxmox.com Git - mirror_ovs.git/blob - datapath/linux/compat/include/net/udp_tunnel.h
datapath: backport: udp: Add socket based GRO and config
[mirror_ovs.git] / datapath / linux / compat / include / net / udp_tunnel.h
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
7 #include <net/addrconf.h>
8 #include <net/dst_metadata.h>
9 #include <linux/netdev_features.h>
10
11 #ifdef USE_UPSTREAM_TUNNEL
12 #include_next <net/udp_tunnel.h>
13
14 #else
15
16 #include <net/ip_tunnels.h>
17 #include <net/udp.h>
18
19 struct udp_port_cfg {
20 u8 family;
21
22 /* Used only for kernel-created sockets */
23 union {
24 struct in_addr local_ip;
25 #if IS_ENABLED(CONFIG_IPV6)
26 struct in6_addr local_ip6;
27 #endif
28 };
29
30 union {
31 struct in_addr peer_ip;
32 #if IS_ENABLED(CONFIG_IPV6)
33 struct in6_addr peer_ip6;
34 #endif
35 };
36
37 __be16 local_udp_port;
38 __be16 peer_udp_port;
39 unsigned int use_udp_checksums:1,
40 use_udp6_tx_checksums:1,
41 use_udp6_rx_checksums:1,
42 ipv6_v6only:1;
43 };
44
45 #define udp_sock_create4 rpl_udp_sock_create4
46 int rpl_udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
47 struct socket **sockp);
48
49 #define udp_sock_create6 rpl_udp_sock_create6
50 #if IS_ENABLED(CONFIG_IPV6)
51 int rpl_udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
52 struct socket **sockp);
53 #else
54 static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
55 struct socket **sockp)
56 {
57 return -EPFNOSUPPORT;
58 }
59 #endif
60
61 #define udp_sock_create rpl_udp_sock_create
62 static inline int udp_sock_create(struct net *net,
63 struct udp_port_cfg *cfg,
64 struct socket **sockp)
65 {
66 if (cfg->family == AF_INET)
67 return udp_sock_create4(net, cfg, sockp);
68
69 if (cfg->family == AF_INET6)
70 return udp_sock_create6(net, cfg, sockp);
71
72 return -EPFNOSUPPORT;
73 }
74
75 typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
76 typedef void (*udp_tunnel_encap_destroy_t)(struct sock *sk);
77 typedef struct sk_buff **(*udp_tunnel_gro_receive_t)(struct sock *sk,
78 struct sk_buff **head,
79 struct sk_buff *skb);
80 typedef int (*udp_tunnel_gro_complete_t)(struct sock *sk, struct sk_buff *skb,
81 int nhoff);
82
83 struct udp_tunnel_sock_cfg {
84 void *sk_user_data; /* user data used by encap_rcv call back */
85 /* Used for setting up udp_sock fields, see udp.h for details */
86 __u8 encap_type;
87 udp_tunnel_encap_rcv_t encap_rcv;
88 udp_tunnel_encap_destroy_t encap_destroy;
89 #ifdef HAVE_UDP_TUNNEL_SOCK_CFG_GRO_RECEIVE
90 udp_tunnel_gro_receive_t gro_receive;
91 udp_tunnel_gro_complete_t gro_complete;
92 #endif
93 };
94
95 /* Setup the given (UDP) sock to receive UDP encapsulated packets */
96 #define setup_udp_tunnel_sock rpl_setup_udp_tunnel_sock
97 void rpl_setup_udp_tunnel_sock(struct net *net, struct socket *sock,
98 struct udp_tunnel_sock_cfg *sock_cfg);
99
100 /* Transmit the skb using UDP encapsulation. */
101 #define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
102 int rpl_udp_tunnel_xmit_skb(struct rtable *rt,
103 struct sock *sk, struct sk_buff *skb,
104 __be32 src, __be32 dst, __u8 tos, __u8 ttl,
105 __be16 df, __be16 src_port, __be16 dst_port,
106 bool xnet, bool nocheck);
107
108
109 #define udp_tunnel_sock_release rpl_udp_tunnel_sock_release
110 void rpl_udp_tunnel_sock_release(struct socket *sock);
111
112 #define udp_tunnel_encap_enable rpl_udp_tunnel_encap_enable
113 static inline void udp_tunnel_encap_enable(struct socket *sock)
114 {
115 #if IS_ENABLED(CONFIG_IPV6)
116 if (sock->sk->sk_family == PF_INET6)
117 #ifdef HAVE_IPV6_STUB
118 ipv6_stub->udpv6_encap_enable();
119 #else
120 udpv6_encap_enable();
121 #endif
122 else
123 #endif
124 udp_encap_enable();
125 }
126
127 #if IS_ENABLED(CONFIG_IPV6)
128 #define udp_tunnel6_xmit_skb rpl_udp_tunnel6_xmit_skb
129 int rpl_udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
130 struct sk_buff *skb,
131 struct net_device *dev, struct in6_addr *saddr,
132 struct in6_addr *daddr,
133 __u8 prio, __u8 ttl, __be32 label, __be16 src_port,
134 __be16 dst_port, bool nocheck);
135 #endif
136
137 static inline void udp_tunnel_gro_complete(struct sk_buff *skb, int nhoff)
138 {
139 struct udphdr *uh;
140
141 uh = (struct udphdr *)(skb->data + nhoff - sizeof(struct udphdr));
142 skb_shinfo(skb)->gso_type |= uh->check ?
143 SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
144 }
145 #endif
146
147 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
148 /* this is to handle the return type change in handle-offload
149 * functions.
150 */
151 static inline int
152 rpl_udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum,
153 bool is_vxlan)
154 {
155 if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
156 return -ENOSYS;
157 }
158 return udp_tunnel_handle_offloads(skb, udp_csum);
159 }
160
161 #else
162 void ovs_udp_gso(struct sk_buff *skb);
163 void ovs_udp_csum_gso(struct sk_buff *skb);
164
165 static inline int rpl_udp_tunnel_handle_offloads(struct sk_buff *skb,
166 bool udp_csum,
167 bool is_vxlan)
168 {
169 int type = 0;
170
171 void (*fix_segment)(struct sk_buff *);
172
173 if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
174 return -ENOSYS;
175 }
176
177 type |= udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
178 if (!udp_csum)
179 fix_segment = ovs_udp_gso;
180 else
181 fix_segment = ovs_udp_csum_gso;
182
183 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
184 if (!is_vxlan)
185 type = 0;
186 #endif
187
188 return ovs_iptunnel_handle_offloads(skb, udp_csum, type, fix_segment);
189 }
190 #endif
191
192 #define udp_tunnel_handle_offloads rpl_udp_tunnel_handle_offloads
193
194 static inline void ovs_udp_tun_rx_dst(struct ip_tunnel_info *info,
195 struct sk_buff *skb,
196 unsigned short family,
197 __be16 flags, __be64 tunnel_id, int md_size)
198 {
199 if (family == AF_INET)
200 ovs_ip_tun_rx_dst(info, skb, flags, tunnel_id, md_size);
201 else
202 ovs_ipv6_tun_rx_dst(info, skb, flags, tunnel_id, md_size);
203
204 info->key.tp_src = udp_hdr(skb)->source;
205 info->key.tp_dst = udp_hdr(skb)->dest;
206 if (udp_hdr(skb)->check)
207 info->key.tun_flags |= TUNNEL_CSUM;
208 }
209
210 #endif