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