^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * GRE over IPv4 demultiplexer driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors: Dmitry Kozlov (xeb@mail.ru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/icmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/if_tunnel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <net/protocol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/gre.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/erspan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/icmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <net/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int gre_add_protocol(const struct gre_protocol *proto, u8 version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (version >= GREPROTO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return (cmpxchg((const struct gre_protocol **)&gre_proto[version], NULL, proto) == NULL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 0 : -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) EXPORT_SYMBOL_GPL(gre_add_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int gre_del_protocol(const struct gre_protocol *proto, u8 version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (version >= GREPROTO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ret = (cmpxchg((const struct gre_protocol **)&gre_proto[version], proto, NULL) == proto) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 0 : -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) EXPORT_SYMBOL_GPL(gre_del_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Fills in tpi and returns header length to be pulled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Note that caller must use pskb_may_pull() before pulling GRE header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bool *csum_err, __be16 proto, int nhs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const struct gre_base_hdr *greh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __be32 *options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int hdr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (unlikely(!pskb_may_pull(skb, nhs + sizeof(struct gre_base_hdr))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) greh = (struct gre_base_hdr *)(skb->data + nhs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) tpi->flags = gre_flags_to_tnl_flags(greh->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) hdr_len = gre_calc_hlen(tpi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!pskb_may_pull(skb, nhs + hdr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) greh = (struct gre_base_hdr *)(skb->data + nhs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) tpi->proto = greh->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) options = (__be32 *)(greh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (greh->flags & GRE_CSUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!skb_checksum_simple_validate(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) skb_checksum_try_convert(skb, IPPROTO_GRE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) null_compute_pseudo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) } else if (csum_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *csum_err = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (greh->flags & GRE_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) tpi->key = *options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) tpi->key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (unlikely(greh->flags & GRE_SEQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) tpi->seq = *options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) options++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) tpi->seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* WCCP version 1 and 2 protocol decoding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * - Change protocol to IPv4/IPv6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 _val, *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) val = skb_header_pointer(skb, nhs + hdr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) sizeof(_val), &_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) tpi->proto = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if ((*val & 0xF0) != 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) hdr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) tpi->hdr_len = hdr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* ERSPAN ver 1 and 2 protocol sets GRE key field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * to 0 and sets the configured key in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * inner erspan header field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if ((greh->protocol == htons(ETH_P_ERSPAN) && hdr_len != 4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) greh->protocol == htons(ETH_P_ERSPAN2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct erspan_base_hdr *ershdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ershdr = (struct erspan_base_hdr *)(skb->data + nhs + hdr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) tpi->key = cpu_to_be32(get_session_id(ershdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return hdr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) EXPORT_SYMBOL(gre_parse_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int gre_rcv(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) const struct gre_protocol *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (!pskb_may_pull(skb, 12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ver = skb->data[1]&0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ver >= GREPROTO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) proto = rcu_dereference(gre_proto[ver]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!proto || !proto->handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) goto drop_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ret = proto->handler(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) drop_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int gre_err(struct sk_buff *skb, u32 info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) const struct gre_protocol *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) const struct iphdr *iph = (const struct iphdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ver >= GREPROTO_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) proto = rcu_dereference(gre_proto[ver]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (proto && proto->err_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) proto->err_handler(skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) err = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static const struct net_protocol net_gre_protocol = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .handler = gre_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .err_handler = gre_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .netns_ok = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int __init gre_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) pr_info("GRE over IPv4 demultiplexor driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pr_err("can't add protocol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static void __exit gre_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) inet_del_protocol(&net_gre_protocol, IPPROTO_GRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) module_init(gre_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) module_exit(gre_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) MODULE_LICENSE("GPL");