ip6_tun: Add infrastructure for doing encapsulation
Add encap_hlen and ip_tunnel_encap structure to ip6_tnl. Add functions for getting encap hlen, setting up encap on a tunnel, performing encapsulation operation. Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
5f914b6812
commit
058214a4d1
@@ -52,10 +52,68 @@ struct ip6_tnl {
|
||||
__u32 o_seqno; /* The last output seqno */
|
||||
int hlen; /* tun_hlen + encap_hlen */
|
||||
int tun_hlen; /* Precalculated header length */
|
||||
int encap_hlen; /* Encap header length (FOU,GUE) */
|
||||
struct ip_tunnel_encap encap;
|
||||
int mlink;
|
||||
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Tunnel encapsulation limit destination sub-option */
|
||||
|
||||
struct ipv6_tlv_tnl_enc_lim {
|
||||
|
Reference in New Issue
Block a user