linux/include/net/gre.h
<<
>>
Prefs
   1#ifndef __LINUX_GRE_H
   2#define __LINUX_GRE_H
   3
   4#include <linux/skbuff.h>
   5#include <net/ip_tunnels.h>
   6
   7struct gre_base_hdr {
   8        __be16 flags;
   9        __be16 protocol;
  10} __packed;
  11
  12struct gre_full_hdr {
  13        struct gre_base_hdr fixed_header;
  14        __be16 csum;
  15        __be16 reserved1;
  16        __be32 key;
  17        __be32 seq;
  18} __packed;
  19#define GRE_HEADER_SECTION 4
  20
  21#define GREPROTO_CISCO          0
  22#define GREPROTO_PPTP           1
  23#define GREPROTO_MAX            2
  24#define GRE_IP_PROTO_MAX        2
  25
  26struct gre_protocol {
  27        int  (*handler)(struct sk_buff *skb);
  28        void (*err_handler)(struct sk_buff *skb, u32 info);
  29};
  30
  31int gre_add_protocol(const struct gre_protocol *proto, u8 version);
  32int gre_del_protocol(const struct gre_protocol *proto, u8 version);
  33
  34struct net_device *gretap_fb_dev_create(struct net *net, const char *name);
  35int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
  36                     bool *csum_err, __be16 proto, int nhs);
  37
  38static inline int gre_calc_hlen(__be16 o_flags)
  39{
  40        int addend = 4;
  41
  42        if (o_flags & TUNNEL_CSUM)
  43                addend += 4;
  44        if (o_flags & TUNNEL_KEY)
  45                addend += 4;
  46        if (o_flags & TUNNEL_SEQ)
  47                addend += 4;
  48        return addend;
  49}
  50
  51static inline __be16 gre_flags_to_tnl_flags(__be16 flags)
  52{
  53        __be16 tflags = 0;
  54
  55        if (flags & GRE_CSUM)
  56                tflags |= TUNNEL_CSUM;
  57        if (flags & GRE_ROUTING)
  58                tflags |= TUNNEL_ROUTING;
  59        if (flags & GRE_KEY)
  60                tflags |= TUNNEL_KEY;
  61        if (flags & GRE_SEQ)
  62                tflags |= TUNNEL_SEQ;
  63        if (flags & GRE_STRICT)
  64                tflags |= TUNNEL_STRICT;
  65        if (flags & GRE_REC)
  66                tflags |= TUNNEL_REC;
  67        if (flags & GRE_VERSION)
  68                tflags |= TUNNEL_VERSION;
  69
  70        return tflags;
  71}
  72
  73static inline __be16 gre_tnl_flags_to_gre_flags(__be16 tflags)
  74{
  75        __be16 flags = 0;
  76
  77        if (tflags & TUNNEL_CSUM)
  78                flags |= GRE_CSUM;
  79        if (tflags & TUNNEL_ROUTING)
  80                flags |= GRE_ROUTING;
  81        if (tflags & TUNNEL_KEY)
  82                flags |= GRE_KEY;
  83        if (tflags & TUNNEL_SEQ)
  84                flags |= GRE_SEQ;
  85        if (tflags & TUNNEL_STRICT)
  86                flags |= GRE_STRICT;
  87        if (tflags & TUNNEL_REC)
  88                flags |= GRE_REC;
  89        if (tflags & TUNNEL_VERSION)
  90                flags |= GRE_VERSION;
  91
  92        return flags;
  93}
  94
  95static inline __sum16 gre_checksum(struct sk_buff *skb)
  96{
  97        __wsum csum;
  98
  99        if (skb->ip_summed == CHECKSUM_PARTIAL)
 100                csum = lco_csum(skb);
 101        else
 102                csum = skb_checksum(skb, 0, skb->len, 0);
 103        return csum_fold(csum);
 104}
 105
 106static inline void gre_build_header(struct sk_buff *skb, int hdr_len,
 107                                    __be16 flags, __be16 proto,
 108                                    __be32 key, __be32 seq)
 109{
 110        struct gre_base_hdr *greh;
 111
 112        skb_push(skb, hdr_len);
 113
 114        skb_set_inner_protocol(skb, proto);
 115        skb_reset_transport_header(skb);
 116        greh = (struct gre_base_hdr *)skb->data;
 117        greh->flags = gre_tnl_flags_to_gre_flags(flags);
 118        greh->protocol = proto;
 119
 120        if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
 121                __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
 122
 123                if (flags & TUNNEL_SEQ) {
 124                        *ptr = seq;
 125                        ptr--;
 126                }
 127                if (flags & TUNNEL_KEY) {
 128                        *ptr = key;
 129                        ptr--;
 130                }
 131                if (flags & TUNNEL_CSUM &&
 132                    !(skb_shinfo(skb)->gso_type &
 133                      (SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
 134                        *ptr = 0;
 135                        *(__sum16 *)ptr = gre_checksum(skb);
 136                }
 137        }
 138}
 139
 140#endif
 141