1 #ifndef __NET_UDP_TUNNEL_WRAPPER_H
2 #define __NET_UDP_TUNNEL_WRAPPER_H
4 #include <linux/version.h>
5 #include <linux/kconfig.h>
7 #include <net/addrconf.h>
8 #include <net/dst_metadata.h>
9 #include <linux/netdev_features.h>
11 #ifdef USE_UPSTREAM_TUNNEL
12 #include_next <net/udp_tunnel.h>
14 /* this is to handle the return type change in handle-offload
18 rpl_udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum,
21 if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
24 return udp_tunnel_handle_offloads(skb, udp_csum);
29 #include <net/addrconf.h>
30 #include <net/ip_tunnels.h>
36 /* Used only for kernel-created sockets */
38 struct in_addr local_ip;
39 #if IS_ENABLED(CONFIG_IPV6)
40 struct in6_addr local_ip6;
45 struct in_addr peer_ip;
46 #if IS_ENABLED(CONFIG_IPV6)
47 struct in6_addr peer_ip6;
51 __be16 local_udp_port;
53 unsigned int use_udp_checksums:1,
54 use_udp6_tx_checksums:1,
55 use_udp6_rx_checksums:1,
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);
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);
68 static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
69 struct socket **sockp)
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)
80 if (cfg->family == AF_INET)
81 return udp_sock_create4(net, cfg, sockp);
83 if (cfg->family == AF_INET6)
84 return udp_sock_create6(net, cfg, sockp);
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,
94 typedef int (*udp_tunnel_gro_complete_t)(struct sock *sk, struct sk_buff *skb,
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 */
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;
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);
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);
123 #define udp_tunnel_sock_release rpl_udp_tunnel_sock_release
124 void rpl_udp_tunnel_sock_release(struct socket *sock);
126 #define udp_tunnel_encap_enable rpl_udp_tunnel_encap_enable
127 static inline void udp_tunnel_encap_enable(struct socket *sock)
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();
134 udpv6_encap_enable();
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,
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);
151 static inline void udp_tunnel_gro_complete(struct sk_buff *skb, int nhoff)
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;
160 void ovs_udp_gso(struct sk_buff *skb);
161 void ovs_udp_csum_gso(struct sk_buff *skb);
163 static inline int rpl_udp_tunnel_handle_offloads(struct sk_buff *skb,
169 void (*fix_segment)(struct sk_buff *);
171 if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
175 type |= udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
177 fix_segment = ovs_udp_gso;
179 fix_segment = ovs_udp_csum_gso;
181 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
186 return ovs_iptunnel_handle_offloads(skb, udp_csum, type, fix_segment);
188 #endif /* USE_UPSTREAM_TUNNEL */
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,
193 unsigned short family,
194 __be16 flags, __be64 tunnel_id, int md_size)
196 struct ip_tunnel_info *info = &md_dst->u.tun_info;
198 if (family == AF_INET)
199 ovs_ip_tun_rx_dst(md_dst, skb, flags, tunnel_id, md_size);
201 ovs_ipv6_tun_rx_dst(md_dst, skb, flags, tunnel_id, md_size);
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;