]> git.proxmox.com Git - ovs.git/blobdiff - datapath/linux/compat/include/net/ip6_tunnel.h
compat: Add ipv6 GRE and IPV6 Tunneling
[ovs.git] / datapath / linux / compat / include / net / ip6_tunnel.h
index b0917d852b0a9ece8e9835b9bb0ea4e387581f54..e0a33a646d6d41609a2c1f0bf61c886b42a2e44e 100644 (file)
-#ifndef _NET_IP6_TUNNEL_WRAPER_H
-#define _NET_IP6_TUNNEL_WRAPER_H
+#ifndef NET_IP6_TUNNEL_WRAPPER_H
+#define NET_IP6_TUNNEL_WRAPPER_H 1
+
+#ifdef HAVE_IP6_TNL_PARM_ERSPAN_VER
+#include_next <net/ip6_tunnel.h>
+#else
 
 #include <linux/ipv6.h>
 #include <linux/netdevice.h>
 #include <linux/if_tunnel.h>
 #include <linux/ip6_tunnel.h>
-#include_next <net/ip6_tunnel.h>
+#include <net/ip_tunnels.h>
+#include <net/dst_cache.h>
+#include <net/dst_metadata.h>
+#include "gso.h"
+
+#define IP6TUNNEL_ERR_TIMEO (30*HZ)
+
+/* capable of sending packets */
+#define IP6_TNL_F_CAP_XMIT 0x10000
+/* capable of receiving packets */
+#define IP6_TNL_F_CAP_RCV 0x20000
+/* determine capability on a per-packet basis */
+#define IP6_TNL_F_CAP_PER_PACKET 0x40000
+
+#ifndef IP6_TNL_F_ALLOW_LOCAL_REMOTE
+#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0
+#endif
+
+struct rpl__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 */
+       bool collect_md;
+       __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;
+
+       __u32                   fwmark;
+       __u32                   index;  /* ERSPAN type II index */
+       __u8                    erspan_ver;     /* ERSPAN version */
+       __u8                    dir;    /* direction */
+       __u16                   hwid;   /* hwid */
+};
+
+#define __ip6_tnl_parm rpl__ip6_tnl_parm
+
+/* IPv6 tunnel */
+struct rpl_ip6_tnl {
+       struct rpl_ip6_tnl __rcu *next; /* next tunnel in list */
+       struct net_device *dev; /* virtual device associated with tunnel */
+       struct net *net;        /* netns for packet i/o */
+       struct __ip6_tnl_parm parms;    /* tunnel configuration parameters */
+       struct flowi fl;        /* flowi template for xmit */
+       struct dst_cache dst_cache;     /* cached dst */
+       struct gro_cells gro_cells;
+
+       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 */
+       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;
+};
+
+#define ip6_tnl rpl_ip6_tnl
+
+struct rpl_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);
+};
+
+#define ip6_tnl_encap_ops rpl_ip6_tnl_encap_ops
+
+#ifdef CONFIG_INET
+
+#ifndef MAX_IPTUN_ENCAP_OPS
+#define MAX_IPTUN_ENCAP_OPS 8
+#endif
+
+extern const struct ip6_tnl_encap_ops __rcu *
+               rpl_ip6tun_encaps[MAX_IPTUN_ENCAP_OPS];
+
+int rpl_ip6_tnl_encap_add_ops(const struct ip6_tnl_encap_ops *ops,
+                             unsigned int num);
+#define ip6_tnl_encap_add_ops rpl_ip6_tnl_encap_add_ops
+int rpl_ip6_tnl_encap_del_ops(const struct ip6_tnl_encap_ops *ops,
+                             unsigned int num);
+#define ip6_tnl_encap_del_ops rpl_ip6_tnl_encap_del_ops 
+int rpl_ip6_tnl_encap_setup(struct ip6_tnl *t,
+                           struct ip_tunnel_encap *ipencap);
+#define ip6_tnl_encap_setup rpl_ip6_tnl_encap_setup
+
+#ifndef HAVE_TUNNEL_ENCAP_TYPES
+enum tunnel_encap_types {
+       TUNNEL_ENCAP_NONE,
+       TUNNEL_ENCAP_FOU,
+       TUNNEL_ENCAP_GUE,
+};
+
+#endif
+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(rpl_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(rpl_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 {
+       __u8 type;              /* type-code for option         */
+       __u8 length;            /* option length                */
+       __u8 encap_limit;       /* tunnel encapsulation limit   */
+} __packed;
+
+int rpl_ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
+                       const struct in6_addr *raddr);
+#define ip6_tnl_rcv_ctl rpl_ip6_tnl_rcv_ctl
+int rpl_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);
+#define ip6_tnl_rcv rpl_ip6_tnl_rcv
+int rpl_ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
+                        const struct in6_addr *raddr);
+#define ip6_tnl_xmit_ctl rpl_ip6_tnl_xmit_ctl
+int rpl_ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+                    struct flowi6 *fl6, int encap_limit, __u32 *pmtu,
+                    __u8 proto);
+#define ip6_tnl_xmit rpl_ip6_tnl_xmit
+__u16 rpl_ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw);
+#define ip6_tnl_parse_tlv_enc_lim rpl_ip6_tnl_parse_tlv_enc_lim
+__u32 rpl_ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
+                         const struct in6_addr *raddr);
+#define ip6_tnl_get_cap rpl_ip6_tnl_get_cap
+struct net *rpl_ip6_tnl_get_link_net(const struct net_device *dev);
+#define ip6_tnl_get_link_net rpl_ip6_tnl_get_link_net
+int rpl_ip6_tnl_get_iflink(const struct net_device *dev);
+#define ip6_tnl_get_iflink rpl_ip6_tnl_get_iflink
+int rpl_ip6_tnl_change_mtu(struct net_device *dev, int new_mtu);
+#define ip6_tnl_change_mtu rpl_ip6_tnl_change_mtu
+
+static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
+                                 struct net_device *dev)
+{
+       int pkt_len, err;
+
+       memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
+       pkt_len = skb->len - skb_inner_network_offset(skb);
+       err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb);
+       if (unlikely(net_xmit_eval(err)))
+               pkt_len = -1;
+       iptunnel_xmit_stats(dev, pkt_len);
+}
+#endif
 
-#define ip6tunnel_xmit rpl_ip6tunnel_xmit
-void rpl_ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
-                   struct net_device *dev);
+#endif /* HAVE_IP6_TNL_PARM_ERSPAN_VER */
 
 #endif