]>
Commit | Line | Data |
---|---|---|
e23775f2 PS |
1 | #ifndef __NET_DST_METADATA_WRAPPER_H |
2 | #define __NET_DST_METADATA_WRAPPER_H 1 | |
3 | ||
1c95839f | 4 | #ifdef USE_UPSTREAM_TUNNEL |
e23775f2 PS |
5 | #include_next <net/dst_metadata.h> |
6 | #else | |
7 | #include <linux/skbuff.h> | |
4431d10a PS |
8 | |
9 | #include <net/dsfield.h> | |
e23775f2 | 10 | #include <net/dst.h> |
4431d10a PS |
11 | #include <net/ipv6.h> |
12 | #include <net/ip_tunnels.h> | |
e23775f2 PS |
13 | |
14 | struct metadata_dst { | |
15 | unsigned long dst; | |
16 | union { | |
17 | struct ip_tunnel_info tun_info; | |
18 | } u; | |
19 | }; | |
20 | ||
4431d10a PS |
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 | ||
e23775f2 PS |
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 | ||
4431d10a | 46 | __metadata_dst_init(md_dst, optslen); |
e23775f2 PS |
47 | return md_dst; |
48 | } | |
4431d10a | 49 | |
e23775f2 | 50 | #define skb_tunnel_info ovs_skb_tunnel_info |
4431d10a | 51 | |
a5d59bf3 | 52 | static inline void ovs_tun_rx_dst(struct metadata_dst *md_dst, int optslen) |
4431d10a PS |
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 | |
a5d59bf3 | 63 | __metadata_dst_init(md_dst, optslen); |
4431d10a PS |
64 | } |
65 | ||
a5d59bf3 PS |
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) | |
e23775f2 PS |
69 | { |
70 | const struct iphdr *iph = ip_hdr(skb); | |
71 | ||
a5d59bf3 PS |
72 | ovs_tun_rx_dst(md_dst, md_size); |
73 | ip_tunnel_key_init(&md_dst->u.tun_info.key, | |
3259c4ff | 74 | iph->saddr, iph->daddr, iph->tos, iph->ttl, 0, |
e23775f2 | 75 | 0, 0, tunnel_id, flags); |
4431d10a PS |
76 | } |
77 | ||
a5d59bf3 | 78 | static inline void ovs_ipv6_tun_rx_dst(struct metadata_dst *md_dst, |
4431d10a PS |
79 | struct sk_buff *skb, |
80 | __be16 flags, | |
81 | __be64 tunnel_id, | |
82 | int md_size) | |
83 | { | |
a5d59bf3 | 84 | struct ip_tunnel_info *info = &md_dst->u.tun_info; |
4431d10a PS |
85 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
86 | ||
a5d59bf3 | 87 | ovs_tun_rx_dst(md_dst, md_size); |
4431d10a PS |
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; | |
3259c4ff | 99 | info->key.label = ip6_flowlabel(ip6h); |
e23775f2 PS |
100 | } |
101 | ||
06aeda48 PS |
102 | #endif /* USE_UPSTREAM_TUNNEL */ |
103 | ||
e23775f2 PS |
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 */ |