Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _NET_IP6_TUNNEL_H
0003 #define _NET_IP6_TUNNEL_H
0004 
0005 #include <linux/ipv6.h>
0006 #include <linux/netdevice.h>
0007 #include <linux/if_tunnel.h>
0008 #include <linux/ip6_tunnel.h>
0009 #include <net/ip_tunnels.h>
0010 #include <net/dst_cache.h>
0011 
0012 #define IP6TUNNEL_ERR_TIMEO (30*HZ)
0013 
0014 /* capable of sending packets */
0015 #define IP6_TNL_F_CAP_XMIT 0x10000
0016 /* capable of receiving packets */
0017 #define IP6_TNL_F_CAP_RCV 0x20000
0018 /* determine capability on a per-packet basis */
0019 #define IP6_TNL_F_CAP_PER_PACKET 0x40000
0020 
0021 struct __ip6_tnl_parm {
0022     char name[IFNAMSIZ];    /* name of tunnel device */
0023     int link;       /* ifindex of underlying L2 interface */
0024     __u8 proto;     /* tunnel protocol */
0025     __u8 encap_limit;   /* encapsulation limit for tunnel */
0026     __u8 hop_limit;     /* hop limit for tunnel */
0027     bool collect_md;
0028     __be32 flowinfo;    /* traffic class and flowlabel for tunnel */
0029     __u32 flags;        /* tunnel flags */
0030     struct in6_addr laddr;  /* local tunnel end-point address */
0031     struct in6_addr raddr;  /* remote tunnel end-point address */
0032 
0033     __be16          i_flags;
0034     __be16          o_flags;
0035     __be32          i_key;
0036     __be32          o_key;
0037 
0038     __u32           fwmark;
0039     __u32           index;  /* ERSPAN type II index */
0040     __u8            erspan_ver; /* ERSPAN version */
0041     __u8            dir;    /* direction */
0042     __u16           hwid;   /* hwid */
0043 };
0044 
0045 /* IPv6 tunnel */
0046 struct ip6_tnl {
0047     struct ip6_tnl __rcu *next; /* next tunnel in list */
0048     struct net_device *dev; /* virtual device associated with tunnel */
0049     netdevice_tracker dev_tracker;
0050     struct net *net;    /* netns for packet i/o */
0051     struct __ip6_tnl_parm parms;    /* tunnel configuration parameters */
0052     struct flowi fl;    /* flowi template for xmit */
0053     struct dst_cache dst_cache; /* cached dst */
0054     struct gro_cells gro_cells;
0055 
0056     int err_count;
0057     unsigned long err_time;
0058 
0059     /* These fields used only by GRE */
0060     __u32 i_seqno;  /* The last seen seqno  */
0061     atomic_t o_seqno;   /* The last output seqno */
0062     int hlen;       /* tun_hlen + encap_hlen */
0063     int tun_hlen;   /* Precalculated header length */
0064     int encap_hlen; /* Encap header length (FOU,GUE) */
0065     struct ip_tunnel_encap encap;
0066     int mlink;
0067 };
0068 
0069 struct ip6_tnl_encap_ops {
0070     size_t (*encap_hlen)(struct ip_tunnel_encap *e);
0071     int (*build_header)(struct sk_buff *skb, struct ip_tunnel_encap *e,
0072                 u8 *protocol, struct flowi6 *fl6);
0073     int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
0074                u8 type, u8 code, int offset, __be32 info);
0075 };
0076 
0077 #ifdef CONFIG_INET
0078 
0079 extern const struct ip6_tnl_encap_ops __rcu *
0080         ip6tun_encaps[MAX_IPTUN_ENCAP_OPS];
0081 
0082 int ip6_tnl_encap_add_ops(const struct ip6_tnl_encap_ops *ops,
0083               unsigned int num);
0084 int ip6_tnl_encap_del_ops(const struct ip6_tnl_encap_ops *ops,
0085               unsigned int num);
0086 int ip6_tnl_encap_setup(struct ip6_tnl *t,
0087             struct ip_tunnel_encap *ipencap);
0088 
0089 static inline int ip6_encap_hlen(struct ip_tunnel_encap *e)
0090 {
0091     const struct ip6_tnl_encap_ops *ops;
0092     int hlen = -EINVAL;
0093 
0094     if (e->type == TUNNEL_ENCAP_NONE)
0095         return 0;
0096 
0097     if (e->type >= MAX_IPTUN_ENCAP_OPS)
0098         return -EINVAL;
0099 
0100     rcu_read_lock();
0101     ops = rcu_dereference(ip6tun_encaps[e->type]);
0102     if (likely(ops && ops->encap_hlen))
0103         hlen = ops->encap_hlen(e);
0104     rcu_read_unlock();
0105 
0106     return hlen;
0107 }
0108 
0109 static inline int ip6_tnl_encap(struct sk_buff *skb, struct ip6_tnl *t,
0110                 u8 *protocol, struct flowi6 *fl6)
0111 {
0112     const struct ip6_tnl_encap_ops *ops;
0113     int ret = -EINVAL;
0114 
0115     if (t->encap.type == TUNNEL_ENCAP_NONE)
0116         return 0;
0117 
0118     if (t->encap.type >= MAX_IPTUN_ENCAP_OPS)
0119         return -EINVAL;
0120 
0121     rcu_read_lock();
0122     ops = rcu_dereference(ip6tun_encaps[t->encap.type]);
0123     if (likely(ops && ops->build_header))
0124         ret = ops->build_header(skb, &t->encap, protocol, fl6);
0125     rcu_read_unlock();
0126 
0127     return ret;
0128 }
0129 
0130 /* Tunnel encapsulation limit destination sub-option */
0131 
0132 struct ipv6_tlv_tnl_enc_lim {
0133     __u8 type;      /* type-code for option         */
0134     __u8 length;        /* option length                */
0135     __u8 encap_limit;   /* tunnel encapsulation limit   */
0136 } __packed;
0137 
0138 int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
0139         const struct in6_addr *raddr);
0140 int ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
0141         const struct tnl_ptk_info *tpi, struct metadata_dst *tun_dst,
0142         bool log_ecn_error);
0143 int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
0144              const struct in6_addr *raddr);
0145 int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
0146          struct flowi6 *fl6, int encap_limit, __u32 *pmtu, __u8 proto);
0147 __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw);
0148 __u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
0149                  const struct in6_addr *raddr);
0150 struct net *ip6_tnl_get_link_net(const struct net_device *dev);
0151 int ip6_tnl_get_iflink(const struct net_device *dev);
0152 int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu);
0153 
0154 static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
0155                   struct net_device *dev)
0156 {
0157     int pkt_len, err;
0158 
0159     memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
0160     pkt_len = skb->len - skb_inner_network_offset(skb);
0161     err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb);
0162 
0163     if (dev) {
0164         if (unlikely(net_xmit_eval(err)))
0165             pkt_len = -1;
0166         iptunnel_xmit_stats(dev, pkt_len);
0167     }
0168 }
0169 #endif
0170 #endif