1 /* SPDX-License-Identifier: GPL-2.0 */
5 #include <linux/skbuff.h>
6 #include <net/ip_tunnels.h>
14 struct gre_base_hdr fixed_header
;
20 #define GRE_HEADER_SECTION 4
22 #define GREPROTO_CISCO 0
23 #define GREPROTO_PPTP 1
24 #define GREPROTO_MAX 2
25 #define GRE_IP_PROTO_MAX 2
28 int (*handler
)(struct sk_buff
*skb
);
29 void (*err_handler
)(struct sk_buff
*skb
, u32 info
);
32 int gre_add_protocol(const struct gre_protocol
*proto
, u8 version
);
33 int gre_del_protocol(const struct gre_protocol
*proto
, u8 version
);
35 struct net_device
*gretap_fb_dev_create(struct net
*net
, const char *name
,
37 int gre_parse_header(struct sk_buff
*skb
, struct tnl_ptk_info
*tpi
,
38 bool *csum_err
, __be16 proto
, int nhs
);
40 static inline bool netif_is_gretap(const struct net_device
*dev
)
42 return dev
->rtnl_link_ops
&&
43 !strcmp(dev
->rtnl_link_ops
->kind
, "gretap");
46 static inline bool netif_is_ip6gretap(const struct net_device
*dev
)
48 return dev
->rtnl_link_ops
&&
49 !strcmp(dev
->rtnl_link_ops
->kind
, "ip6gretap");
52 static inline int gre_calc_hlen(const unsigned long *o_flags
)
56 if (test_bit(IP_TUNNEL_CSUM_BIT
, o_flags
))
58 if (test_bit(IP_TUNNEL_KEY_BIT
, o_flags
))
60 if (test_bit(IP_TUNNEL_SEQ_BIT
, o_flags
))
65 static inline void gre_flags_to_tnl_flags(unsigned long *dst
, __be16 flags
)
67 IP_TUNNEL_DECLARE_FLAGS(res
) = { };
69 __assign_bit(IP_TUNNEL_CSUM_BIT
, res
, flags
& GRE_CSUM
);
70 __assign_bit(IP_TUNNEL_ROUTING_BIT
, res
, flags
& GRE_ROUTING
);
71 __assign_bit(IP_TUNNEL_KEY_BIT
, res
, flags
& GRE_KEY
);
72 __assign_bit(IP_TUNNEL_SEQ_BIT
, res
, flags
& GRE_SEQ
);
73 __assign_bit(IP_TUNNEL_STRICT_BIT
, res
, flags
& GRE_STRICT
);
74 __assign_bit(IP_TUNNEL_REC_BIT
, res
, flags
& GRE_REC
);
75 __assign_bit(IP_TUNNEL_VERSION_BIT
, res
, flags
& GRE_VERSION
);
77 ip_tunnel_flags_copy(dst
, res
);
80 static inline __be16
gre_tnl_flags_to_gre_flags(const unsigned long *tflags
)
84 if (test_bit(IP_TUNNEL_CSUM_BIT
, tflags
))
86 if (test_bit(IP_TUNNEL_ROUTING_BIT
, tflags
))
88 if (test_bit(IP_TUNNEL_KEY_BIT
, tflags
))
90 if (test_bit(IP_TUNNEL_SEQ_BIT
, tflags
))
92 if (test_bit(IP_TUNNEL_STRICT_BIT
, tflags
))
94 if (test_bit(IP_TUNNEL_REC_BIT
, tflags
))
96 if (test_bit(IP_TUNNEL_VERSION_BIT
, tflags
))
102 static inline void gre_build_header(struct sk_buff
*skb
, int hdr_len
,
103 const unsigned long *flags
, __be16 proto
,
104 __be32 key
, __be32 seq
)
106 IP_TUNNEL_DECLARE_FLAGS(cond
) = { };
107 struct gre_base_hdr
*greh
;
109 skb_push(skb
, hdr_len
);
111 skb_set_inner_protocol(skb
, proto
);
112 skb_reset_transport_header(skb
);
113 greh
= (struct gre_base_hdr
*)skb
->data
;
114 greh
->flags
= gre_tnl_flags_to_gre_flags(flags
);
115 greh
->protocol
= proto
;
117 __set_bit(IP_TUNNEL_KEY_BIT
, cond
);
118 __set_bit(IP_TUNNEL_CSUM_BIT
, cond
);
119 __set_bit(IP_TUNNEL_SEQ_BIT
, cond
);
121 if (ip_tunnel_flags_intersect(flags
, cond
)) {
122 __be32
*ptr
= (__be32
*)(((u8
*)greh
) + hdr_len
- 4);
124 if (test_bit(IP_TUNNEL_SEQ_BIT
, flags
)) {
128 if (test_bit(IP_TUNNEL_KEY_BIT
, flags
)) {
132 if (test_bit(IP_TUNNEL_CSUM_BIT
, flags
) &&
133 !(skb_shinfo(skb
)->gso_type
&
134 (SKB_GSO_GRE
| SKB_GSO_GRE_CSUM
))) {
136 if (skb
->ip_summed
== CHECKSUM_PARTIAL
) {
137 *(__sum16
*)ptr
= csum_fold(lco_csum(skb
));
139 skb
->ip_summed
= CHECKSUM_PARTIAL
;
140 skb
->csum_start
= skb_transport_header(skb
) - skb
->head
;
141 skb
->csum_offset
= sizeof(*greh
);