datapath: Add support for lwtunnel
[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/dst_metadata.h>
8 #include <linux/netdev_features.h>
9 #ifdef HAVE_UDP_TUNNEL_IPV6
10 #include_next <net/udp_tunnel.h>
11
12 static inline struct sk_buff *
13 rpl_udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum,
14                 int type, bool is_vxlan)
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
24 #else
25
26 #include <net/ip_tunnels.h>
27 #include <net/udp.h>
28
29 struct 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,
51                                 use_udp6_rx_checksums:1,
52                                 ipv6_v6only:1;
53 };
54
55 #define udp_sock_create rpl_udp_sock_create
56 int rpl_udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
57                         struct socket **sockp);
58
59 typedef int (*udp_tunnel_encap_rcv_t)(struct sock *sk, struct sk_buff *skb);
60 typedef void (*udp_tunnel_encap_destroy_t)(struct sock *sk);
61
62 struct 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 */
71 #define setup_udp_tunnel_sock rpl_setup_udp_tunnel_sock
72 void rpl_setup_udp_tunnel_sock(struct net *net, struct socket *sock,
73                                struct udp_tunnel_sock_cfg *sock_cfg);
74
75 /* Transmit the skb using UDP encapsulation. */
76 #define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
77 int rpl_udp_tunnel_xmit_skb(struct rtable *rt,
78                             struct sock *sk, struct sk_buff *skb,
79                             __be32 src, __be32 dst, __u8 tos, __u8 ttl,
80                             __be16 df, __be16 src_port, __be16 dst_port,
81                             bool xnet, bool nocheck);
82
83
84 #define udp_tunnel_sock_release rpl_udp_tunnel_sock_release
85 void rpl_udp_tunnel_sock_release(struct socket *sock);
86
87 void ovs_udp_gso(struct sk_buff *skb);
88 void ovs_udp_csum_gso(struct sk_buff *skb);
89
90 #define udp_tunnel_encap_enable(sock) udp_encap_enable()
91 static inline struct sk_buff *udp_tunnel_handle_offloads(struct sk_buff *skb,
92                                                          bool udp_csum,
93                                                          int type,
94                                                          bool is_vxlan)
95 {
96         void (*fix_segment)(struct sk_buff *);
97
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;
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
117 #if IS_ENABLED(CONFIG_IPV6)
118 #define udp_tunnel6_xmit_skb rpl_udp_tunnel6_xmit_skb
119 int 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
127 static 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
137 static 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 }
150
151 #endif