* Re: NET_NS: unregister_netdevice: waiting for lo to become free (after using openvpn)
From: Eric W. Biederman @ 2010-08-05 9:51 UTC (permalink / raw)
To: Michael Leun
Cc: Greg KH, netdev, davem, linux-kernel, Alexey Dobriyan,
Patrick McHardy
In-Reply-To: <20100805112538.60a46cb1@xenia.leun.net>
Michael Leun <lkml20100708@newton.leun.net> writes:
> Hi,
>
> On Wed, 04 Aug 2010 17:12:29 -0700
> ebiederm@xmission.com (Eric W. Biederman) wrote:
>
> First, thank you very much for picking that up (and, of course, for
> your work at linux in general).
>
>
>> > # > unshare -n /bin/bash
>> > # > # how to setup veth device pair to get connectivity into
>> > namespace not shown here # > openvpn --config some.config
>> > [ running some traffic over vpn device not shown here ]
>> > ^c # stopping openvpn
>> > # > lsof -i
>> > # > netstat -an
>> > Active Internet connections (servers and established)
>> > Proto Recv-Q Send-Q Local Address Foreign Address
>> > State Active UNIX domain sockets (servers and established)
>> > Proto RefCnt Flags Type State I-Node Path
>> > # > ps ax|grep openvpn|grep -v grep
>> > # > # cannot find anything that suggests there is anything left
>> > from that openvpn session # > exit # logging out from shell in
>> > network namespace
>> >
>> > Now I get
>> >
>> > Jul 10 20:02:36 doris kernel: unregister_netdevice: waiting for lo
>> > to become free. Usage count = 3 [repeated]
>>
>> How many times?
>
> Unfortunately looks like indefinitely. Never watched longer so far
> (rebooted soon), but I'm seeing this message now repeated every 10 secs
> for ~10 minutes on a idle system.
Ugh. A real bug then. These can be a pain to track down and fix. I
think the last one of these I tracked down took a couple of weeks. I
will start digging in when I get back from vacation.
> Additionally when testing this I found another one (by accident started
> my firewall script in that namespace...) - using netfilter RECENT
> makes it barf. Stripped down to the essentials it looks like this:
Micheal this is on 2.6.35?
Alexey can you look at this BUG_ON? It looks like there has been a regression
or you missed something when you did the netns conversion of xt_recent.
>> # unshare -n /bin/bash
>> # iptables -I INPUT -d 1.2.3.4 -m recent --name BLA --set
>> # exit
>
> Aug 5 11:19:47 doris kernel: [ 218.420238] ------------[ cut here ]------------
> Aug 5 11:19:47 doris kernel: [ 218.420256] kernel BUG at net/netfilter/xt_recent.c:609!
> Aug 5 11:19:47 doris kernel: [ 218.420268] invalid opcode: 0000 [#1] PREEMPT SMP
> Aug 5 11:19:47 doris kernel: [ 218.420284] last sysfs file: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0A:00/power_supply/BAT0/charge_full
> Aug 5 11:19:47 doris kernel: [ 218.420295] Modules linked in: snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device edd cpufreq_conservative cpufreq_userspace cpufreq_powersave acpi_cpufreq mperf ipt_REJECT ipt_LOG xt_limit xt_recent iptable_mangle iptable_nat iptable_filter nf_conntrack_ipv6 xt_state xt_tcpudp ip6table_filter ip6_tables nf_nat_ftp nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_ftp nf_conntrack ip_tables x_tables fuse nls_utf8 loop arc4 ecb iwlagn iwlcore mac80211 snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_pcm cfg80211 snd_timer snd usb_storage iTCO_wdt soundcore tg3 sg iTCO_vendor_support snd_page_alloc rfkill i2c_i801 pcspkr battery ac ext4 jbd2 crc16 sha256_generic aes_generic cbc dm_crypt linear i915 drm_kms_helper drm i2c_algo_bit sd_mod vide
o intel_agp button dm_snapshot dm_mod fan processor ata_piix ahci libahci libata scsi_mod thermal thermal_sys
> Aug 5 11:19:47 doris kernel: [ 218.420529]
> Aug 5 11:19:47 doris kernel: [ 218.420542] Pid: 13, comm: netns Not tainted 2.6.35 #2 Kuril /40684JG
> Aug 5 11:19:47 doris kernel: [ 218.420557] EIP: 0060:[<fc886a15>] EFLAGS: 00010206 CPU: 0
> Aug 5 11:19:47 doris kernel: [ 218.420578] EIP is at recent_net_exit+0x55/0x70 [xt_recent]
> Aug 5 11:19:47 doris kernel: [ 218.420589] EAX: f2218000 EBX: f5b79290 ECX: f2f27b40 EDX: f5cd4000
> Aug 5 11:19:47 doris kernel: [ 218.420601] ESI: f2218000 EDI: f5cd5f44 EBP: f5cd5f28 ESP: f5cd5f20
> Aug 5 11:19:47 doris kernel: [ 218.420612] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
> Aug 5 11:19:47 doris kernel: [ 218.420626] Process netns (pid: 13, ti=f5cd4000 task=f5cc9920 task.ti=f5cd4000)
> Aug 5 11:19:47 doris kernel: [ 218.420635] Stack:
> Aug 5 11:19:47 doris kernel: [ 218.420641] f5cd5f30 fc887618 f5cd5f3c c130867d fc887618 f5cd5f44 c1308850 f5cd5f60
> Aug 5 11:19:47 doris kernel: [ 218.420667] <0> c1308919 f2218014 f2218014 f221800c f221800c c15915a0 c3bb4f40 c1308850
> Aug 5 11:19:47 doris kernel: [ 218.420695] <0> f5cd5fbc c105a230 c13d1658 00000001 00000000 f7048000 c160f500 f5cc9c00
> Aug 5 11:19:47 doris kernel: [ 218.420724] Call Trace:
> Aug 5 11:19:47 doris kernel: [ 218.420749] [<c130867d>] ? ops_exit_list+0x1d/0x50
> Aug 5 11:19:47 doris kernel: [ 218.420766] [<c1308850>] ? cleanup_net+0x0/0x160
> Aug 5 11:19:47 doris kernel: [ 218.420782] [<c1308919>] ? cleanup_net+0xc9/0x160
> Aug 5 11:19:47 doris kernel: [ 218.420797] [<c1308850>] ? cleanup_net+0x0/0x160
> Aug 5 11:19:47 doris kernel: [ 218.420815] [<c105a230>] ? worker_thread+0x110/0x250
> Aug 5 11:19:47 doris kernel: [ 218.420832] [<c13d1658>] ? schedule+0x748/0x7a0
> Aug 5 11:19:47 doris kernel: [ 218.420849] [<c105d5f0>] ? autoremove_wake_function+0x0/0x40
> Aug 5 11:19:47 doris kernel: [ 218.420864] [<c105a120>] ? worker_thread+0x0/0x250
> Aug 5 11:19:47 doris kernel: [ 218.420879] [<c105d1bc>] ? kthread+0x6c/0x80
> Aug 5 11:19:47 doris kernel: [ 218.420895] [<c105d150>] ? kthread+0x0/0x80
> Aug 5 11:19:47 doris kernel: [ 218.420910] [<c1003336>] ? kernel_thread_helper+0x6/0x10
> Aug 5 11:19:47 doris kernel: [ 218.420919] Code: 91 08 89 e2 81 e2 00 e0 ff ff 83 6a 14 01 f6 42 08 08 75 19 3b 1b 75 13 ba fa 72 88 fc e8 94 3e 8c c4 8d 64 24 04 5b 5d c3 0f 0b <0f> 0b 89 45 f8 e8 a1 ad b4 c4 8b 45 f8 eb da 8d b6 00 00 00 00
> Aug 5 11:19:47 doris kernel: [ 218.421063] EIP: [<fc886a15>] recent_net_exit+0x55/0x70 [xt_recent] SS:ESP 0068:f5cd5f20
> Aug 5 11:19:47 doris kernel: [ 218.421136] ---[ end trace f57524f15f4df616 ]---
>
Eric
^ permalink raw reply
* [PATCH v2 3/3] PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)
From: Dmitry Kozlov @ 2010-08-05 9:39 UTC (permalink / raw)
To: netdev
This is patch 3/3 which contains MAINTAINERS file modification.
---
MAINTAINERS | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 02f75fc..191d7c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6450,6 +6450,20 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org>
S: Maintained
F: drivers/serial/zs.*
+GRE DEMULTIPLEXER DRIVER
+M: Dmitry Kozlov <D.Kozlov@protek-vrn.ru>
+L: netdev@vger.kernel.org
+S: Maintained
+F: net/ipv4/gre.c
+F: include/net/gre.h
+
+PPTP DRIVER
+M: Dmitry Kozlov <D.Kozlov@protek-vrn.ru>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/pptp.c
+W: http://sourceforge.net/projects/accel-pptp
+
THE REST
M: Linus Torvalds <torvalds@linux-foundation.org>
L: linux-kernel@vger.kernel.org
^ permalink raw reply related
* [patch] isdn: fix information leak
From: Dan Carpenter @ 2010-08-05 9:38 UTC (permalink / raw)
To: Karsten Keil; +Cc: netdev, kernel-janitors
The main motivation of this patch changing strcpy() to strlcpy().
We strcpy() to copy a 48 byte buffers into a 49 byte buffers. So at
best the last byte has leaked information, or maybe there is an
overflow? Anyway, this patch closes the information leaks by zeroing
the memory and the calls to strlcpy() prevent overflows.
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c
index 1081091..2655e3a 100644
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -174,7 +174,7 @@ int sc_ioctl(int card, scs_ioctl *data)
pr_debug("%s: SCIOGETSPID: ioctl received\n",
sc_adapter[card]->devicename);
- spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
+ spid = kzalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
if (!spid) {
kfree(rcvmsg);
return -ENOMEM;
@@ -194,7 +194,7 @@ int sc_ioctl(int card, scs_ioctl *data)
kfree(rcvmsg);
return status;
}
- strcpy(spid, rcvmsg->msg_data.byte_array);
+ strlcpy(spid, rcvmsg->msg_data.byte_array, SCIOC_SPIDSIZE);
/*
* Package the switch type and send to user space
@@ -272,12 +272,12 @@ int sc_ioctl(int card, scs_ioctl *data)
return status;
}
- dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL);
+ dn = kzalloc(SCIOC_DNSIZE, GFP_KERNEL);
if (!dn) {
kfree(rcvmsg);
return -ENOMEM;
}
- strcpy(dn, rcvmsg->msg_data.byte_array);
+ strlcpy(dn, rcvmsg->msg_data.byte_array, SCIOC_DNSIZE);
kfree(rcvmsg);
/*
@@ -348,7 +348,7 @@ int sc_ioctl(int card, scs_ioctl *data)
pr_debug("%s: SCIOSTAT: ioctl received\n",
sc_adapter[card]->devicename);
- bi = kmalloc (sizeof(boardInfo), GFP_KERNEL);
+ bi = kzalloc(sizeof(boardInfo), GFP_KERNEL);
if (!bi) {
kfree(rcvmsg);
return -ENOMEM;
^ permalink raw reply related
* [PATCH v2 2/3] PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)
From: Dmitry Kozlov @ 2010-08-05 9:38 UTC (permalink / raw)
To: netdev
This is patch 2/3 which contains pptp driver source.
---
drivers/net/Kconfig | 11 +
drivers/net/Makefile | 1 +
drivers/net/pptp.c | 826 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/if_pppox.h | 20 +-
4 files changed, 857 insertions(+), 1 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ce2fcdd..2fa0516 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -3167,6 +3167,17 @@ config PPPOE
which contains instruction on how to use this driver (under
the heading "Kernel mode PPPoE").
+config PPTP
+ tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX
+ help
+ Support for PPP over IPv4.(Point-to-Point Tunneling Protocol)
+
+ This driver requires pppd plugin to work in client mode or
+ modified pptpd (poptop) to work in server mode.
+ See http://accel-pptp.sourceforge.net/ for information how to
+ utilize this module.
+
config PPPOATM
tristate "PPP over ATM"
depends on ATM && PPP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0a0512a..b33fef1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -162,6 +162,7 @@ obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_PPPOL2TP) += pppox.o
+obj-$(CONFIG_PPTP) += pppox.o pptp.o
obj-$(CONFIG_SLIP) += slip.o
obj-$(CONFIG_SLHC) += slhc.o
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c
new file mode 100644
index 0000000..c619fc1
--- /dev/null
+++ b/drivers/net/pptp.c
@@ -0,0 +1,826 @@
+/*
+ * Point-to-Point Tunneling Protocol for Linux
+ *
+ * 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 <linux/string.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/ppp_channel.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_pppox.h>
+#include <linux/if_ppp.h>
+#include <linux/notifier.h>
+#include <linux/file.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/version.h>
+//#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/semaphore.h>
+
+
+#include <net/sock.h>
+#include <net/protocol.h>
+#include <net/ip.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <net/gre.h>
+
+#include <asm/uaccess.h>
+
+#define DEBUG
+
+#define PPTP_DRIVER_VERSION "0.8.4"
+
+static int log_level = 0;
+static int log_packets = 10;
+
+#define MAX_CALLID 65535
+#define PPP_LCP_ECHOREQ 0x09
+#define PPP_LCP_ECHOREP 0x0A
+#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
+
+static unsigned long *callid_bitmap = NULL;
+static struct pppox_sock **callid_sock=NULL;
+
+
+static DECLARE_MUTEX(chan_lock);
+
+static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb);
+static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
+ unsigned long arg);
+static int pptp_rcv_core(struct sock *sk,struct sk_buff *skb);
+
+static struct ppp_channel_ops pptp_chan_ops = {
+ .start_xmit = pptp_xmit,
+ .ioctl = pptp_ppp_ioctl,
+};
+
+
+#define MISSING_WINDOW 20
+#define WRAPPED( curseq, lastseq) \
+ ((((curseq) & 0xffffff00) == 0) && \
+ (((lastseq) & 0xffffff00 ) == 0xffffff00))
+
+/* gre header structure: -------------------------------------------- */
+
+#define PPTP_GRE_PROTO 0x880B
+#define PPTP_GRE_VER 0x1
+
+#define PPTP_GRE_FLAG_C 0x80
+#define PPTP_GRE_FLAG_R 0x40
+#define PPTP_GRE_FLAG_K 0x20
+#define PPTP_GRE_FLAG_S 0x10
+#define PPTP_GRE_FLAG_A 0x80
+
+#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C)
+#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R)
+#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K)
+#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S)
+#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A)
+
+#define PPTP_HEADER_OVERHEAD (2+sizeof(struct pptp_gre_header))
+struct pptp_gre_header {
+ u8 flags; /* bitfield */
+ u8 ver; /* should be PPTP_GRE_VER (enhanced GRE) */
+ u16 protocol; /* should be PPTP_GRE_PROTO (ppp-encaps) */
+ u16 payload_len; /* size of ppp payload, not inc. gre header */
+ u16 call_id; /* peer's call_id for this session */
+ u32 seq; /* sequence number. Present if S==1 */
+ u32 ack; /* seq number of highest packet recieved by */
+ /* sender in this session */
+};
+
+static struct pppox_sock * lookup_chan(__u16 call_id, __be32 s_addr)
+{
+ struct pppox_sock *sock;
+ struct pptp_opt *opt;
+
+ rcu_read_lock();
+ sock = rcu_dereference(callid_sock[call_id]);
+ if (sock) {
+ opt = &sock->proto.pptp;
+ if (opt->dst_addr.sin_addr.s_addr != s_addr) sock = NULL;
+ else sock_hold(sk_pppox(sock));
+ }
+ rcu_read_unlock();
+
+ return sock;
+}
+
+static int lookup_chan_dst(__u16 call_id, __be32 d_addr)
+{
+ struct pppox_sock *sock;
+ struct pptp_opt *opt;
+ int i;
+
+ down(&chan_lock);
+ for(i = find_next_bit(callid_bitmap,MAX_CALLID,1); i < MAX_CALLID; i = find_next_bit(callid_bitmap,MAX_CALLID,i+1)) {
+ sock = callid_sock[i];
+ opt = &sock->proto.pptp;
+ if (opt->dst_addr.call_id == call_id && opt->dst_addr.sin_addr.s_addr == d_addr) break;
+ }
+ up(&chan_lock);
+
+ return i < MAX_CALLID;
+}
+
+static int add_chan(struct pppox_sock *sock)
+{
+ static int call_id = 0;
+ int res = -1;
+
+ synchronize_rcu();
+
+ down(&chan_lock);
+ if (!sock->proto.pptp.src_addr.call_id) {
+ call_id = find_next_zero_bit(callid_bitmap,MAX_CALLID,call_id+1);
+ if (call_id == MAX_CALLID)
+ call_id = find_next_zero_bit(callid_bitmap,MAX_CALLID,1);
+ sock->proto.pptp.src_addr.call_id = call_id;
+ } else if (test_bit(sock->proto.pptp.src_addr.call_id,callid_bitmap))
+ goto exit;
+
+ set_bit(sock->proto.pptp.src_addr.call_id,callid_bitmap);
+ rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id],sock);
+ res = 0;
+
+exit:
+ up(&chan_lock);
+
+ return res;
+}
+
+static void del_chan(struct pppox_sock *sock)
+{
+ synchronize_rcu();
+
+ down(&chan_lock);
+ clear_bit(sock->proto.pptp.src_addr.call_id,callid_bitmap);
+ rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id],NULL);
+ up(&chan_lock);
+}
+
+static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
+{
+ struct sock *sk = (struct sock *) chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ struct pptp_gre_header *hdr;
+ unsigned int header_len = sizeof(*hdr);
+ int err = 0;
+ int islcp;
+ int len;
+ unsigned char *data;
+ __u32 seq_recv;
+
+
+ struct rtable *rt; /* Route to the other host */
+ struct net_device *tdev; /* Device to other host */
+ struct iphdr *iph; /* Our new IP header */
+ int max_headroom; /* The extra header space needed */
+
+ if (sk_pppox(po)->sk_state & PPPOX_DEAD)
+ goto tx_error;
+
+ {
+ struct flowi fl = { .oif = 0,
+ .nl_u = { .ip4_u =
+ { .daddr = opt->dst_addr.sin_addr.s_addr,
+ .saddr = opt->src_addr.sin_addr.s_addr,
+ .tos = RT_TOS(0) } },
+ .proto = IPPROTO_GRE };
+ if ((err=ip_route_output_key(&init_net,&rt, &fl))) {
+ goto tx_error;
+ }
+ }
+ tdev = rt->u.dst.dev;
+
+ max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph)+sizeof(*hdr)+2;
+
+ if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (!new_skb) {
+ ip_rt_put(rt);
+ goto tx_error;
+ }
+ if (skb->sk)
+ skb_set_owner_w(new_skb, skb->sk);
+ kfree_skb(skb);
+ skb = new_skb;
+ }
+
+ data = skb->data;
+ islcp = ((data[0] << 8) + data[1])== PPP_LCP && 1 <= data[2] && data[2] <= 7;
+
+ /* compress protocol field */
+ if ((opt->ppp_flags & SC_COMP_PROT) && data[0] == 0 && !islcp)
+ skb_pull(skb,1);
+
+ /*
+ * Put in the address/control bytes if necessary
+ */
+ if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) {
+ data = skb_push(skb,2);
+ data[0] = PPP_ALLSTATIONS;
+ data[1] = PPP_UI;
+ }
+
+ len = skb->len;
+
+ seq_recv = opt->seq_recv;
+
+ if (opt->ack_sent == seq_recv) header_len -= sizeof(hdr->ack);
+
+ // Push down and install GRE header
+ skb_push(skb,header_len);
+ hdr = (struct pptp_gre_header *)(skb->data);
+
+ hdr->flags = PPTP_GRE_FLAG_K;
+ hdr->ver = PPTP_GRE_VER;
+ hdr->protocol = htons(PPTP_GRE_PROTO);
+ hdr->call_id = htons(opt->dst_addr.call_id);
+
+ hdr->flags |= PPTP_GRE_FLAG_S;
+ hdr->seq = htonl(++opt->seq_sent);
+ #ifdef DEBUG
+ if (log_level >= 3 && opt->seq_sent <= log_packets)
+ printk(KERN_INFO"PPTP[%i]: send packet: seq=%i",opt->src_addr.call_id,opt->seq_sent);
+ #endif
+ if (opt->ack_sent != seq_recv) {
+ /* send ack with this message */
+ hdr->ver |= PPTP_GRE_FLAG_A;
+ hdr->ack = htonl(seq_recv);
+ opt->ack_sent = seq_recv;
+ #ifdef DEBUG
+ if (log_level >= 3 && opt->seq_sent <= log_packets)
+ printk(" ack=%i",seq_recv);
+ #endif
+ }
+ hdr->payload_len = htons(len);
+ #ifdef DEBUG
+ if (log_level >= 3 && opt->seq_sent <= log_packets)
+ printk("\n");
+ #endif
+
+ /*
+ * Push down and install the IP header.
+ */
+
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*iph));
+ skb_reset_network_header(skb);
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED);
+
+ iph = ip_hdr(skb);
+ iph->version = 4;
+ iph->ihl = sizeof(struct iphdr) >> 2;
+ if (ip_dont_fragment(sk, &rt->u.dst))
+ iph->frag_off = htons(IP_DF);
+ else
+ iph->frag_off = 0;
+ iph->protocol = IPPROTO_GRE;
+ iph->tos = 0;
+ iph->daddr = rt->rt_dst;
+ iph->saddr = rt->rt_src;
+ iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
+ iph->tot_len = htons(skb->len);
+
+ skb_dst_drop(skb);
+ skb_dst_set(skb,&rt->u.dst);
+
+ nf_reset(skb);
+
+ skb->ip_summed = CHECKSUM_NONE;
+ ip_select_ident(iph, &rt->u.dst, NULL);
+ ip_send_check(iph);
+
+ ip_local_out(skb);
+
+tx_error:
+ return 1;
+}
+
+static int pptp_rcv_core(struct sock *sk,struct sk_buff *skb)
+{
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ int headersize,payload_len,seq;
+ __u8 *payload;
+ struct pptp_gre_header *header;
+
+ if (!(sk->sk_state & PPPOX_CONNECTED)) {
+ if (sock_queue_rcv_skb(sk, skb))
+ goto drop;
+ return NET_RX_SUCCESS;
+ }
+
+ header = (struct pptp_gre_header *)(skb->data);
+
+ /* test if acknowledgement present */
+ if (PPTP_GRE_IS_A(header->ver)){
+ __u32 ack = (PPTP_GRE_IS_S(header->flags))?
+ header->ack:header->seq; /* ack in different place if S = 0 */
+
+ ack = ntohl( ack);
+
+ if (ack > opt->ack_recv) opt->ack_recv = ack;
+ /* also handle sequence number wrap-around */
+ if (WRAPPED(ack,opt->ack_recv)) opt->ack_recv = ack;
+ }
+
+ /* test if payload present */
+ if (!PPTP_GRE_IS_S(header->flags)){
+ goto drop;
+ }
+
+ headersize = sizeof(*header);
+ payload_len = ntohs(header->payload_len);
+ seq = ntohl(header->seq);
+
+ /* no ack present? */
+ if (!PPTP_GRE_IS_A(header->ver)) headersize -= sizeof(header->ack);
+ /* check for incomplete packet (length smaller than expected) */
+ if (skb->len - headersize < payload_len) {
+ #ifdef DEBUG
+ if (log_level >= 1)
+ printk(KERN_INFO"PPTP: discarding truncated packet (expected %d, got %d bytes)\n",
+ payload_len, skb->len - headersize);
+ #endif
+ goto drop;
+ }
+
+ payload = skb->data+headersize;
+ /* check for expected sequence number */
+ if ( seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq) ) {
+ if ( (payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) &&
+ (PPP_PROTOCOL(payload) == PPP_LCP) &&
+ ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP)) ) {
+ #ifdef DEBUG
+ if ( log_level >= 1)
+ printk(KERN_INFO"PPTP[%i]: allowing old LCP Echo packet %d (expecting %d)\n", opt->src_addr.call_id,
+ seq, opt->seq_recv + 1);
+ #endif
+ goto allow_packet;
+ }
+ #ifdef DEBUG
+ if ( log_level >= 1)
+ printk(KERN_INFO"PPTP[%i]: discarding duplicate or old packet %d (expecting %d)\n",opt->src_addr.call_id,
+ seq, opt->seq_recv + 1);
+ #endif
+ }else{
+ opt->seq_recv = seq;
+allow_packet:
+ #ifdef DEBUG
+ if ( log_level >= 3 && opt->seq_sent<=log_packets)
+ printk(KERN_INFO"PPTP[%i]: accepting packet %d size=%i (%02x %02x %02x %02x %02x %02x)\n",opt->src_addr.call_id, seq,payload_len,
+ *(payload +0),
+ *(payload +1),
+ *(payload +2),
+ *(payload +3),
+ *(payload +4),
+ *(payload +5));
+ #endif
+
+ skb_pull(skb,headersize);
+
+ if (payload[0] == PPP_ALLSTATIONS && payload[1] == PPP_UI) {
+ /* chop off address/control */
+ if (skb->len < 3)
+ goto drop;
+ skb_pull(skb,2);
+ }
+
+ if ((*skb->data) & 1){
+ /* protocol is compressed */
+ skb_push(skb, 1)[0] = 0;
+ }
+
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_set_network_header(skb,skb->head-skb->data);
+ ppp_input(&po->chan,skb);
+
+ return NET_RX_SUCCESS;
+ }
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static int pptp_rcv(struct sk_buff *skb)
+{
+ struct pppox_sock *po;
+ struct pptp_gre_header *header;
+ struct iphdr *iph;
+
+ if (skb->pkt_type != PACKET_HOST)
+ goto drop;
+
+ if (!pskb_may_pull(skb, 12))
+ goto drop;
+
+ iph = ip_hdr(skb);
+
+ header = (struct pptp_gre_header *)skb->data;
+
+ if ( /* version should be 1 */
+ ((header->ver & 0x7F) != PPTP_GRE_VER) ||
+ /* PPTP-GRE protocol for PPTP */
+ (ntohs(header->protocol) != PPTP_GRE_PROTO)||
+ /* flag C should be clear */
+ PPTP_GRE_IS_C(header->flags) ||
+ /* flag R should be clear */
+ PPTP_GRE_IS_R(header->flags) ||
+ /* flag K should be set */
+ (!PPTP_GRE_IS_K(header->flags)) ||
+ /* routing and recursion ctrl = 0 */
+ ((header->flags&0xF) != 0)){
+ /* if invalid, discard this packet */
+ if (log_level >=1 )
+ printk(KERN_INFO"PPTP: Discarding GRE: %X %X %X %X %X %X\n",
+ header->ver&0x7F, ntohs(header->protocol),
+ PPTP_GRE_IS_C(header->flags),
+ PPTP_GRE_IS_R(header->flags),
+ PPTP_GRE_IS_K(header->flags),
+ header->flags & 0xF);
+ goto drop;
+ }
+
+
+ if ((po=lookup_chan(htons(header->call_id),iph->saddr))) {
+ skb_dst_drop(skb);
+ skb_dst_set(skb,NULL);
+ nf_reset(skb);
+ return sk_receive_skb(sk_pppox(po), skb, 0);
+ } else {
+ if (log_level >= 1)
+ printk(KERN_INFO"PPTP: Discarding packet from unknown call_id %i\n",htons(header->call_id));
+ }
+
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static int pptp_bind(struct socket *sock,struct sockaddr *uservaddr,int sockaddr_len)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ int error = 0;
+
+ #ifdef DEBUG
+ if (log_level >= 1)
+ printk(KERN_INFO"PPTP: bind: addr=%X call_id=%i\n",sp->sa_addr.pptp.sin_addr.s_addr,
+ sp->sa_addr.pptp.call_id);
+ #endif
+ lock_sock(sk);
+
+ opt->src_addr = sp->sa_addr.pptp;
+ if (add_chan(po)) {
+ release_sock(sk);
+ error = -EBUSY;
+ }
+ #ifdef DEBUG
+ if (log_level >= 1)
+ printk(KERN_INFO"PPTP: using call_id %i\n",opt->src_addr.call_id);
+ #endif
+
+ release_sock(sk);
+ return error;
+}
+
+static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ int sockaddr_len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ struct rtable *rt; /* Route to the other host */
+ int error=0;
+
+ if (sp->sa_protocol != PX_PROTO_PPTP)
+ return -EINVAL;
+
+ #ifdef DEBUG
+ if (log_level >= 1)
+ printk(KERN_INFO"PPTP[%i]: connect: addr=%X call_id=%i\n",opt->src_addr.call_id,
+ sp->sa_addr.pptp.sin_addr.s_addr,sp->sa_addr.pptp.call_id);
+ #endif
+
+ if (lookup_chan_dst(sp->sa_addr.pptp.call_id,sp->sa_addr.pptp.sin_addr.s_addr))
+ return -EALREADY;
+
+ lock_sock(sk);
+ /* Check for already bound sockets */
+ if (sk->sk_state & PPPOX_CONNECTED){
+ error = -EBUSY;
+ goto end;
+ }
+
+ /* Check for already disconnected sockets, on attempts to disconnect */
+ if (sk->sk_state & PPPOX_DEAD){
+ error = -EALREADY;
+ goto end;
+ }
+
+ if (!opt->src_addr.sin_addr.s_addr || !sp->sa_addr.pptp.sin_addr.s_addr){
+ error = -EINVAL;
+ goto end;
+ }
+
+ po->chan.private = sk;
+ po->chan.ops = &pptp_chan_ops;
+
+ {
+ struct flowi fl = {
+ .nl_u = { .ip4_u =
+ { .daddr = opt->dst_addr.sin_addr.s_addr,
+ .saddr = opt->src_addr.sin_addr.s_addr,
+ .tos = RT_CONN_FLAGS(sk) } },
+ .proto = IPPROTO_GRE };
+ security_sk_classify_flow(sk, &fl);
+ if (ip_route_output_key(&init_net, &rt, &fl)) {
+ error = -EHOSTUNREACH;
+ goto end;
+ }
+ sk_setup_caps(sk, &rt->u.dst);
+ }
+ po->chan.mtu = dst_mtu(&rt->u.dst);
+ if (!po->chan.mtu) po->chan.mtu = PPP_MTU;
+ ip_rt_put(rt);
+ po->chan.mtu -= PPTP_HEADER_OVERHEAD;
+
+ po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
+ error = ppp_register_channel(&po->chan);
+ if (error) {
+ printk(KERN_ERR "PPTP: failed to register PPP channel (%d)\n",error);
+ goto end;
+ }
+
+ opt->dst_addr = sp->sa_addr.pptp;
+ sk->sk_state = PPPOX_CONNECTED;
+
+ end:
+ release_sock(sk);
+ return error;
+}
+
+static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
+ int *usockaddr_len, int peer)
+{
+ int len = sizeof(struct sockaddr_pppox);
+ struct sockaddr_pppox sp;
+
+ sp.sa_family = AF_PPPOX;
+ sp.sa_protocol = PX_PROTO_PPTP;
+ sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
+
+ memcpy(uaddr, &sp, len);
+
+ *usockaddr_len = len;
+
+ return 0;
+}
+
+static int pptp_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+ struct pppox_sock *po;
+ struct pptp_opt *opt;
+ int error = 0;
+
+ if (!sk)
+ return 0;
+
+ lock_sock(sk);
+
+ if (sock_flag(sk, SOCK_DEAD)) {
+ release_sock(sk);
+ return -EBADF;
+ }
+
+ po = pppox_sk(sk);
+ opt = &po->proto.pptp;
+ del_chan(po);
+
+ pppox_unbind_sock(sk);
+ sk->sk_state = PPPOX_DEAD;
+
+ #ifdef DEBUG
+ if (log_level >= 1)
+ printk(KERN_INFO"PPTP[%i]: release\n",opt->src_addr.call_id);
+ #endif
+
+ sock_orphan(sk);
+ sock->sk = NULL;
+
+ release_sock(sk);
+ sock_put(sk);
+
+ return error;
+}
+
+
+static struct proto pptp_sk_proto = {
+ .name = "PPTP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct pppox_sock),
+};
+
+static struct proto_ops pptp_ops = {
+ .family = AF_PPPOX,
+ .owner = THIS_MODULE,
+ .release = pptp_release,
+ .bind = pptp_bind,
+ .connect = pptp_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = pptp_getname,
+ .poll = sock_no_poll,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = sock_no_sendmsg,
+ .recvmsg = sock_no_recvmsg,
+ .mmap = sock_no_mmap,
+ .ioctl = pppox_ioctl,
+};
+
+static void pptp_sock_destruct(struct sock *sk)
+{
+ if (!(sk->sk_state & PPPOX_DEAD)) {
+ del_chan(pppox_sk(sk));
+ pppox_unbind_sock(sk);
+ }
+ skb_queue_purge(&sk->sk_receive_queue);
+}
+static int pptp_create(struct net *net, struct socket *sock)
+{
+ int error = -ENOMEM;
+ struct sock *sk;
+ struct pppox_sock *po;
+ struct pptp_opt *opt;
+
+ sk = sk_alloc(net,PF_PPPOX, GFP_KERNEL, &pptp_sk_proto);
+ if (!sk)
+ goto out;
+
+ sock_init_data(sock, sk);
+
+ sock->state = SS_UNCONNECTED;
+ sock->ops = &pptp_ops;
+
+ sk->sk_backlog_rcv = pptp_rcv_core;
+ sk->sk_state = PPPOX_NONE;
+ sk->sk_type = SOCK_STREAM;
+ sk->sk_family = PF_PPPOX;
+ sk->sk_protocol = PX_PROTO_PPTP;
+ sk->sk_destruct = pptp_sock_destruct;
+
+ po = pppox_sk(sk);
+ opt = &po->proto.pptp;
+
+ opt->seq_sent = 0; opt->seq_recv = 0;
+ opt->ack_recv = 0; opt->ack_sent = 0;
+
+ error = 0;
+out:
+ return error;
+}
+
+static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sock *sk = (struct sock *) chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ struct pptp_opt *opt = &po->proto.pptp;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int err, val;
+
+ err = -EFAULT;
+ switch (cmd) {
+ case PPPIOCGFLAGS:
+ val = opt->ppp_flags;
+ if (put_user(val, p))
+ break;
+ err = 0;
+ break;
+ case PPPIOCSFLAGS:
+ if (get_user(val, p))
+ break;
+ opt->ppp_flags = val & ~SC_RCV_BITS;
+ err = 0;
+ break;
+ default:
+ err = -ENOTTY;
+ }
+
+ return err;
+}
+
+
+static struct pppox_proto pppox_pptp_proto = {
+ .create = pptp_create,
+ .owner = THIS_MODULE,
+};
+
+
+static struct gre_protocol gre_pptp_protocol = {
+ .handler = pptp_rcv,
+ //.err_handler = pptp_err,
+};
+
+static int __init pptp_init_module(void)
+{
+ int err=0;
+ printk(KERN_INFO "PPTP driver version " PPTP_DRIVER_VERSION "\n");
+
+ if (gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP) < 0) {
+ printk(KERN_INFO "PPTP: can't add protocol\n");
+ goto out;
+ }
+
+ err = proto_register(&pptp_sk_proto, 0);
+ if (err) {
+ printk(KERN_INFO "PPTP: can't register sk_proto\n");
+ goto out_inet_del_protocol;
+ }
+
+ err = register_pppox_proto(PX_PROTO_PPTP, &pppox_pptp_proto);
+ if (err) {
+ printk(KERN_INFO "PPTP: can't register pppox_proto\n");
+ goto out_unregister_sk_proto;
+ }
+
+
+ //assuming PAGESIZE is 4096 bytes
+ callid_bitmap = (unsigned long*)__get_free_pages(GFP_KERNEL,1);
+ memset(callid_bitmap,0,PAGE_SIZE << 1);
+
+ #if (BITS_PER_LONG == 32)
+ callid_sock = (struct pppox_sock **)__get_free_pages(GFP_KERNEL,6);
+ memset(callid_sock,0,PAGE_SIZE << 6);
+ #elif (BITS_PER_LONG == 64)
+ callid_sock = (struct pppox_sock **)__get_free_pages(GFP_KERNEL,7);
+ memset(callid_sock,0,PAGE_SIZE << 7);
+ #else
+ #error unknown size of LONG
+ #endif
+
+out:
+ return err;
+out_unregister_sk_proto:
+ proto_unregister(&pptp_sk_proto);
+out_inet_del_protocol:
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ return err;
+}
+
+static void __exit pptp_exit_module(void)
+{
+ unregister_pppox_proto(PX_PROTO_PPTP);
+ proto_unregister(&pptp_sk_proto);
+ gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
+ if (callid_bitmap) free_pages((unsigned long)callid_bitmap,1);
+ if (callid_sock) {
+ #if (BITS_PER_LONG == 32)
+ free_pages((unsigned long)callid_sock,6);
+ #elif (BITS_PER_LONG == 64)
+ free_pages((unsigned long)callid_sock,7);
+ #endif
+ }
+}
+
+module_init(pptp_init_module);
+module_exit(pptp_exit_module);
+
+MODULE_DESCRIPTION("Point-to-Point Tunneling Protocol for Linux");
+MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
+MODULE_LICENSE("GPL");
+
+module_param(log_level,int,0);
+module_param(log_packets,int,0);
+MODULE_PARM_DESC(log_level,"Logging level (default=0)");
+
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index a6577af..455ff56 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -47,17 +47,27 @@ struct pppoe_addr{
};
/************************************************************************
+ * PPTP addressing definition
+ */
+struct pptp_addr{
+ __u16 call_id;
+ struct in_addr sin_addr;
+};
+
+/************************************************************************
* Protocols supported by AF_PPPOX
*/
#define PX_PROTO_OE 0 /* Currently just PPPoE */
#define PX_PROTO_OL2TP 1 /* Now L2TP also */
-#define PX_MAX_PROTO 2
+#define PX_PROTO_PPTP 2
+#define PX_MAX_PROTO 3
struct sockaddr_pppox {
sa_family_t sa_family; /* address family, AF_PPPOX */
unsigned int sa_protocol; /* protocol identifier */
union{
struct pppoe_addr pppoe;
+ struct pptp_addr pptp;
}sa_addr;
}__attribute__ ((packed));
@@ -150,6 +160,13 @@ struct pppoe_opt {
relayed to (PPPoE relaying) */
};
+struct pptp_opt {
+ struct pptp_addr src_addr;
+ struct pptp_addr dst_addr;
+ __u32 ack_sent, ack_recv;
+ __u32 seq_sent, seq_recv;
+ int ppp_flags;
+};
#include <net/sock.h>
struct pppox_sock {
@@ -159,6 +176,7 @@ struct pppox_sock {
struct pppox_sock *next; /* for hash table */
union {
struct pppoe_opt pppoe;
+ struct pptp_opt pptp;
} proto;
__be16 num;
};
^ permalink raw reply related
* [PATCH v2 1/3] PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)
From: Dmitry Kozlov @ 2010-08-05 9:36 UTC (permalink / raw)
To: netdev
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 | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++
net/ipv4/ip_gre.c | 10 ++--
5 files changed, 178 insertions(+), 5 deletions(-)
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 <linux/skbuff.h>
+
+#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..f54a0fc
--- /dev/null
+++ b/net/ipv4/gre.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <net/protocol.h>
+#include <net/gre.h>
+
+
+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);
+
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 32618e1..f0391b3 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -44,6 +44,7 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
+#include <net/gre.h>
#ifdef CONFIG_IPV6
#include <net/ipv6.h>
@@ -1276,10 +1277,9 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
}
-static const struct net_protocol ipgre_protocol = {
+static const struct gre_protocol ipgre_protocol = {
.handler = ipgre_rcv,
.err_handler = ipgre_err,
- .netns_ok = 1,
};
static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head)
@@ -1661,7 +1661,7 @@ static int __init ipgre_init(void)
if (err < 0)
return err;
- err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE);
+ err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
if (err < 0) {
printk(KERN_INFO "ipgre init: can't add protocol\n");
goto add_proto_failed;
@@ -1681,7 +1681,7 @@ out:
tap_ops_failed:
rtnl_link_unregister(&ipgre_link_ops);
rtnl_link_failed:
- inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
+ gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
add_proto_failed:
unregister_pernet_device(&ipgre_net_ops);
goto out;
@@ -1691,7 +1691,7 @@ static void __exit ipgre_fini(void)
{
rtnl_link_unregister(&ipgre_tap_ops);
rtnl_link_unregister(&ipgre_link_ops);
- if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
+ if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n");
unregister_pernet_device(&ipgre_net_ops);
}
^ permalink raw reply related
* Re: NET_NS: unregister_netdevice: waiting for lo to become free (after using openvpn) (was Re: sysfs bug when using tun with network namespaces)
From: Michael Leun @ 2010-08-05 9:25 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Greg KH, netdev, davem, linux-kernel
In-Reply-To: <m1lj8l29zm.fsf@fess.ebiederm.org>
Hi,
On Wed, 04 Aug 2010 17:12:29 -0700
ebiederm@xmission.com (Eric W. Biederman) wrote:
First, thank you very much for picking that up (and, of course, for
your work at linux in general).
> > # > unshare -n /bin/bash
> > # > # how to setup veth device pair to get connectivity into
> > namespace not shown here # > openvpn --config some.config
> > [ running some traffic over vpn device not shown here ]
> > ^c # stopping openvpn
> > # > lsof -i
> > # > netstat -an
> > Active Internet connections (servers and established)
> > Proto Recv-Q Send-Q Local Address Foreign Address
> > State Active UNIX domain sockets (servers and established)
> > Proto RefCnt Flags Type State I-Node Path
> > # > ps ax|grep openvpn|grep -v grep
> > # > # cannot find anything that suggests there is anything left
> > from that openvpn session # > exit # logging out from shell in
> > network namespace
> >
> > Now I get
> >
> > Jul 10 20:02:36 doris kernel: unregister_netdevice: waiting for lo
> > to become free. Usage count = 3 [repeated]
>
> How many times?
Unfortunately looks like indefinitely. Never watched longer so far
(rebooted soon), but I'm seeing this message now repeated every 10 secs
for ~10 minutes on a idle system.
Additionally when testing this I found another one (by accident started
my firewall script in that namespace...) - using netfilter RECENT
makes it barf. Stripped down to the essentials it looks like this:
> # unshare -n /bin/bash
> # iptables -I INPUT -d 1.2.3.4 -m recent --name BLA --set
> # exit
Aug 5 11:19:47 doris kernel: [ 218.420238] ------------[ cut here ]------------
Aug 5 11:19:47 doris kernel: [ 218.420256] kernel BUG at net/netfilter/xt_recent.c:609!
Aug 5 11:19:47 doris kernel: [ 218.420268] invalid opcode: 0000 [#1] PREEMPT SMP
Aug 5 11:19:47 doris kernel: [ 218.420284] last sysfs file: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0A:00/power_supply/BAT0/charge_full
Aug 5 11:19:47 doris kernel: [ 218.420295] Modules linked in: snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device edd cpufreq_conservative cpufreq_userspace cpufreq_powersave acpi_cpufreq mperf ipt_REJECT ipt_LOG xt_limit xt_recent iptable_mangle iptable_nat iptable_filter nf_conntrack_ipv6 xt_state xt_tcpudp ip6table_filter ip6_tables nf_nat_ftp nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_ftp nf_conntrack ip_tables x_tables fuse nls_utf8 loop arc4 ecb iwlagn iwlcore mac80211 snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_pcm cfg80211 snd_timer snd usb_storage iTCO_wdt soundcore tg3 sg iTCO_vendor_support snd_page_alloc rfkill i2c_i801 pcspkr battery ac ext4 jbd2 crc16 sha256_generic aes_generic cbc dm_crypt linear i915 drm_kms_helper drm i2c_algo_bit sd_mod video
intel_agp button dm_snapshot dm_mod fan processor ata_piix ahci libahci libata scsi_mod thermal thermal_sys
Aug 5 11:19:47 doris kernel: [ 218.420529]
Aug 5 11:19:47 doris kernel: [ 218.420542] Pid: 13, comm: netns Not tainted 2.6.35 #2 Kuril /40684JG
Aug 5 11:19:47 doris kernel: [ 218.420557] EIP: 0060:[<fc886a15>] EFLAGS: 00010206 CPU: 0
Aug 5 11:19:47 doris kernel: [ 218.420578] EIP is at recent_net_exit+0x55/0x70 [xt_recent]
Aug 5 11:19:47 doris kernel: [ 218.420589] EAX: f2218000 EBX: f5b79290 ECX: f2f27b40 EDX: f5cd4000
Aug 5 11:19:47 doris kernel: [ 218.420601] ESI: f2218000 EDI: f5cd5f44 EBP: f5cd5f28 ESP: f5cd5f20
Aug 5 11:19:47 doris kernel: [ 218.420612] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
Aug 5 11:19:47 doris kernel: [ 218.420626] Process netns (pid: 13, ti=f5cd4000 task=f5cc9920 task.ti=f5cd4000)
Aug 5 11:19:47 doris kernel: [ 218.420635] Stack:
Aug 5 11:19:47 doris kernel: [ 218.420641] f5cd5f30 fc887618 f5cd5f3c c130867d fc887618 f5cd5f44 c1308850 f5cd5f60
Aug 5 11:19:47 doris kernel: [ 218.420667] <0> c1308919 f2218014 f2218014 f221800c f221800c c15915a0 c3bb4f40 c1308850
Aug 5 11:19:47 doris kernel: [ 218.420695] <0> f5cd5fbc c105a230 c13d1658 00000001 00000000 f7048000 c160f500 f5cc9c00
Aug 5 11:19:47 doris kernel: [ 218.420724] Call Trace:
Aug 5 11:19:47 doris kernel: [ 218.420749] [<c130867d>] ? ops_exit_list+0x1d/0x50
Aug 5 11:19:47 doris kernel: [ 218.420766] [<c1308850>] ? cleanup_net+0x0/0x160
Aug 5 11:19:47 doris kernel: [ 218.420782] [<c1308919>] ? cleanup_net+0xc9/0x160
Aug 5 11:19:47 doris kernel: [ 218.420797] [<c1308850>] ? cleanup_net+0x0/0x160
Aug 5 11:19:47 doris kernel: [ 218.420815] [<c105a230>] ? worker_thread+0x110/0x250
Aug 5 11:19:47 doris kernel: [ 218.420832] [<c13d1658>] ? schedule+0x748/0x7a0
Aug 5 11:19:47 doris kernel: [ 218.420849] [<c105d5f0>] ? autoremove_wake_function+0x0/0x40
Aug 5 11:19:47 doris kernel: [ 218.420864] [<c105a120>] ? worker_thread+0x0/0x250
Aug 5 11:19:47 doris kernel: [ 218.420879] [<c105d1bc>] ? kthread+0x6c/0x80
Aug 5 11:19:47 doris kernel: [ 218.420895] [<c105d150>] ? kthread+0x0/0x80
Aug 5 11:19:47 doris kernel: [ 218.420910] [<c1003336>] ? kernel_thread_helper+0x6/0x10
Aug 5 11:19:47 doris kernel: [ 218.420919] Code: 91 08 89 e2 81 e2 00 e0 ff ff 83 6a 14 01 f6 42 08 08 75 19 3b 1b 75 13 ba fa 72 88 fc e8 94 3e 8c c4 8d 64 24 04 5b 5d c3 0f 0b <0f> 0b 89 45 f8 e8 a1 ad b4 c4 8b 45 f8 eb da 8d b6 00 00 00 00
Aug 5 11:19:47 doris kernel: [ 218.421063] EIP: [<fc886a15>] recent_net_exit+0x55/0x70 [xt_recent] SS:ESP 0068:f5cd5f20
Aug 5 11:19:47 doris kernel: [ 218.421136] ---[ end trace f57524f15f4df616 ]---
--
MfG,
Michael Leun
^ permalink raw reply
* Re: [PATCH RESEND block#for-2.6.36] block_dev: always serialize exclusive open attempts
From: Jens Axboe @ 2010-08-05 9:20 UTC (permalink / raw)
To: Markus Trippelsdorf
Cc: Tejun Heo, Rafael J. Wysocki, Linux Kernel Mailing List,
Maciej Rutecki, Andrew Morton, Kernel Testers List,
Network Development, Linux ACPI, Linux PM List, Linux SCSI List,
Linux Wireless List, DRI, Linus Torvalds,
stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
In-Reply-To: <20100805091704.GA1772-joY5NpejW+Hx3b7vapvTcQ@public.gmane.org>
On 2010-08-05 11:17, Markus Trippelsdorf wrote:
> On Thu, Aug 05, 2010 at 11:02:43AM +0200, Jens Axboe wrote:
>> On 2010-08-04 17:59, Tejun Heo wrote:
>>> bd_prepare_to_claim() incorrectly allowed multiple attempts for
>>> exclusive open to progress in parallel if the attempting holders are
>>> identical. This triggered BUG_ON() as reported in the following bug.
>>>
>>> https://bugzilla.kernel.org/show_bug.cgi?id=16393
>>>
>>> __bd_abort_claiming() is used to finish claiming blocks and doesn't
>>> work if multiple openers are inside a claiming block. Allowing
>>> multiple parallel open attempts to continue doesn't gain anything as
>>> those are serialized down in the call chain anyway. Fix it by always
>>> allowing only single open attempt in a claiming block.
>>>
>>> This problem can easily be reproduced by adding a delay after
>>> bd_prepare_to_claim() and attempting to mount two partitions of a
>>> disk.
>>>
>>> stable: only applicable to v2.6.35
>>>
>>> Signed-off-by: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>>> Reported-by: Markus Trippelsdorf <markus-xp2qqqlHh3xzoYq+O6RWwA@public.gmane.org>
>>> Cc: stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
>>
>> Thanks Tejun, applied.
>
> It's already in mainline:
> e75aa85892b2ee78c79edac720868cbef16e62eb
Irk, had not noticed yet, my for-2.6.36 branch isn't fully merged
up yet. Thanks for the heads-up.
--
Jens Axboe
Confidentiality Notice: This e-mail message, its contents and any attachments to it are confidential to the intended recipient, and may contain information that is privileged and/or exempt from disclosure under applicable law. If you are not the intended recipient, please immediately notify the sender and destroy the original e-mail message and any attachments (and any copies that may have been made) from your system or otherwise. Any unauthorized use, copying, disclosure or distribution of this information is strictly prohibited.
^ permalink raw reply
* Re: [PATCH RESEND block#for-2.6.36] block_dev: always serialize exclusive open attempts
From: Markus Trippelsdorf @ 2010-08-05 9:17 UTC (permalink / raw)
To: Jens Axboe
Cc: Tejun Heo, Rafael J. Wysocki, Linux Kernel Mailing List,
Maciej Rutecki, Andrew Morton, Kernel Testers List,
Network Development, Linux ACPI, Linux PM List, Linux SCSI List,
Linux Wireless List, DRI, Linus Torvalds,
stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
In-Reply-To: <4C5A7E33.3060101-5c4llco8/ftWk0Htik3J/w@public.gmane.org>
On Thu, Aug 05, 2010 at 11:02:43AM +0200, Jens Axboe wrote:
> On 2010-08-04 17:59, Tejun Heo wrote:
> > bd_prepare_to_claim() incorrectly allowed multiple attempts for
> > exclusive open to progress in parallel if the attempting holders are
> > identical. This triggered BUG_ON() as reported in the following bug.
> >
> > https://bugzilla.kernel.org/show_bug.cgi?id=16393
> >
> > __bd_abort_claiming() is used to finish claiming blocks and doesn't
> > work if multiple openers are inside a claiming block. Allowing
> > multiple parallel open attempts to continue doesn't gain anything as
> > those are serialized down in the call chain anyway. Fix it by always
> > allowing only single open attempt in a claiming block.
> >
> > This problem can easily be reproduced by adding a delay after
> > bd_prepare_to_claim() and attempting to mount two partitions of a
> > disk.
> >
> > stable: only applicable to v2.6.35
> >
> > Signed-off-by: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > Reported-by: Markus Trippelsdorf <markus-xp2qqqlHh3xzoYq+O6RWwA@public.gmane.org>
> > Cc: stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
>
> Thanks Tejun, applied.
It's already in mainline:
e75aa85892b2ee78c79edac720868cbef16e62eb
--
»A man who doesn't know he is in prison can never escape.«
William S. Burroughs
^ permalink raw reply
* Re: [PATCH RESEND block#for-2.6.36] block_dev: always serialize exclusive open attempts
From: Jens Axboe @ 2010-08-05 9:02 UTC (permalink / raw)
To: Tejun Heo
Cc: Rafael J. Wysocki, Linux Kernel Mailing List, Maciej Rutecki,
Andrew Morton, Kernel Testers List, Network Development,
Linux ACPI, Linux PM List, Linux SCSI List, Linux Wireless List,
DRI, Linus Torvalds, stable@kernel.org
In-Reply-To: <4C598E6B.7050405@gmail.com>
On 2010-08-04 17:59, Tejun Heo wrote:
> bd_prepare_to_claim() incorrectly allowed multiple attempts for
> exclusive open to progress in parallel if the attempting holders are
> identical. This triggered BUG_ON() as reported in the following bug.
>
> https://bugzilla.kernel.org/show_bug.cgi?id=16393
>
> __bd_abort_claiming() is used to finish claiming blocks and doesn't
> work if multiple openers are inside a claiming block. Allowing
> multiple parallel open attempts to continue doesn't gain anything as
> those are serialized down in the call chain anyway. Fix it by always
> allowing only single open attempt in a claiming block.
>
> This problem can easily be reproduced by adding a delay after
> bd_prepare_to_claim() and attempting to mount two partitions of a
> disk.
>
> stable: only applicable to v2.6.35
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de>
> Cc: stable@kernel.org
Thanks Tejun, applied.
--
Jens Axboe
Confidentiality Notice: This e-mail message, its contents and any attachments to it are confidential to the intended recipient, and may contain information that is privileged and/or exempt from disclosure under applicable law. If you are not the intended recipient, please immediately notify the sender and destroy the original e-mail message and any attachments (and any copies that may have been made) from your system or otherwise. Any unauthorized use, copying, disclosure or distribution of this information is strictly prohibited.
^ permalink raw reply
* RE: [RFC PATCH v8 00/16] Provide a zero-copy method on KVM virtio-net.
From: Xin, Xiaohui @ 2010-08-05 8:52 UTC (permalink / raw)
To: Xin, Xiaohui, netdev@vger.kernel.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1280402088-5849-1-git-send-email-xiaohui.xin@intel.com>
Herbert,
The v8 patches are modified mostly based on your comments about
napi_gro_frags interface. How do you think about the patches about
net core system part?
We know currently there are some comments about the mp device,
such as to support zero-copy for tun/tap and macvtap. Since there
isn't a decision yet about it. May you give comments about the
net core system first, since this part is all the same for zero-copy.
Thanks
Xiaohui
>-----Original Message-----
>From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-owner@vger.kernel.org] On
>Behalf Of xiaohui.xin@intel.com
>Sent: Thursday, July 29, 2010 7:15 PM
>To: netdev@vger.kernel.org; kvm@vger.kernel.org; linux-kernel@vger.kernel.org;
>mst@redhat.com; mingo@elte.hu; davem@davemloft.net; herbert@gondor.apana.org.au;
>jdike@linux.intel.com
>Subject: [RFC PATCH v8 00/16] Provide a zero-copy method on KVM virtio-net.
>
>We provide an zero-copy method which driver side may get external
>buffers to DMA. Here external means driver don't use kernel space
>to allocate skb buffers. Currently the external buffer can be from
>guest virtio-net driver.
>
>The idea is simple, just to pin the guest VM user space and then
>let host NIC driver has the chance to directly DMA to it.
>The patches are based on vhost-net backend driver. We add a device
>which provides proto_ops as sendmsg/recvmsg to vhost-net to
>send/recv directly to/from the NIC driver. KVM guest who use the
>vhost-net backend may bind any ethX interface in the host side to
>get copyless data transfer thru guest virtio-net frontend.
>
>patch 01-10: net core and kernel changes.
>patch 11-13: new device as interface to mantpulate external buffers.
>patch 14: for vhost-net.
>patch 15: An example on modifying NIC driver to using napi_gro_frags().
>patch 16: An example how to get guest buffers based on driver
> who using napi_gro_frags().
>
>The guest virtio-net driver submits multiple requests thru vhost-net
>backend driver to the kernel. And the requests are queued and then
>completed after corresponding actions in h/w are done.
>
>For read, user space buffers are dispensed to NIC driver for rx when
>a page constructor API is invoked. Means NICs can allocate user buffers
>from a page constructor. We add a hook in netif_receive_skb() function
>to intercept the incoming packets, and notify the zero-copy device.
>
>For write, the zero-copy deivce may allocates a new host skb and puts
>payload on the skb_shinfo(skb)->frags, and copied the header to skb->data.
>The request remains pending until the skb is transmitted by h/w.
>
>We provide multiple submits and asynchronous notifiicaton to
>vhost-net too.
>
>Our goal is to improve the bandwidth and reduce the CPU usage.
>Exact performance data will be provided later.
>
>What we have not done yet:
> Performance tuning
>
>what we have done in v1:
> polish the RCU usage
> deal with write logging in asynchroush mode in vhost
> add notifier block for mp device
> rename page_ctor to mp_port in netdevice.h to make it looks generic
> add mp_dev_change_flags() for mp device to change NIC state
> add CONIFG_VHOST_MPASSTHRU to limit the usage when module is not load
> a small fix for missing dev_put when fail
> using dynamic minor instead of static minor number
> a __KERNEL__ protect to mp_get_sock()
>
>what we have done in v2:
>
> remove most of the RCU usage, since the ctor pointer is only
> changed by BIND/UNBIND ioctl, and during that time, NIC will be
> stopped to get good cleanup(all outstanding requests are finished),
> so the ctor pointer cannot be raced into wrong situation.
>
> Remove the struct vhost_notifier with struct kiocb.
> Let vhost-net backend to alloc/free the kiocb and transfer them
> via sendmsg/recvmsg.
>
> use get_user_pages_fast() and set_page_dirty_lock() when read.
>
> Add some comments for netdev_mp_port_prep() and handle_mpassthru().
>
>what we have done in v3:
> the async write logging is rewritten
> a drafted synchronous write function for qemu live migration
> a limit for locked pages from get_user_pages_fast() to prevent Dos
> by using RLIMIT_MEMLOCK
>
>
>what we have done in v4:
> add iocb completion callback from vhost-net to queue iocb in mp device
> replace vq->receiver by mp_sock_data_ready()
> remove stuff in mp device which access structures from vhost-net
> modify skb_reserve() to ignore host NIC driver reserved space
> rebase to the latest vhost tree
> split large patches into small pieces, especially for net core part.
>
>
>what we have done in v5:
> address Arnd Bergmann's comments
> -remove IFF_MPASSTHRU_EXCL flag in mp device
> -Add CONFIG_COMPAT macro
> -remove mp_release ops
> move dev_is_mpassthru() as inline func
> fix a bug in memory relinquish
> Apply to current git (2.6.34-rc6) tree.
>
>what we have done in v6:
> move create_iocb() out of page_dtor which may happen in interrupt context
> -This remove the potential issues which lock called in interrupt context
> make the cache used by mp, vhost as static, and created/destoryed during
> modules init/exit functions.
> -This makes multiple mp guest created at the same time.
>
>what we have done in v7:
> some cleanup prepared to suppprt PS mode
>
>what we have done in v8
> discarding the modifications to point skb->data to guest buffer directly.
> Add code to modify driver to support napi_gro_frags() with Herbert's comments.
> To support PS mode.
> Add mergeable buffer support in mp device.
> Add GSO/GRO support in mp deice.
> Address comments from Eric Dumazet about cache line and rcu usage.
>
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: GIT: net-*2.6 rebased...
From: David Miller @ 2010-08-05 8:46 UTC (permalink / raw)
To: arnd-BCMAnToX5e2ELgA04lAiVw
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, sfr-3FnU+UHB4dNDw9hX6IcOSA
In-Reply-To: <4C5A6EFE.7040703-BCMAnToX5e2ELgA04lAiVw@public.gmane.org>
From: Arnd Hannemann <arnd-BCMAnToX5e2ELgA04lAiVw@public.gmane.org>
Date: Thu, 05 Aug 2010 09:57:50 +0200
> if I try to fetch from net-next-2.6, I get:
> fatal: The remote end hung up unexpectedly
>
> if I try to clone net-2.6:
> (e.g. git clone git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
>
> I get lots of errors reading the tags "does not point to a valid object!" and then:
> remote: error: Could not read 3cfc2c42c1cbc8e238bb9c0612c0df4565e3a8b4
> remote: fatal: Failed to traverse parents of commit 7aaaaa1e44b2a4047dfe05f304a5090eb995cf44
> remote: aborting due to possible repository corruption on the remote side.
> fatal: early EOF
> fatal: index-pack failed
Hmmm, since I can I tried an ssh based clone and it works.
But indeed if I try to use the git:// URL it fails.
Oh I see, the alternates files in those repos are completely broken.
They have:
/home/davem/git/../torvalds/linux-2.6.git/objects
/home/davem/git is a symlink to /pub/scm/linux/kernel/git/davem
so if I login and "cd git" then:
git clone --shared --bare ../torvalds/linux-2.6.git net-next-2.6.git
which is how I always create my trees, we get that unusable 'alternates'
path above.
The ".." works when my GIT directory is the working directory, but
not as part of the symlink include path to get there.
I fixed the alternates file but it will take some time for the fix
to propagate from master.kernel.org
Let me know if it doesn't work even after an hour or so.
Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] usbnet: remove noisy and hardly useful printk
From: Christian Samsel @ 2010-08-05 8:14 UTC (permalink / raw)
To: netdev; +Cc: dhollis, Christian Samsel
With turned on hspa modem (Dell 5530 internal card) and activated usb auto
suspend, my system gets up 100 "usbnet_resume has delayed data" per
minute. I didnt noticed any pathological behaviour, so just drop
this message. if any objections, please at least change it to _DEBUG.
Signed-off-by: Christian Samsel <christian.samsel@rwth-aachen.de>
---
drivers/net/usb/usbnet.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 3b03794..7f62e2d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1457,7 +1457,6 @@ int usbnet_resume (struct usb_interface *intf)
spin_lock_irq(&dev->txq.lock);
while ((res = usb_get_from_anchor(&dev->deferred))) {
- printk(KERN_INFO"%s has delayed data\n", __func__);
skb = (struct sk_buff *)res->context;
retval = usb_submit_urb(res, GFP_ATOMIC);
if (retval < 0) {
--
1.7.2
^ permalink raw reply related
* Re: GIT: net-*2.6 rebased...
From: Changli Gao @ 2010-08-05 8:02 UTC (permalink / raw)
To: Arnd Hannemann
Cc: David Miller, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, sfr-3FnU+UHB4dNDw9hX6IcOSA
In-Reply-To: <4C5A6EFE.7040703-BCMAnToX5e2ELgA04lAiVw@public.gmane.org>
On Thu, Aug 5, 2010 at 3:57 PM, Arnd Hannemann <arnd-BCMAnToX5e2ELgA04lAiVw@public.gmane.org> wrote:
> Hi,
>
> Am 05.08.2010 01:21, schrieb David Miller:
>>
>> Both net-2.6 and net-next-2.6 have been rebased.
>>
>> To be honest, if you've been pulling from my tree you can just keep
>> doing so if you want, it will look just as if I had merged Linus's
>> tree into net-2.6 et al.
>
> I there something broken with the trees on git.kernel.org?
>
> if I try to fetch from net-next-2.6, I get:
> fatal: The remote end hung up unexpectedly
>
> if I try to clone net-2.6:
> (e.g. git clone git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
>
> I get lots of errors reading the tags "does not point to a valid object!" and then:
> remote: error: Could not read 3cfc2c42c1cbc8e238bb9c0612c0df4565e3a8b4
> remote: fatal: Failed to traverse parents of commit 7aaaaa1e44b2a4047dfe05f304a5090eb995cf44
> remote: aborting due to possible repository corruption on the remote side.
> fatal: early EOF
> fatal: index-pack failed
>
> I'm using git version 1.7.1.
>
me 2 for net-next-2.6
localhost linux # git pull
fatal: The remote end hung up unexpectedly
localhost linux # git version
git version 1.7.1
--
Regards,
Changli Gao(xiaosuo-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org)
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: GIT: net-*2.6 rebased...
From: Arnd Hannemann @ 2010-08-05 7:57 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, sfr-3FnU+UHB4dNDw9hX6IcOSA
In-Reply-To: <20100804.162141.15218463.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Hi,
Am 05.08.2010 01:21, schrieb David Miller:
>
> Both net-2.6 and net-next-2.6 have been rebased.
>
> To be honest, if you've been pulling from my tree you can just keep
> doing so if you want, it will look just as if I had merged Linus's
> tree into net-2.6 et al.
I there something broken with the trees on git.kernel.org?
if I try to fetch from net-next-2.6, I get:
fatal: The remote end hung up unexpectedly
if I try to clone net-2.6:
(e.g. git clone git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
I get lots of errors reading the tags "does not point to a valid object!" and then:
remote: error: Could not read 3cfc2c42c1cbc8e238bb9c0612c0df4565e3a8b4
remote: fatal: Failed to traverse parents of commit 7aaaaa1e44b2a4047dfe05f304a5090eb995cf44
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOF
fatal: index-pack failed
I'm using git version 1.7.1.
Best regards,
Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: can TCP send buffer be over used?
From: Leslie Rhorer @ 2010-08-05 7:20 UTC (permalink / raw)
To: 'Jack Zhang', linux-net, netdev
In-Reply-To: <AANLkTikWH8NQZ5CYN7ytPYg-tK=eXF=OgJn=cuAoVexO@mail.gmail.com>
> There is one part of your suggestion I'm not sure if I fully
> understand though... "the transmitter cannot be allowed to send more
> data without acknowledgement of receipt of all the sent data than the
> receiver can assemble in one chunk. " I take it as the transmitter
> cannot send data of more than the receive window size without ack of
> the sent data. Is that what you meant?
For TCP, yes. In general it is true of any protocol which
guarantees intact delivery of data. The far (Rx) end must be able to
assemble all the data in good order if no data is to be lost. If the far
end can only buffer N blocks of data and the transmitter sends N + 1 blocks
of data before the far end can properly assemble the chunk, then the far end
has to discard one of the blocks of data.
TCP employs a sliding window, so once N blocks of data have been
assembled by the Rx system, it sends and ACK for the Nth block back to the
Tx host, whereupon the Tx host moves up its pointer for the window's
starting position to N + 1, and continues transmitting until the end of the
window is reached. If the latency is very small and the link error free, it
may never reach the end of the window, and the transfer will proceed at wire
speed. Otherwise, the near host transmits until it reaches the end of the
buffer whose size has been negotiated between the near and far system, and
then waits for an acknowledgement from the far end. When it comes, it may
not be an acknowledgement for the 1st block of data in the window, but
rather for some number of blocks, or perhaps even the entire window.
However many blocks are acknowledged, the Tx system moves its window pointer
up by that many blocks, and transmission begins again.
> > 3. Your measurement is based upon transfers that are too small in
> extent.
>
> I was transferring 1 GB data over the 100 Mbps link. Do you think if I
> should increase the size of the transfer?
No. As long as the file size is large compared to the maximum
window size, the measurement should be valid. A file size of 1G is very
large compared to 128K.
^ permalink raw reply
* Re: [PATCH 3/3] PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)
From: Dmitry Kozlov @ 2010-08-05 5:55 UTC (permalink / raw)
To: Bill Fink; +Cc: netdev
In-Reply-To: <20100804212251.59c08e58.billfink@mindspring.com>
On Wed, 4 Aug 2010 21:22:51 -0400 Bill Fink <billfink@mindspring.com> wrote:
> On Wed, 04 Aug 2010, xeb@mail.ru wrote:
>
> > This is patch 3/3 which contains MAINTAINERS file modification.
> >
> > ---
> > MAINTAINERS | 14 ++++++++++++++
> > 1 files changed, 14 insertions(+), 0 deletions(-)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 02f75fc..313d829 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6450,6 +6450,20 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org>
> > S: Maintained
> > F: drivers/serial/zs.*
> >
> > +GRE DEMULTIPLEXER DRIVER
> > +M: Dmitry Kozlov <xeb@mail.ru>
> > +L: linux-net@vger.kernel.org
>
> Shouldn't this also be:
>
> +L: netdev@vger.kernel.org
>
> just like the PPTP DRIVER entry below?
>
> -Bill
Seems like it should ... will be fixed.
^ permalink raw reply
* [PATCH 1/3 update] PPTP: PPP over IPv4 (Point-to-Point Tunneling Protocol)
From: xeb @ 2010-08-05 5:48 UTC (permalink / raw)
To: netdev
This is patch 1/3 which contains gre demultiplexer driver source
for demultiplexing gre packets with different gre version.
Update: included forgotten net/ipv4/ip_gre.c
include/net/gre.h | 18 ++++++
net/ipv4/Kconfig | 7 +++
net/ipv4/Makefile | 1 +
net/ipv4/gre.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++
net/ipv4/ip_gre.c | 10 ++--
5 files changed, 182 insertions(+), 5 deletions(-)
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 <linux/skbuff.h>
+
+#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 <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <net/protocol.h>
+#include <net/gre.h>
+
+
+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);
+
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 32618e1..f0391b3 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -44,6 +44,7 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
+#include <net/gre.h>
#ifdef CONFIG_IPV6
#include <net/ipv6.h>
@@ -1276,10 +1277,9 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
}
-static const struct net_protocol ipgre_protocol = {
+static const struct gre_protocol ipgre_protocol = {
.handler = ipgre_rcv,
.err_handler = ipgre_err,
- .netns_ok = 1,
};
static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head)
@@ -1661,7 +1661,7 @@ static int __init ipgre_init(void)
if (err < 0)
return err;
- err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE);
+ err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
if (err < 0) {
printk(KERN_INFO "ipgre init: can't add protocol\n");
goto add_proto_failed;
@@ -1681,7 +1681,7 @@ out:
tap_ops_failed:
rtnl_link_unregister(&ipgre_link_ops);
rtnl_link_failed:
- inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
+ gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
add_proto_failed:
unregister_pernet_device(&ipgre_net_ops);
goto out;
@@ -1691,7 +1691,7 @@ static void __exit ipgre_fini(void)
{
rtnl_link_unregister(&ipgre_tap_ops);
rtnl_link_unregister(&ipgre_link_ops);
- if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
+ if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0)
printk(KERN_INFO "ipgre close: can't remove protocol\n");
unregister_pernet_device(&ipgre_net_ops);
}
^ permalink raw reply related
* [linux-next] build failure
From: divya @ 2010-08-05 5:32 UTC (permalink / raw)
To: LKML, linux-next, linuxppc-dev, netdev, jeffrey.t.kirsher
Yestersday's linux-next(2.6.35_next_20100802) build fails with the following error on both system p and x.
drivers/net/ixgbe/ixgbe_main.c: In function 'ixgbe_select_queue':
drivers/net/ixgbe/ixgbe_main.c:6159: error: 'struct ixgbe_fcoe' has no member named 'up'
drivers/net/ixgbe/ixgbe_main.c: In function 'ixgbe_xmit_frame':
drivers/net/ixgbe/ixgbe_main.c:6221: error: 'struct ixgbe_fcoe' has no member named 'up'
make[3]: *** [drivers/net/ixgbe/ixgbe_main.o] Error 1
make[2]: *** [drivers/net/ixgbe] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [drivers/net] Error 2
make: *** [drivers] Error 2
Thanks
Divya
^ permalink raw reply
* Re: [PATCH] ppp: make channel_ops const
From: David Miller @ 2010-08-05 4:56 UTC (permalink / raw)
To: shemminger; +Cc: paulus, linux-ppp, netdev
In-Reply-To: <20100804103436.72e234d6@nehalam>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 4 Aug 2010 10:34:36 -0700
> The PPP channel ops structure should be const.
> Cleanup the declarations to use standard C99 format.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 4/4] sch_sfq: add sanity check for the packet length
From: David Miller @ 2010-08-05 4:55 UTC (permalink / raw)
To: xiaosuo; +Cc: hadi, netdev
In-Reply-To: <1280933939-17548-1-git-send-email-xiaosuo@gmail.com>
From: Changli Gao <xiaosuo@gmail.com>
Date: Wed, 4 Aug 2010 22:58:59 +0800
> The packet length should be checked before the packet data is dereferenced.
>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 3/4] cls_rsvp: add sanity check for the packet length
From: David Miller @ 2010-08-05 4:55 UTC (permalink / raw)
To: xiaosuo; +Cc: hadi, netdev
In-Reply-To: <1280933740-17480-1-git-send-email-xiaosuo@gmail.com>
From: Changli Gao <xiaosuo@gmail.com>
Date: Wed, 4 Aug 2010 22:55:40 +0800
> The packet length should be checked before the packet data is dereferenced.
>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 2/4] cls_flow: add sanity check for the packet length
From: David Miller @ 2010-08-05 4:55 UTC (permalink / raw)
To: kaber; +Cc: xiaosuo, hadi, netdev
In-Reply-To: <4C59915D.1020902@trash.net>
From: Patrick McHardy <kaber@trash.net>
Date: Wed, 04 Aug 2010 18:12:13 +0200
> Am 04.08.2010 16:48, schrieb Changli Gao:
>> The packet length should be checked before the packet data is dereferenced.
>>
>
> Acked-by: Patrick McHardy <kaber@trash.net>
Applied.
^ permalink raw reply
* Re: [PATCH v2 1/4] sk_buff: introduce pskb_network_may_pull()
From: David Miller @ 2010-08-05 4:55 UTC (permalink / raw)
To: xiaosuo; +Cc: hadi, kaber, netdev
In-Reply-To: <1280933024-12132-1-git-send-email-xiaosuo@gmail.com>
From: Changli Gao <xiaosuo@gmail.com>
Date: Wed, 4 Aug 2010 22:43:44 +0800
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH] RxRPC: Fix a potential deadlock between the call resend_timer and state_lock
From: David Miller @ 2010-08-05 4:55 UTC (permalink / raw)
To: dhowells; +Cc: netdev
In-Reply-To: <20100804123417.29580.95095.stgit@warthog.procyon.org.uk>
From: David Howells <dhowells@redhat.com>
Date: Wed, 04 Aug 2010 13:34:17 +0100
> RxRPC can potentially deadlock as rxrpc_resend_time_expired() wants to get
> call->state_lock so that it can alter the state of an RxRPC call. However, its
> caller (call_timer_fn()) has an apparent lock on the timer struct.
>
> The problem is that rxrpc_resend_time_expired() isn't permitted to lock
> call->state_lock as this could cause a deadlock against rxrpc_send_abort() as
> that takes state_lock and then attempts to delete the resend timer by calling
> del_timer_sync().
>
> The deadlock can occur because del_timer_sync() will sit there forever waiting
> for rxrpc_resend_time_expired() to return, but the latter may then wait for
> call->state_lock, which rxrpc_send_abort() holds around del_timer_sync()...
>
> This leads to a warning appearing in the kernel log that looks something like
> the attached.
>
> It should be sufficient to simply dispense with the locks. It doesn't matter
> if we set the resend timer expired event bit and queue the event processor
> whilst we're changing state to one where the resend timer is irrelevant as the
> event can just be ignored by the processor thereafter.
...
> Signed-off-by: David Howells <dhowells@redhat.com>
Applied, thanks!
^ permalink raw reply
* Re: [PATCH] act_nat: fix on the TX path
From: David Miller @ 2010-08-05 4:54 UTC (permalink / raw)
To: herbert; +Cc: xiaosuo, hadi, netdev
In-Reply-To: <20100804070621.GB370@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 4 Aug 2010 15:06:21 +0800
> On Wed, Aug 04, 2010 at 11:39:18AM +0800, Changli Gao wrote:
>> On the TX path, skb->data points to the ethernet header, not the network
>> header. So when validating the packet length for accessing we should
>> take the ethernet header into account.
>>
>> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
>
> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Applied, thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox