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