dst_metadata.h 2.5 KB
Newer Older
T
Thomas Graf 已提交
1 2 3 4 5 6 7 8 9 10
#ifndef __NET_DST_METADATA_H
#define __NET_DST_METADATA_H 1

#include <linux/skbuff.h>
#include <net/ip_tunnels.h>
#include <net/dst.h>

struct metadata_dst {
	struct dst_entry		dst;
	size_t				opts_len;
T
Thomas Graf 已提交
11 12 13
	union {
		struct ip_tunnel_info	tun_info;
	} u;
T
Thomas Graf 已提交
14 15 16 17 18 19 20 21 22 23 24 25
};

static inline struct metadata_dst *skb_metadata_dst(struct sk_buff *skb)
{
	struct metadata_dst *md_dst = (struct metadata_dst *) skb_dst(skb);

	if (md_dst && md_dst->dst.flags & DST_METADATA)
		return md_dst;

	return NULL;
}

26
static inline struct ip_tunnel_info *skb_tunnel_info(struct sk_buff *skb)
T
Thomas Graf 已提交
27 28
{
	struct metadata_dst *md_dst = skb_metadata_dst(skb);
29
	struct dst_entry *dst;
T
Thomas Graf 已提交
30 31 32 33

	if (md_dst)
		return &md_dst->u.tun_info;

34 35 36
	dst = skb_dst(skb);
	if (dst && dst->lwtstate)
		return lwt_tun_info(dst->lwtstate);
37

T
Thomas Graf 已提交
38 39 40
	return NULL;
}

T
Thomas Graf 已提交
41 42 43 44 45 46 47 48
static inline bool skb_valid_dst(const struct sk_buff *skb)
{
	struct dst_entry *dst = skb_dst(skb);

	return dst && !(dst->flags & DST_METADATA);
}

struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
49
struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);
T
Thomas Graf 已提交
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 107
static inline struct metadata_dst *tun_rx_dst(__be16 flags,
					      __be64 tunnel_id, int md_size)
{
	struct metadata_dst *tun_dst;
	struct ip_tunnel_info *info;

	tun_dst = metadata_dst_alloc(md_size, GFP_ATOMIC);
	if (!tun_dst)
		return NULL;

	info = &tun_dst->u.tun_info;
	info->key.tun_flags = flags;
	info->key.tun_id = tunnel_id;
	info->key.tp_src = 0;
	info->key.tp_dst = 0;
	return tun_dst;
}

static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
						 __be16 flags,
						 __be64 tunnel_id,
						 int md_size)
{
	const struct iphdr *iph = ip_hdr(skb);
	struct metadata_dst *tun_dst;
	struct ip_tunnel_info *info;

	tun_dst = tun_rx_dst(flags, tunnel_id, md_size);
	if (!tun_dst)
		return NULL;

	info = &tun_dst->u.tun_info;
	info->key.u.ipv4.src = iph->saddr;
	info->key.u.ipv4.dst = iph->daddr;
	info->key.tos = iph->tos;
	info->key.ttl = iph->ttl;
	return tun_dst;
}

static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
						 __be16 flags,
						 __be64 tunnel_id,
						 int md_size)
{
	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
	struct metadata_dst *tun_dst;
	struct ip_tunnel_info *info;

	tun_dst = tun_rx_dst(flags, tunnel_id, md_size);
	if (!tun_dst)
		return NULL;

	info = &tun_dst->u.tun_info;
	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;
108
	info->mode = IP_TUNNEL_INFO_IPV6;
109 110 111
	return tun_dst;
}

T
Thomas Graf 已提交
112
#endif /* __NET_DST_METADATA_H */