ip6_tunnel.h 4.7 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
#ifndef _NET_IP6_TUNNEL_H
#define _NET_IP6_TUNNEL_H

#include <linux/ipv6.h>
#include <linux/netdevice.h>
6
#include <linux/if_tunnel.h>
L
Linus Torvalds 已提交
7
#include <linux/ip6_tunnel.h>
8
#include <net/ip_tunnels.h>
9
#include <net/dst_cache.h>
L
Linus Torvalds 已提交
10

X
xeb@mail.ru 已提交
11 12
#define IP6TUNNEL_ERR_TIMEO (30*HZ)

L
Linus Torvalds 已提交
13 14 15 16
/* capable of sending packets */
#define IP6_TNL_F_CAP_XMIT 0x10000
/* capable of receiving packets */
#define IP6_TNL_F_CAP_RCV 0x20000
17 18
/* determine capability on a per-packet basis */
#define IP6_TNL_F_CAP_PER_PACKET 0x40000
L
Linus Torvalds 已提交
19

X
xeb@mail.ru 已提交
20 21 22 23 24 25
struct __ip6_tnl_parm {
	char name[IFNAMSIZ];	/* name of tunnel device */
	int link;		/* ifindex of underlying L2 interface */
	__u8 proto;		/* tunnel protocol */
	__u8 encap_limit;	/* encapsulation limit for tunnel */
	__u8 hop_limit;		/* hop limit for tunnel */
26
	bool collect_md;
X
xeb@mail.ru 已提交
27 28 29 30 31 32 33 34 35
	__be32 flowinfo;	/* traffic class and flowlabel for tunnel */
	__u32 flags;		/* tunnel flags */
	struct in6_addr laddr;	/* local tunnel end-point address */
	struct in6_addr raddr;	/* remote tunnel end-point address */

	__be16			i_flags;
	__be16			o_flags;
	__be32			i_key;
	__be32			o_key;
36 37

	__u32			fwmark;
X
xeb@mail.ru 已提交
38
};
L
Linus Torvalds 已提交
39

X
xeb@mail.ru 已提交
40
/* IPv6 tunnel */
L
Linus Torvalds 已提交
41
struct ip6_tnl {
E
Eric Dumazet 已提交
42
	struct ip6_tnl __rcu *next;	/* next tunnel in list */
L
Linus Torvalds 已提交
43
	struct net_device *dev;	/* virtual device associated with tunnel */
N
Nicolas Dichtel 已提交
44
	struct net *net;	/* netns for packet i/o */
X
xeb@mail.ru 已提交
45
	struct __ip6_tnl_parm parms;	/* tunnel configuration parameters */
L
Linus Torvalds 已提交
46
	struct flowi fl;	/* flowi template for xmit */
47
	struct dst_cache dst_cache;	/* cached dst */
48
	struct gro_cells gro_cells;
X
xeb@mail.ru 已提交
49 50 51 52 53 54 55

	int err_count;
	unsigned long err_time;

	/* These fields used only by GRE */
	__u32 i_seqno;	/* The last seen seqno	*/
	__u32 o_seqno;	/* The last output seqno */
T
Tom Herbert 已提交
56 57
	int hlen;       /* tun_hlen + encap_hlen */
	int tun_hlen;	/* Precalculated header length */
58 59
	int encap_hlen; /* Encap header length (FOU,GUE) */
	struct ip_tunnel_encap encap;
X
xeb@mail.ru 已提交
60
	int mlink;
61
};
T
Tom Herbert 已提交
62

63 64 65 66
struct ip6_tnl_encap_ops {
	size_t (*encap_hlen)(struct ip_tunnel_encap *e);
	int (*build_header)(struct sk_buff *skb, struct ip_tunnel_encap *e,
			    u8 *protocol, struct flowi6 *fl6);
L
Linus Torvalds 已提交
67 68
};

69 70
#ifdef CONFIG_INET

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 108 109 110 111 112 113 114 115 116 117 118 119 120 121
extern const struct ip6_tnl_encap_ops __rcu *
		ip6tun_encaps[MAX_IPTUN_ENCAP_OPS];

int ip6_tnl_encap_add_ops(const struct ip6_tnl_encap_ops *ops,
			  unsigned int num);
int ip6_tnl_encap_del_ops(const struct ip6_tnl_encap_ops *ops,
			  unsigned int num);
int ip6_tnl_encap_setup(struct ip6_tnl *t,
			struct ip_tunnel_encap *ipencap);

static inline int ip6_encap_hlen(struct ip_tunnel_encap *e)
{
	const struct ip6_tnl_encap_ops *ops;
	int hlen = -EINVAL;

	if (e->type == TUNNEL_ENCAP_NONE)
		return 0;

	if (e->type >= MAX_IPTUN_ENCAP_OPS)
		return -EINVAL;

	rcu_read_lock();
	ops = rcu_dereference(ip6tun_encaps[e->type]);
	if (likely(ops && ops->encap_hlen))
		hlen = ops->encap_hlen(e);
	rcu_read_unlock();

	return hlen;
}

static inline int ip6_tnl_encap(struct sk_buff *skb, struct ip6_tnl *t,
				u8 *protocol, struct flowi6 *fl6)
{
	const struct ip6_tnl_encap_ops *ops;
	int ret = -EINVAL;

	if (t->encap.type == TUNNEL_ENCAP_NONE)
		return 0;

	if (t->encap.type >= MAX_IPTUN_ENCAP_OPS)
		return -EINVAL;

	rcu_read_lock();
	ops = rcu_dereference(ip6tun_encaps[t->encap.type]);
	if (likely(ops && ops->build_header))
		ret = ops->build_header(skb, &t->encap, protocol, fl6);
	rcu_read_unlock();

	return ret;
}

L
Linus Torvalds 已提交
122 123 124 125 126 127
/* Tunnel encapsulation limit destination sub-option */

struct ipv6_tlv_tnl_enc_lim {
	__u8 type;		/* type-code for option         */
	__u8 length;		/* option length                */
	__u8 encap_limit;	/* tunnel encapsulation limit   */
E
Eric Dumazet 已提交
128
} __packed;
L
Linus Torvalds 已提交
129

X
xeb@mail.ru 已提交
130 131
int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
		const struct in6_addr *raddr);
132 133 134
int ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
		const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
		bool log_ecn_error);
135 136
int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
		     const struct in6_addr *raddr);
T
Tom Herbert 已提交
137 138
int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
		 struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto);
X
xeb@mail.ru 已提交
139 140 141
__u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw);
__u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
			     const struct in6_addr *raddr);
142
struct net *ip6_tnl_get_link_net(const struct net_device *dev);
143
int ip6_tnl_get_iflink(const struct net_device *dev);
T
Tom Herbert 已提交
144
int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu);
X
xeb@mail.ru 已提交
145

146 147
static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
				  struct net_device *dev)
148 149 150
{
	int pkt_len, err;

151
	memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
152
	pkt_len = skb->len - skb_inner_network_offset(skb);
153
	err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb);
154 155 156
	if (unlikely(net_xmit_eval(err)))
		pkt_len = -1;
	iptunnel_xmit_stats(dev, pkt_len);
157
}
L
Linus Torvalds 已提交
158
#endif
159
#endif