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