6660dfc72ff23570bd5aadf3d1b1c5c8c00eede9
[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 #endif
52
53 static inline void ovs_tun_rx_dst(struct metadata_dst *md_dst, int optslen)
54 {
55         /* No need to allocate for OVS backport case. */
56 #if 0
57         struct metadata_dst *tun_dst;
58         struct ip_tunnel_info *info;
59
60         tun_dst = metadata_dst_alloc(md_size, GFP_ATOMIC);
61         if (!tun_dst)
62                 return NULL;
63 #endif
64         __metadata_dst_init(md_dst, optslen);
65 }
66
67 static inline void ovs_ip_tun_rx_dst(struct metadata_dst *md_dst,
68                                      struct sk_buff *skb, __be16 flags,
69                                      __be64 tunnel_id, int md_size)
70 {
71         const struct iphdr *iph = ip_hdr(skb);
72
73         ovs_tun_rx_dst(md_dst, md_size);
74         ip_tunnel_key_init(&md_dst->u.tun_info.key,
75                            iph->saddr, iph->daddr, iph->tos, iph->ttl, 0,
76                            0, 0, tunnel_id, flags);
77 }
78
79 static inline void ovs_ipv6_tun_rx_dst(struct metadata_dst *md_dst,
80                                        struct sk_buff *skb,
81                                        __be16 flags,
82                                        __be64 tunnel_id,
83                                        int md_size)
84 {
85         struct ip_tunnel_info *info = &md_dst->u.tun_info;
86         const struct ipv6hdr *ip6h = ipv6_hdr(skb);
87
88         ovs_tun_rx_dst(md_dst, md_size);
89         info->mode = IP_TUNNEL_INFO_IPV6;
90         info->key.tun_flags = flags;
91         info->key.tun_id = tunnel_id;
92         info->key.tp_src = 0;
93         info->key.tp_dst = 0;
94
95         info->key.u.ipv6.src = ip6h->saddr;
96         info->key.u.ipv6.dst = ip6h->daddr;
97
98         info->key.tos = ipv6_get_dsfield(ip6h);
99         info->key.ttl = ip6h->hop_limit;
100         info->key.label = ip6_flowlabel(ip6h);
101 }
102
103 void ovs_ip_tunnel_rcv(struct net_device *dev, struct sk_buff *skb,
104                       struct metadata_dst *tun_dst);
105 #endif /* __NET_DST_METADATA_WRAPPER_H */