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