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