From patchwork Wed Aug 4 10:40:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: xeb@mail.ru X-Patchwork-Id: 60838 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 0E21BB70A4 for ; Wed, 4 Aug 2010 20:43:49 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932478Ab0HDKno (ORCPT ); Wed, 4 Aug 2010 06:43:44 -0400 Received: from fallback3.mail.ru ([94.100.176.58]:41318 "EHLO fallback3.mail.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932295Ab0HDKnn (ORCPT ); Wed, 4 Aug 2010 06:43:43 -0400 Received: from f35.mail.ru (f35.mail.ru [217.69.129.98]) by fallback3.mail.ru (mPOP.Fallback_MX) with ESMTP id D5E822D995B2 for ; Wed, 4 Aug 2010 14:43:40 +0400 (MSD) Received: from mail by f35.mail.ru with local id 1OgbOV-0005IJ-00 for netdev@vger.kernel.org; Wed, 04 Aug 2010 14:40:19 +0400 Received: from [195.24.254.26] by win.mail.ru with HTTP; Wed, 04 Aug 2010 14:40:19 +0400 From: xeb@mail.ru To: netdev@vger.kernel.org Subject: =?koi8-r?Q?PATCH_1/3]_PPTP=3A_PPP_over_IPv4_(Point-to-Point_Tunneling_Protocol)?= Mime-Version: 1.0 X-Mailer: mPOP Web-Mail 2.19 X-Originating-IP: unknown via proxy [195.24.254.26] Date: Wed, 04 Aug 2010 14:40:19 +0400 Reply-To: xeb@mail.ru Message-Id: X-Spam: Not detected X-Mras: Ok Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This is patch 1/3 which contains gre demultiplexer driver source for demultiplexing gre packets with different gre version. --- include/net/gre.h | 18 ++++++ net/ipv4/Kconfig | 7 +++ net/ipv4/Makefile | 1 + net/ipv4/gre.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 0 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/net/gre.h b/include/net/gre.h new file mode 100644 index 0000000..31a0f76 --- /dev/null +++ b/include/net/gre.h @@ -0,0 +1,18 @@ +#ifndef __LINUX_GRE_H +#define __LINUX_GRE_H + +#include + +#define GREPROTO_CISCO 0 +#define GREPROTO_PPTP 1 +#define GREPROTO_MAX 2 + +struct gre_protocol { + int (*handler)(struct sk_buff *skb); + void (*err_handler)(struct sk_buff *skb, u32 info); +}; + +int gre_add_protocol(const struct gre_protocol *proto, u8 version); +int gre_del_protocol(const struct gre_protocol *proto, u8 version); + +#endif diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 7c3a7d1..7458bda 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -215,8 +215,15 @@ config NET_IPIP be inserted in and removed from the running kernel whenever you want). Most people won't need this and can say N. +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. + config NET_IPGRE tristate "IP: GRE tunnels over IP" + depends on NET_IPGRE_DEMUX help Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 80ff87c..4978d22 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o 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_SYN_COOKIES) += syncookies.o obj-$(CONFIG_INET_AH) += ah4.o diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c new file mode 100644 index 0000000..993f3cf --- /dev/null +++ b/net/ipv4/gre.c @@ -0,0 +1,151 @@ +/* + * GRE over IPv4 demultiplexer driver + * + * Authors: Dmitry Kozlov (xeb@mail.ru) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const struct gre_protocol *gre_proto[GREPROTO_MAX] ____cacheline_aligned_in_smp; +static DEFINE_RWLOCK(gre_proto_lock); + +int gre_add_protocol(const struct gre_protocol *proto, u8 version) +{ + int ret; + + if (version >= GREPROTO_MAX) + return -1; + + write_lock_bh(&gre_proto_lock); + if (gre_proto[version]) { + ret = -1; + } else { + gre_proto[version]=proto; + ret = 0; + } + write_unlock_bh(&gre_proto_lock); + + return ret; +} +int gre_del_protocol(const struct gre_protocol *proto, u8 version) +{ + int ret; + + if (version >= GREPROTO_MAX) + return -1; + + write_lock_bh(&gre_proto_lock); + if (gre_proto[version] == proto) { + gre_proto[version] = NULL; + ret = 0; + } else { + ret = -1; + } + write_unlock_bh(&gre_proto_lock); + + return ret; +} +static int gre_rcv(struct sk_buff *skb) +{ + u8 ver; + int ret; + + if (!pskb_may_pull(skb, 12)) + goto drop_nolock; + + ver = skb->data[1]&0x7f; + if (ver >= GREPROTO_MAX) + goto drop_nolock; + + read_lock(&gre_proto_lock); + if (!gre_proto[ver] || !gre_proto[ver]->handler) + goto drop; + + ret = gre_proto[ver]->handler(skb); + read_unlock(&gre_proto_lock); + + return ret; + +drop: + read_unlock(&gre_proto_lock); +drop_nolock: + kfree_skb(skb); + return NET_RX_DROP; +} +static void gre_err(struct sk_buff *skb, u32 info) +{ + u8 ver; + + printk("err\n"); + + if (!pskb_may_pull(skb, 12)) + goto drop_nolock; + + ver=skb->data[1]; + if (ver>=GREPROTO_MAX) + goto drop_nolock; + + read_lock(&gre_proto_lock); + if (!gre_proto[ver] || !gre_proto[ver]->err_handler) + goto drop; + + gre_proto[ver]->err_handler(skb,info); + read_unlock(&gre_proto_lock); + + return; + +drop: + read_unlock(&gre_proto_lock); +drop_nolock: + kfree_skb(skb); +} + + +static struct net_protocol net_gre_protocol = { + .handler = gre_rcv, + .err_handler = gre_err, +// .netns_ok=1, +}; + +static int __init gre_init(void) +{ + printk(KERN_INFO "GRE over IPv4 demultiplexor driver"); + + if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) { + printk(KERN_INFO "gre: can't add protocol\n"); + return -EAGAIN; + } + + return 0; +} + +static void __exit gre_exit(void) +{ + inet_del_protocol(&net_gre_protocol, IPPROTO_GRE); +} + +module_init(gre_init); +module_exit(gre_exit); + +MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver"); +MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); +MODULE_LICENSE("GPL"); +EXPORT_SYMBOL_GPL(gre_add_protocol); +EXPORT_SYMBOL_GPL(gre_del_protocol);