datapath: Add support for kernel 4.6
[cascardo/ovs.git] / datapath / linux / compat / include / net / dst_metadata.h
1 #ifndef __NET_DST_METADATA_WRAPPER_H
2 #define __NET_DST_METADATA_WRAPPER_H 1
3
4 #ifdef USE_UPSTREAM_TUNNEL
5 #include_next <net/dst_metadata.h>
6 #else
7 #include <linux/skbuff.h>
8
9 #include <net/dsfield.h>
10 #include <net/dst.h>
11 #include <net/ipv6.h>
12 #include <net/ip_tunnels.h>
13
14 struct metadata_dst {
15         unsigned long dst;
16         union {
17                 struct ip_tunnel_info   tun_info;
18         } u;
19 };
20
21 static void __metadata_dst_init(struct metadata_dst *md_dst, u8 optslen)
22 {
23         unsigned long *dst;
24
25         dst = &md_dst->dst;
26         *dst = 0;
27 #if 0
28         dst_init(dst, &md_dst_ops, NULL, 1, DST_OBSOLETE_NONE,
29                         DST_METADATA | DST_NOCACHE | DST_NOCOUNT);
30
31         dst->input = dst_md_discard;
32         dst->output = dst_md_discard_out;
33 #endif
34
35         memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst));
36 }
37
38 static inline struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags)
39 {
40         struct metadata_dst *md_dst;
41
42         md_dst = kmalloc(sizeof(*md_dst) + optslen, flags);
43         if (!md_dst)
44                 return NULL;
45
46         __metadata_dst_init(md_dst, optslen);
47         return md_dst;
48 }
49
50 #define skb_tunnel_info ovs_skb_tunnel_info
51
52 static inline void ovs_tun_rx_dst(struct metadata_dst *md_dst, int optslen)
53 {
54         /* No need to allocate for OVS backport case. */
55 #if 0
56         struct metadata_dst *tun_dst;
57         struct ip_tunnel_info *info;
58
59         tun_dst = metadata_dst_alloc(md_size, GFP_ATOMIC);
60         if (!tun_dst)
61                 return NULL;
62 #endif
63         __metadata_dst_init(md_dst, optslen);
64 }
65
66 static inline void ovs_ip_tun_rx_dst(struct metadata_dst *md_dst,
67                                      struct sk_buff *skb, __be16 flags,
68                                      __be64 tunnel_id, int md_size)
69 {
70         const struct iphdr *iph = ip_hdr(skb);
71
72         ovs_tun_rx_dst(md_dst, md_size);
73         ip_tunnel_key_init(&md_dst->u.tun_info.key,
74                            iph->saddr, iph->daddr, iph->tos, iph->ttl, 0,
75                            0, 0, tunnel_id, flags);
76 }
77
78 static inline void ovs_ipv6_tun_rx_dst(struct metadata_dst *md_dst,
79                                        struct sk_buff *skb,
80                                        __be16 flags,
81                                        __be64 tunnel_id,
82                                        int md_size)
83 {
84         struct ip_tunnel_info *info = &md_dst->u.tun_info;
85         const struct ipv6hdr *ip6h = ipv6_hdr(skb);
86
87         ovs_tun_rx_dst(md_dst, md_size);
88         info->mode = IP_TUNNEL_INFO_IPV6;
89         info->key.tun_flags = flags;
90         info->key.tun_id = tunnel_id;
91         info->key.tp_src = 0;
92         info->key.tp_dst = 0;
93
94         info->key.u.ipv6.src = ip6h->saddr;
95         info->key.u.ipv6.dst = ip6h->daddr;
96
97         info->key.tos = ipv6_get_dsfield(ip6h);
98         info->key.ttl = ip6h->hop_limit;
99         info->key.label = ip6_flowlabel(ip6h);
100 }
101
102 #endif /* USE_UPSTREAM_TUNNEL */
103
104 void ovs_ip_tunnel_rcv(struct net_device *dev, struct sk_buff *skb,
105                       struct metadata_dst *tun_dst);
106 #endif /* __NET_DST_METADATA_WRAPPER_H */