kernel: add eoip support

Thx do Developer_MZRIP
This commit is contained in:
Maxim Anisimov
2018-12-27 05:34:26 +00:00
parent cc6335d3e1
commit d047a742a2
6 changed files with 1097 additions and 12 deletions

View File

@ -20,6 +20,14 @@ struct gre_full_hdr {
#define GREPROTO_PPTP 1
#define GREPROTO_MAX 2
/* handle protocols with non-standard GRE header by ids that do not overlap
* with possible standard GRE protocol versions (0x00 - 0x7f)
*/
#define GREPROTO_NONSTD_BASE 0x80
#define GREPROTO_NONSTD_EOIP (0 + GREPROTO_NONSTD_BASE)
#define GREPROTO_NONSTD_MAX (1 + GREPROTO_NONSTD_BASE)
struct gre_protocol {
int (*handler)(struct sk_buff *skb);
void (*err_handler)(struct sk_buff *skb, u32 info);

View File

@ -184,7 +184,7 @@ config NET_IPGRE_DEMUX
tristate "IP: GRE demultiplexer"
help
This is helper module to demultiplex GRE packets on GRE version field criteria.
Required by ip_gre and pptp modules.
Required by ip_gre, pptp and eoip modules.
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
@ -209,6 +209,17 @@ config NET_IPGRE_BROADCAST
Network), but can be distributed all over the Internet. If you want
to do that, say Y here and to "IP multicast routing" below.
config NET_EOIP
tristate "IP: EOIP ethernet tunnels over IP"
depends on (IPV6 || IPV6=n) && NET_IPGRE_DEMUX
help
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
encapsulating protocol. This particular tunneling driver implements
MikroTik RouterOS compatible encapsulation of ethernet frames over
existing IPv4 infrastructure. It is useful if the other endpoint
is a MirkoTik router.
config IP_MROUTE
bool "IP: multicast routing"
depends on IP_MULTICAST

View File

@ -20,6 +20,7 @@ obj-$(CONFIG_IP_MROUTE) += ipmr.o
obj-$(CONFIG_NET_IPIP) += ipip.o
obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
obj-$(CONFIG_NET_IPGRE) += ip_gre.o
obj-$(CONFIG_NET_EOIP) += eoip.o
obj-$(CONFIG_SYN_COOKIES) += syncookies.o
obj-$(CONFIG_INET_AH) += ah4.o
obj-$(CONFIG_INET_ESP) += esp4.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#ifndef __EOIP_VERSION_H__
#define __EOIP_VERSION_H__
#define EOIP_VERSION "1.0-3"
#endif /* __EOIP_VERSION_H__ */

View File

@ -23,14 +23,19 @@
#include <net/protocol.h>
#include <net/gre.h>
#define GREPROTO_CNT \
(GREPROTO_MAX + GREPROTO_NONSTD_MAX - GREPROTO_NONSTD_BASE)
static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly;
static const struct gre_protocol __rcu *gre_proto[GREPROTO_CNT] __read_mostly;
static DEFINE_SPINLOCK(gre_proto_lock);
int gre_add_protocol(const struct gre_protocol *proto, u8 version)
{
if (version >= GREPROTO_MAX)
goto err_out;
if (version >= GREPROTO_NONSTD_BASE && version < GREPROTO_NONSTD_MAX)
version -= GREPROTO_NONSTD_BASE - GREPROTO_MAX;
else
if (version >= GREPROTO_MAX)
goto err_out;
spin_lock(&gre_proto_lock);
if (gre_proto[version])
@ -49,8 +54,11 @@ EXPORT_SYMBOL_GPL(gre_add_protocol);
int gre_del_protocol(const struct gre_protocol *proto, u8 version)
{
if (version >= GREPROTO_MAX)
goto err_out;
if (version >= GREPROTO_NONSTD_BASE && version < GREPROTO_NONSTD_MAX)
version -= GREPROTO_NONSTD_BASE - GREPROTO_MAX;
else
if (version >= GREPROTO_MAX)
goto err_out;
spin_lock(&gre_proto_lock);
if (rcu_dereference_protected(gre_proto[version],
@ -74,12 +82,22 @@ static int gre_rcv(struct sk_buff *skb)
u8 ver;
int ret;
/* the standard GRE header is 12 octets; the EOIP header is 8
* 4 octets long ethernet packet can not be valid
*/
if (!pskb_may_pull(skb, 12))
goto drop;
ver = skb->data[1]&0x7f;
if (ver >= GREPROTO_MAX)
goto drop;
/* check for custom EOIP header */
if (skb->data[0] == 0x20 && skb->data[1] == 0x01 &&
skb->data[2] == 0x64 && skb->data[3] == 0x00)
ver = GREPROTO_NONSTD_EOIP - GREPROTO_NONSTD_BASE
+ GREPROTO_MAX;
else {
ver = skb->data[1]&0x7f;
if (ver >= GREPROTO_MAX)
goto drop;
}
rcu_read_lock();
proto = rcu_dereference(gre_proto[ver]);
@ -100,10 +118,19 @@ static void gre_err(struct sk_buff *skb, u32 info)
{
const struct gre_protocol *proto;
const struct iphdr *iph = (const struct iphdr *)skb->data;
u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
u8 ver;
if (ver >= GREPROTO_MAX)
return;
if (skb->data[(iph->ihl<<2) + 0] == 0x20 &&
skb->data[(iph->ihl<<2) + 1] == 0x01 &&
skb->data[(iph->ihl<<2) + 2] == 0x64 &&
skb->data[(iph->ihl<<2) + 3] == 0x00)
ver = GREPROTO_NONSTD_EOIP - GREPROTO_NONSTD_BASE
+ GREPROTO_MAX;
else {
ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
if (ver >= GREPROTO_MAX)
return;
}
rcu_read_lock();
proto = rcu_dereference(gre_proto[ver]);