Netdev List
 help / color / mirror / Atom feed
* [PATCH 0/6] tagged sysfs support
From: Eric W. Biederman @ 2010-03-30 18:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Kay Sievers, Greg KH, linux-kernel, Tejun Heo, Cornelia Huck,
	linux-fsdevel, Eric Dumazet, Benjamin LaHaise, Serge Hallyn,
	netdev


The main short coming of using multiple network namespaces today
is that only network devices for the primary network namespaces
can be put in the kobject layer and sysfs.

This is essentially the earlier version of this patchset that was
reviewed before, just now on top of a version of sysfs that doesn't
need cleanup patches to support it.

I have been running these patches in some form for well over a
year so the basics should at least be solid.  

This patchset is currently against 2.6.34-rc1.

This patchset is just the basic infrastructure a couple of more pretty
trivial patches are needed to actually enable network namespaces to use this.
My current plan is to send those after these patches have made it through
review.

 drivers/base/class.c    |    9 ++++
 drivers/base/core.c     |   98 +++++++++++++++++++++++++++++++++----------
 drivers/gpio/gpiolib.c  |    2 +-
 drivers/md/bitmap.c     |    4 +-
 drivers/md/md.c         |    6 +-
 fs/sysfs/bin.c          |    2 +-
 fs/sysfs/dir.c          |  106 ++++++++++++++++++++++++++++++++++++-----------
 fs/sysfs/file.c         |   17 ++++---
 fs/sysfs/group.c        |    6 +-
 fs/sysfs/inode.c        |    6 ++-
 fs/sysfs/mount.c        |   91 +++++++++++++++++++++++++++++++++++++++-
 fs/sysfs/symlink.c      |   35 ++++++++++++++-
 fs/sysfs/sysfs.h        |   23 ++++++++--
 include/linux/device.h  |    3 +
 include/linux/kobject.h |   26 +++++++++++
 include/linux/sysfs.h   |   18 ++++++++
 lib/kobject.c           |  104 ++++++++++++++++++++++++++++++++++++++++++++++
 17 files changed, 480 insertions(+), 76 deletions(-)

Eric

^ permalink raw reply

* Re: [PATCH -next] x86, fs: add sys_compat_write for net/socket.c
From: Florian Westphal @ 2010-03-30 18:17 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Florian Westphal, linux-fsdevel, Al Viro, David S. Miller,
	Thomas Gleixner, Ingo Molnar, x86, netdev, linux-kernel
In-Reply-To: <4BB23B35.7060401@zytor.com>

H. Peter Anvin <hpa@zytor.com> wrote:
> > On some configurations, e.g. x86_64 with 32bit userspace, netlink/xfrm
> > misinterprets messages from userspace due to different structure
> > layout (u64 has different alignment requirements on x86 vs. x86_64).

[..]

> > As long as messages are sent via sendmsg(), this could be handled via
> > net/compat.c; it will set the CMSG_MSG_COMPAT flag in struct msghdr
> > for compat tasks, which would allow to the xfrm_user code to detect
> > when messages need compat fixups.
> > 
> > Unfortunately, some programs (e.g. pluto ike daemon), send netlink data
> > to the kernel using write().
> > 
> > Thus, introduce f_ops->compat_aio_write and compat_sys_write to treat
> > writes on sockets specially.
> > 
> > This only wires up compat_sys_write for x86/x86_64 -- at the moment this
> > is only required to parse xfrm netlink messages, which happen to only
> > need special treatment in case of COMPAT_FOR_U64_ALIGNMENT=y.
> > 
> > Setting CMSG_MSG_COMPAT depending on plain is_compat_task() in net/socket.c
> > was not done due to concerns regarding the kernel doing socket
> > writes in response to a user event (which might set MSG_COMPAT erronously).
> > 
> 
> OK... I have to ask the question:
> 
> This only applies if you're using unpacked structures with
> non-naturally-aligned objects in them.  Where to we have those, and can
> we shoot the authors?

Fair enough.
This happens e.g. when trying to add xfrm policies or SAs from 32bit x86
userspace on x86_64 kernels, e.g. commands like "ip xfrm pol add dir in"
fail due to user/kernelspace structure size mismatch.

One structure that has this problem is struct xfrm_userpolicy_info, but
there are more.

Now, I realize that adding a write compat syscall is borderline
insanity, and I am open to suggestions.

In fact, I would even accept a "userspace must use sendmsg() when dealing
with xfrm netlink"; the only problem is that my pending xfrm compat patches
depend on this patch being accepted [ or, rather, they depend
on the MSG_COMPAT flag being set; which is currently only done when userspace
uses sendmsg().

In fact, "ip xfrm .. " even works with the xfrm compat patch set applied
because ip xfrm ... happens to use sendmsg(). But not all userspace apps do this ].

Thanks, Florian

^ permalink raw reply

* Re: Add PGM protocol support to the IP stack
From: Christoph Lameter @ 2010-03-30 18:12 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Andi Kleen, David Miller, netdev, linux-kernel
In-Reply-To: <4BB13133.6030500@zytor.com>

On Mon, 29 Mar 2010, H. Peter Anvin wrote:

> On 03/22/2010 11:53 AM, Andi Kleen wrote:
> >
> > There's just no portable atomic64_t. Ok maybe you can use the socket lock
> > to synchronize all the counts if they are only per socket.
> >
>
> In 2.6.34 there is (although some arches which could support it natively
> don't as of yet... but that's fixable.)  See lib/atomic64.c.

There are also the 64bit thiscpu operations that were merged in 2.6.33.
They do the right thing if the arch does not provide operations.

^ permalink raw reply

* Re: [PATCH -next] x86, fs: add sys_compat_write for net/socket.c
From: H. Peter Anvin @ 2010-03-30 17:56 UTC (permalink / raw)
  To: Florian Westphal
  Cc: linux-fsdevel, Al Viro, David S. Miller, Thomas Gleixner,
	Ingo Molnar, x86, netdev, linux-kernel
In-Reply-To: <1269971469-1254-1-git-send-email-fw@strlen.de>

On 03/30/2010 10:51 AM, Florian Westphal wrote:
> On some configurations, e.g. x86_64 with 32bit userspace, netlink/xfrm
> misinterprets messages from userspace due to different structure
> layout (u64 has different alignment requirements on x86 vs. x86_64).
> 
> As long as messages are sent via sendmsg(), this could be handled via
> net/compat.c; it will set the CMSG_MSG_COMPAT flag in struct msghdr
> for compat tasks, which would allow to the xfrm_user code to detect
> when messages need compat fixups.
> 
> Unfortunately, some programs (e.g. pluto ike daemon), send netlink data
> to the kernel using write().
> 
> Thus, introduce f_ops->compat_aio_write and compat_sys_write to treat
> writes on sockets specially.
> 
> This only wires up compat_sys_write for x86/x86_64 -- at the moment this
> is only required to parse xfrm netlink messages, which happen to only
> need special treatment in case of COMPAT_FOR_U64_ALIGNMENT=y.
> 
> Setting CMSG_MSG_COMPAT depending on plain is_compat_task() in net/socket.c
> was not done due to concerns regarding the kernel doing socket
> writes in response to a user event (which might set MSG_COMPAT erronously).
> 

OK... I have to ask the question:

This only applies if you're using unpacked structures with
non-naturally-aligned objects in them.  Where to we have those, and can
we shoot the authors?

	-hpa

^ permalink raw reply

* Re: Tiny patch (w/ discussion) to provide the peer information on unix domain sockets
From: Erkki Seppala @ 2010-03-30 17:39 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1269961013.2012.61.camel@edumazet-laptop>

Hi Eric,

On Tue, Mar 30, 2010 at 04:56:53PM +0200, Eric Dumazet wrote:
> Such patches should be sent to netdev

Oops! Thanks for the pointer!

> I believe you missed some necessary locking.

I don't think so, because I don't actually dereference the other unix
address, I just print the its address.

> Prior art from Kenan Kalajdzic :
> 
>  http://patchwork.ozlabs.org/patch/46561/

Perhaps this would be a more decent solution (using the more
user-space compatible concept of inodes), although I think don't that
the backwards compatiblity for this kind of rarely used feature is
that critical, given the impact of the breakage seems to be quite low
as well.

I think the way forward in general should be that user space
applications actually look what columns are available and provide
future compatibility in that fashion. And empty fields should have
have some filler :).

-- 
  _____________________________________________________________________
     / __// /__ ____  __               http://www.modeemi.fi/~flux/\   \
    / /_ / // // /\ \/ /                                            \  /
   /_/  /_/ \___/ /_/\_\@modeemi.fi                                  \/

^ permalink raw reply

* Re: [PATCH 2/2] ethtool: RXHASH flag support
From: Jeff Garzik @ 2010-03-30 17:37 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20100330103207.7fc5681a@nehalam>

On 03/30/2010 01:32 PM, Stephen Hemminger wrote:
> On Tue, 30 Mar 2010 13:29:01 -0400
> Jeff Garzik<jeff@garzik.org>  wrote:
>
>> By blindly sync'ing the ethtool.h header, ETHTOOL_MAX_NTUPLE_LIST_ENTRY
>> and its sibling ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY were removed,
>> breaking the ethtool build.
>
> In the patch I moved it to ethtool.c to have local entries.
>
> I believe that all cloned headers should only come from the result
> of kernel "make install_headers".  Not locally different vrsions.

There is nothing locally different about ethtool-copy.h.

	Jeff





^ permalink raw reply

* Re: [PATCH 2/2] ethtool: RXHASH flag support
From: Stephen Hemminger @ 2010-03-30 17:32 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev
In-Reply-To: <4BB234DD.9040800@garzik.org>

On Tue, 30 Mar 2010 13:29:01 -0400
Jeff Garzik <jeff@garzik.org> wrote:

> By blindly sync'ing the ethtool.h header, ETHTOOL_MAX_NTUPLE_LIST_ENTRY 
> and its sibling ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY were removed, 
> breaking the ethtool build.

In the patch I moved it to ethtool.c to have local entries.

I believe that all cloned headers should only come from the result
of kernel "make install_headers".  Not locally different vrsions.


-- 

^ permalink raw reply

* Re: [PATCH 2/2] ethtool: RXHASH flag support
From: Jeff Garzik @ 2010-03-30 17:29 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20100329175352.38008e05@nehalam>

On 03/29/2010 08:53 PM, Stephen Hemminger wrote:
> Add support for RXHASH flag in ethtool offload.
> Update to current net-next sanitized version of ethtool.h
>
> Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>
> ---
>   ethtool-copy.h |   32 +++++++++++++++++++++++++-------
>   ethtool.8      |    4 ++++
>   ethtool.c      |   42 +++++++++++++++++++++++++++++++++++++-----
>   3 files changed, 66 insertions(+), 12 deletions(-)
>
> diff --git a/ethtool-copy.h b/ethtool-copy.h
> index 8681f5e..0cf8f33 100644
> --- a/ethtool-copy.h
> +++ b/ethtool-copy.h
> @@ -36,7 +36,7 @@ struct ethtool_cmd {
>   	__u32	reserved[2];
>   };
>
> -static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
> +static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
>   						__u32 speed)
>   {
>
> @@ -44,7 +44,7 @@ static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
>   	ep->speed_hi = (__u16)(speed>>  16);
>   }
>
> -static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
> +static __inline__ __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
>   {
>   	return (ep->speed_hi<<  16) | ep->speed;
>   }
> @@ -61,6 +61,13 @@ struct ethtool_drvinfo {
>   				/* For PCI devices, use pci_name(pci_dev). */
>   	char	reserved1[32];
>   	char	reserved2[12];
> +				/*
> +				 * Some struct members below are filled in
> +				 * using ops->get_sset_count().  Obtaining
> +				 * this info from ethtool_drvinfo is now
> +				 * deprecated; Use ETHTOOL_GSSET_INFO
> +				 * instead.
> +				 */
>   	__u32	n_priv_flags;	/* number of flags valid in ETHTOOL_GPFLAGS */
>   	__u32	n_stats;	/* number of u64's from ETHTOOL_GSTATS */
>   	__u32	testinfo_len;
> @@ -253,6 +260,17 @@ struct ethtool_gstrings {
>   	__u8	data[0];
>   };
>
> +struct ethtool_sset_info {
> +	__u32	cmd;		/* ETHTOOL_GSSET_INFO */
> +	__u32	reserved;
> +	__u64	sset_mask;	/* input: each bit selects an sset to query */
> +				/* output: each bit a returned sset */
> +	__u32	data[0];	/* ETH_SS_xxx count, in order, based on bits
> +				   in sset_mask.  One bit implies one
> +				   __u32, two bits implies two
> +				   __u32's, etc. */
> +};
> +
>   enum ethtool_test_flags {
>   	ETH_TEST_FL_OFFLINE	= (1<<  0),	/* online / offline */
>   	ETH_TEST_FL_FAILED	= (1<<  1),	/* test passed / failed */
> @@ -292,6 +310,7 @@ struct ethtool_perm_addr {
>   enum ethtool_flags {
>   	ETH_FLAG_LRO		= (1<<  15),	/* LRO is enabled */
>   	ETH_FLAG_NTUPLE		= (1<<  27),	/* N-tuple filters enabled */
> +	ETH_FLAG_RXHASH		= (1<<  28),
>   };
>
>   /* The following structures are for supporting RX network flow
> @@ -389,8 +408,6 @@ struct ethtool_rx_ntuple_flow_spec {
>   #define ETHTOOL_RXNTUPLE_ACTION_DROP -1
>   };
>
> -#define ETHTOOL_MAX_NTUPLE_LIST_ENTRY 1024
> -#define ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY 14
>   struct ethtool_rx_ntuple {
>   	__u32					cmd;
>   	struct ethtool_rx_ntuple_flow_spec	fs;
> @@ -408,6 +425,7 @@ struct ethtool_flash {
>   	char	data[ETHTOOL_FLASH_MAX_FILENAME];
>   };
>
> +
>   /* CMDs currently supported */
>   #define ETHTOOL_GSET		0x00000001 /* Get settings. */
>   #define ETHTOOL_SSET		0x00000002 /* Set settings. */
> @@ -463,9 +481,9 @@ struct ethtool_flash {
>   #define	ETHTOOL_SRXCLSRLINS	0x00000032 /* Insert RX classification rule */
>   #define	ETHTOOL_FLASHDEV	0x00000033 /* Flash firmware to device */
>   #define	ETHTOOL_RESET		0x00000034 /* Reset hardware */
> -
> -#define ETHTOOL_SRXNTUPLE	0x00000035 /* Add an n-tuple filter to device */
> -#define ETHTOOL_GRXNTUPLE	0x00000036 /* Get n-tuple filters from device */
> +#define	ETHTOOL_SRXNTUPLE	0x00000035 /* Add an n-tuple filter to device */
> +#define	ETHTOOL_GRXNTUPLE	0x00000036 /* Get n-tuple filters from device */
> +#define	ETHTOOL_GSSET_INFO	0x00000037 /* Get string set info */
>

NAK - you broke the build.  You should also know not to combine patches 
like this.  Linux 101: separate changes, separate patches.

By blindly sync'ing the ethtool.h header, ETHTOOL_MAX_NTUPLE_LIST_ENTRY 
and its sibling ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY were removed, 
breaking the ethtool build.

Furthermore, I just pulled net-next and did my own sync, and those 
s/inline/__inline__/ substitutions are not present.

I went ahead and made sure everything is sync'd correctly and building 
correctly, in the ethtool git repo.  Please resubmit a patch DIRECTLY 
and ONLY related to RXHASH flag support.  If you decide to do any other 
work, that belongs in a separate patch.

	Jeff





^ permalink raw reply

* Re: [PATCH v3 04/12] l2tp: Add ppp device name to L2TP ppp session data
From: Stephen Hemminger @ 2010-03-30 16:29 UTC (permalink / raw)
  To: James Chapman; +Cc: netdev
In-Reply-To: <20100330161746.9628.40723.stgit@bert.katalix.com>

On Tue, 30 Mar 2010 17:17:46 +0100
James Chapman <jchapman@katalix.com> wrote:

> When dumping L2TP PPP sessions using /proc/net/l2tp, get
> the assigned PPP device name from PPP using ppp_dev_name().
> 
> Signed-off-by: James Chapman <jchapman@katalix.com>
> Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
>

Why is this a necessary API?
Why not put it in debugfs if just a debugging tool?

^ permalink raw reply

* Re: [PATCH v3 10/12] l2tp: Add L2TP ethernet pseudowire support
From: Stephen Hemminger @ 2010-03-30 16:32 UTC (permalink / raw)
  To: James Chapman; +Cc: netdev
In-Reply-To: <20100330161819.9628.10853.stgit@bert.katalix.com>

On Tue, 30 Mar 2010 17:18:19 +0100
James Chapman <jchapman@katalix.com> wrote:

> +struct l2tp_eth_net {
> +	struct list_head l2tp_eth_dev_list;
> +	rwlock_t l2tp_eth_lock;
> +};

Reader/write locks are discouraged because they are slower than
spin locks.  If you have lots of readers use RCU, if reading
is infrequent just use a spin lock.

-- 

^ permalink raw reply

* Re: [PATCH v3 10/12] l2tp: Add L2TP ethernet pseudowire support
From: Stephen Hemminger @ 2010-03-30 16:30 UTC (permalink / raw)
  To: James Chapman; +Cc: netdev
In-Reply-To: <20100330161819.9628.10853.stgit@bert.katalix.com>

On Tue, 30 Mar 2010 17:18:19 +0100
James Chapman <jchapman@katalix.com> wrote:

> +
> +	/* Derive a MAC address for the new interface. We use the L2TP
> +	 * session's session-id to guarantee a system-wide unique
> +	 * address. This MAC is only visible within the L2TP session.
> +	 */
> +	dev->dev_addr[0] = 0x02; /* IEEE 802 local */
> +	dev->dev_addr[1] = 'L';
> +	memcpy(&dev->dev_addr[2], &sid, 4);

Why not random ether address?


-- 

^ permalink raw reply

* Re: [PATCH v3 10/12] l2tp: Add L2TP ethernet pseudowire support
From: Stephen Hemminger @ 2010-03-30 16:30 UTC (permalink / raw)
  To: James Chapman; +Cc: netdev
In-Reply-To: <20100330161819.9628.10853.stgit@bert.katalix.com>

On Tue, 30 Mar 2010 17:18:19 +0100
James Chapman <jchapman@katalix.com> wrote:

> static inline struct l2tp_eth_net *l2tp_eth_pernet(struct net *net)
> +{
> +	BUG_ON(!net);
> +
> +	return net_generic(net, l2tp_eth_net_id);
> +}

Don't test for NULL with BUG_ON. It is redundant, the null
dereference will cause the same kind of backtrace failure.


-- 

^ permalink raw reply

* Re: [PATCH 1/2] netdev: ethtool RXHASH flag
From: Jeff Garzik @ 2010-03-30 17:19 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20100329174727.4654e19c@nehalam>

On 03/29/2010 08:47 PM, Stephen Hemminger wrote:
> This adds ethtool and device feature flag to allow control
> of receive hashing offload.
>
> Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>

Acked-by: Jeff Garzik <jgarzik@redhat.com>



^ permalink raw reply

* Re: [PATCH] net/pcmcia 3com: replacements of printk() with dev_info() and friends (fwd)
From: Joe Perches @ 2010-03-30 17:22 UTC (permalink / raw)
  To: Alexander Kurz
  Cc: David S. Miller, Ken Kawasaki, Dominik Brodowski, Magnus Damm,
	Ben Hutchings, netdev, linux-kernel
In-Reply-To: <alpine.DEB.1.10.1003302019200.11637@blala.de>

On Tue, 2010-03-30 at 21:01 +0400, Alexander Kurz wrote:
>   I wrote a patch as suggested by kernel-janitors.
>   It is my first patch, so I highly welcome comments and hints,
>   thanks, Alexander Kurz

As this is a network driver, you could use netdev_<level>
for most of this.  Also, you could coalesce the format
strings to go beyond 80 columns.  It makes grepping
a bit easier.

> -	printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
> +	dev_info(&dev->dev, "%s: %s at io %#3lx, irq %d, "
>   	       "hw_addr %pM.\n",

This could become:

	netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n"
		    cardname, dev->base_addr, dev->irq, dev->dev_addr);

etc.



^ permalink raw reply

* Re: [PATCH] net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register()
From: John W. Linville @ 2010-03-30 17:20 UTC (permalink / raw)
  To: Dan Williams
  Cc: Holger Schurig, Daniel Mack, libertas-dev, netdev, linux-wireless,
	linux-kernel
In-Reply-To: <1269968673.3019.37.camel@localhost.localdomain>

On Tue, Mar 30, 2010 at 10:04:33AM -0700, Dan Williams wrote:
> On Tue, 2010-03-30 at 12:59 +0200, Holger Schurig wrote:
> > > I don't get your point. The patch I submitted fixes an Ooops in the
> > > driver, due to wrong handling of an API. What does that have to do with
> > > principle discussions about the frameworks in use?
> > 
> > I asked if there is a better method, and you said that you would test a better 
> > solution. That means that someone else should make a better solution.
> > 
> > I just pointed out that I won't be the one who creates the better solution, 
> > because for fundamental reasons I don't see the libertas+cfg80211 approach 
> > going forward. That issue has nothing to do with you or your patch, so please 
> > don't feel offended or confused.
> 
> Fine; just rip out the mesh code and do the vanilla cfg80211 conversion
> for infra & adhoc, and we'll add the mesh code back later.  I don't have
> time to do the cfg80211 bits, neither do the OLPC guys (AFAIK), so lets
> take advantage of your willingness to do this and just move the driver
> forward.

Someone post a feature removal patch, please?

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [ethtool PATCH v4] ethtool: Correctly pull n-tuple string length for get_rx_ntuple
From: Jeff Garzik @ 2010-03-30 17:11 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: netdev, gospo
In-Reply-To: <20100304085328.4510.9284.stgit@localhost.localdomain>

On 03/04/2010 03:53 AM, Jeff Kirsher wrote:
> From: Peter Waskiewicz<peter.p.waskiewicz.jr@intel.com>
>
> This patch fixes inconsistencies with the kernel header files, while
> correctly gets the variable length string counts for the get_rx_ntuple
> return value.  It does this by using the new GSSET_INFO ioctl.
>
> Signed-off-by: Peter P Waskiewicz Jr<peter.p.waskiewicz.jr@intel.com>
> Signed-off-by: Jeff Kirsher<jeffrey.t.kirsher@intel.com>
> ---
>
>   ethtool-copy.h |   14 ++++++++++++--
>   ethtool.c      |   19 ++++++++++++++++---
>   2 files changed, 28 insertions(+), 5 deletions(-)

applied



^ permalink raw reply

* Re: [PATCH 2/2] ath: fix code readability in regd.c
From: Luis de Bethencourt @ 2010-03-30 17:08 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: linville@tuxdriver.com, Luis Rodriguez,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20100330165645.GB25095@tux>

On Tue, Mar 30, 2010 at 5:56 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Tue, Mar 30, 2010 at 08:44:33AM -0700, Luis de Bethencourt wrote:
>> This is a patch to the ath/regd.c file that fixes two code
>> readability issues. A space between to separate two defines
>> and the indentation inside the ath_redg_is_eeprom_valid
>> function.
>
> Acked-by: Luis R. Rodriguez <lrodriguez@atheros.com>
>
> You can drop netdev and linux-kernel from future linux-wireless e-mails
> like this one.
>
>  Luis
>

OK. Will do.

Luis

^ permalink raw reply

* Re: [PATCH] net/wireless/libertas: do not call wiphy_unregister() w/o wiphy_register()
From: Dan Williams @ 2010-03-30 17:04 UTC (permalink / raw)
  To: Holger Schurig
  Cc: Daniel Mack, libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, John W. Linville
In-Reply-To: <201003301259.23973.hs4233-x6+DxXLjN1AJvtFkdXX2Hg4jNU5vUVPG@public.gmane.org>

On Tue, 2010-03-30 at 12:59 +0200, Holger Schurig wrote:
> > I don't get your point. The patch I submitted fixes an Ooops in the
> > driver, due to wrong handling of an API. What does that have to do with
> > principle discussions about the frameworks in use?
> 
> I asked if there is a better method, and you said that you would test a better 
> solution. That means that someone else should make a better solution.
> 
> I just pointed out that I won't be the one who creates the better solution, 
> because for fundamental reasons I don't see the libertas+cfg80211 approach 
> going forward. That issue has nothing to do with you or your patch, so please 
> don't feel offended or confused.

Fine; just rip out the mesh code and do the vanilla cfg80211 conversion
for infra & adhoc, and we'll add the mesh code back later.  I don't have
time to do the cfg80211 bits, neither do the OLPC guys (AFAIK), so lets
take advantage of your willingness to do this and just move the driver
forward.

Dan

> 
> Basically, I neither ack nor nak you patch. Given that it fixes an oops the 
> patch should go in, and probably to stable at well. I just gave a hint, to 
> make you think if you could come up with something better.
> 
> 
> 
> BTW, testing/fixing of failure paths in libertas as well as simplifying the 
> call sequence of functions during initialisation could be quite useful.
> 
> _______________________________________________
> libertas-dev mailing list
> libertas-dev-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev


--
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] net/pcmcia 3com: replacements of printk() with dev_info() and friends (fwd)
From: Alexander Kurz @ 2010-03-30 17:01 UTC (permalink / raw)
  To: David S. Miller, Ken Kawasaki, Dominik Brodowski, Magnus Damm,
	Ben 
  Cc: netdev, linux-kernel

Hi,
  I wrote a patch as suggested by kernel-janitors.
  It is my first patch, so I highly welcome comments and hints,
  thanks, Alexander Kurz

---------- Forwarded message ----------
Date: Tue, 30 Mar 2010 18:55:33 +0400 (MSD)
From: Alexander Kurz <akurz@blala.de>
To: kernel-janitors@vger.kernel.org
Subject: [PATCH] net/pcmcia 3com: replacements of printk() with dev_info() and
     friends

Hello List,
  I wrote a patch replacing some printk() with dev_info() and friends
  for 3com 16-bit PCMCIA cards.
  As this is my first linux patch, comments are welcome,
  thanks, Alexander Kurz

---------- Forwarded message ----------
Date: Tue, 30 Mar 2010 18:51:43 +0400
From: Alexander Kurz <akurz@blala.de>
To: akurz@blala.de

> From 84616314b126b730528ca10e704d80eabad96ff8 Mon Sep 17 00:00:00 2001
From: Alexander Kurz <akurz@kbdbabel.org>
Date: Tue, 30 Mar 2010 12:08:54 +0200
Subject: [PATCH] net/pcmcia 3com: replacements of printk() with dev_info() and 
friends
  as suggested by kernel-janitors for 3com 16-bit PCMCIA cards

---
  drivers/net/pcmcia/3c574_cs.c |   37 +++++++++++++++++--------------------
  drivers/net/pcmcia/3c589_cs.c |   41 +++++++++++++++++++----------------------
  2 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 3d1d3a7..639cd21 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -396,7 +396,7 @@ static int tc574_config(struct pcmcia_device *link)
  		outw(2<<11, ioaddr + RunnerRdCtrl);
  		mcr = inb(ioaddr + 2);
  		outw(0<<11, ioaddr + RunnerRdCtrl);
-		printk(KERN_INFO "  ASIC rev %d,", mcr>>3);
+		dev_info(&dev->dev, "  ASIC rev %d,", mcr>>3);
  		EL3WINDOW(3);
  		config = inl(ioaddr + Wn3_Config);
  		lp->default_media = (config & Xcvr) >> Xcvr_shift;
@@ -457,11 +457,11 @@ static int tc574_config(struct pcmcia_device *link)

  	strcpy(lp->node.dev_name, dev->name);

-	printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
+	dev_info(&dev->dev, "%s: %s at io %#3lx, irq %d, "
  	       "hw_addr %pM.\n",
  	       dev->name, cardname, dev->base_addr, dev->irq,
  	       dev->dev_addr);
-	printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
+	dev_info(&dev->dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n",
  		   8 << config & Ram_size,
  		   ram_split[(config & Ram_split) >> Ram_split_shift],
  		   config & Autoselect ? "autoselect " : "");
@@ -511,12 +511,12 @@ static void dump_status(struct net_device *dev)
  {
  	unsigned int ioaddr = dev->base_addr;
  	EL3WINDOW(1);
-	printk(KERN_INFO "  irq status %04x, rx status %04x, tx status "
+	dev_info(&dev->dev, "  irq status %04x, rx status %04x, tx status "
  		   "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS),
  		   inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
  		   inw(ioaddr+TxFree));
  	EL3WINDOW(4);
-	printk(KERN_INFO "  diagnostics: fifo %04x net %04x ethernet %04x"
+	dev_info(&dev->dev, "  diagnostics: fifo %04x net %04x ethernet %04x"
  		   " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06),
  		   inw(ioaddr+0x08), inw(ioaddr+0x0a));
  	EL3WINDOW(1);
@@ -532,7 +532,7 @@ static void tc574_wait_for_completion(struct net_device 
*dev, int cmd)
  	while (--i > 0)
  		if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break;
  	if (i == 0)
-		printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", 
dev->name, cmd);
+		dev_notice(&dev->dev, "command 0x%04x did not complete!\n", 
cmd);
  }

  /* Read a word from the EEPROM using the regular EEPROM access register.
@@ -736,7 +736,7 @@ static void el3_tx_timeout(struct net_device *dev)
  {
  	unsigned int ioaddr = dev->base_addr;

-	printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
+	dev_notice(&dev->dev, "Transmit timed out!\n");
  	dump_status(dev);
  	dev->stats.tx_errors++;
  	dev->trans_start = jiffies;
@@ -856,8 +856,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
  				EL3WINDOW(4);
  				fifo_diag = inw(ioaddr + Wn4_FIFODiag);
  				EL3WINDOW(1);
-				printk(KERN_NOTICE "%s: adapter failure, FIFO 
diagnostic"
-					   " register %04x.\n", dev->name, 
fifo_diag);
+				dev_notice(&dev->dev, "adapter failure, FIFO 
diagnostic"
+					   " register %04x.\n", fifo_diag);
  				if (fifo_diag & 0x0400) {
  					/* Tx overrun */
  					tc574_wait_for_completion(dev, 
TxReset);
@@ -911,7 +911,7 @@ static void media_check(unsigned long arg)
  	   this, we can limp along even if the interrupt is blocked */
  	if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 
0xff)) {
  		if (!lp->fast_poll)
-			printk(KERN_INFO "%s: interrupt(s) dropped!\n", 
dev->name);
+			dev_info(&dev->dev, "interrupt(s) dropped!\n");

  		local_irq_save(flags);
  		el3_interrupt(dev->irq, dev);
@@ -934,23 +934,21 @@ static void media_check(unsigned long arg)

  	if (media != lp->media_status) {
  		if ((media ^ lp->media_status) & 0x0004)
-			printk(KERN_INFO "%s: %s link beat\n", dev->name,
+			dev_info(&dev->dev, "%s link beat\n",
  				   (lp->media_status & 0x0004) ? "lost" : 
"found");
  		if ((media ^ lp->media_status) & 0x0020) {
  			lp->partner = 0;
  			if (lp->media_status & 0x0020) {
-				printk(KERN_INFO "%s: autonegotiation 
restarted\n",
-					   dev->name);
+				dev_info(&dev->dev, "autonegotiation 
restarted\n");
  			} else if (partner) {
  				partner &= lp->advertising;
  				lp->partner = partner;
-				printk(KERN_INFO "%s: autonegotiation complete: 
"
-					   "%sbaseT-%cD selected\n", dev->name,
+				dev_info(&dev->dev, "autonegotiation complete: 
"
+					   "%sbaseT-%cD selected\n",
  					   ((partner & 0x0180) ? "100" : "10"),
  					   ((partner & 0x0140) ? 'F' : 'H'));
  			} else {
-				printk(KERN_INFO "%s: link partner did not 
autonegotiate\n",
-					   dev->name);
+				dev_info(&dev->dev, "link partner did not 
autonegotiate\n");
  			}

  			EL3WINDOW(3);
@@ -960,10 +958,9 @@ static void media_check(unsigned long arg)

  		}
  		if (media & 0x0010)
-			printk(KERN_INFO "%s: remote fault detected\n",
-				   dev->name);
+			dev_info(&dev->dev, "remote fault detected\n");
  		if (media & 0x0002)
-			printk(KERN_INFO "%s: jabber detected\n", dev->name);
+			dev_info(&dev->dev, "jabber detected\n");
  		lp->media_status = media;
  	}
  	spin_unlock_irqrestore(&lp->window_lock, flags);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 091e0b0..9f6736b 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -324,11 +324,11 @@ static int tc589_config(struct pcmcia_device *link)

      strcpy(lp->node.dev_name, dev->name);

-    printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, "
+    dev_info(&dev->dev, "3Com 3c%s, io %#3lx, irq %d, "
  	   "hw_addr %pM\n",
-	   dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq,
+	   (multi ? "562" : "589"), dev->base_addr, dev->irq,
  	   dev->dev_addr);
-    printk(KERN_INFO "  %dK FIFO split %s Rx:Tx, %s xcvr\n",
+    dev_info(&dev->dev, "  %dK FIFO split %s Rx:Tx, %s xcvr\n",
  	   (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
  	   if_names[dev->if_port]);
      return 0;
@@ -385,8 +385,7 @@ static void tc589_wait_for_completion(struct net_device 
*dev, int cmd)
      while (--i > 0)
  	if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break;
      if (i == 0)
-	printk(KERN_WARNING "%s: command 0x%04x did not complete!\n",
-	       dev->name, cmd);
+	dev_warn(&dev->dev, "command 0x%04x did not complete!\n", cmd);
  }

  /*
@@ -435,12 +434,12 @@ static void dump_status(struct net_device *dev)
  {
      unsigned int ioaddr = dev->base_addr;
      EL3WINDOW(1);
-    printk(KERN_INFO "  irq status %04x, rx status %04x, tx status "
+    dev_info(&dev->dev, "  irq status %04x, rx status %04x, tx status "
  	   "%02x  tx free %04x\n", inw(ioaddr+EL3_STATUS),
  	   inw(ioaddr+RX_STATUS), inb(ioaddr+TX_STATUS),
  	   inw(ioaddr+TX_FREE));
      EL3WINDOW(4);
-    printk(KERN_INFO "  diagnostics: fifo %04x net %04x ethernet %04x"
+    dev_info(&dev->dev, "  diagnostics: fifo %04x net %04x ethernet %04x"
  	   " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06),
  	   inw(ioaddr+0x08), inw(ioaddr+0x0a));
      EL3WINDOW(1);
@@ -504,8 +503,8 @@ static int el3_config(struct net_device *dev, struct ifmap 
*map)
      if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
  	if (map->port <= 3) {
  	    dev->if_port = map->port;
-	    printk(KERN_INFO "%s: switched to %s port\n",
-		   dev->name, if_names[dev->if_port]);
+	    dev_info(&dev->dev, "switched to %s port\n",
+		   if_names[dev->if_port]);
  	    tc589_set_xcvr(dev, dev->if_port);
  	} else
  	    return -EINVAL;
@@ -541,7 +540,7 @@ static void el3_tx_timeout(struct net_device *dev)
  {
      unsigned int ioaddr = dev->base_addr;

-    printk(KERN_WARNING "%s: Transmit timed out!\n", dev->name);
+    dev_warn(&dev->dev, "Transmit timed out!\n");
      dump_status(dev);
      dev->stats.tx_errors++;
      dev->trans_start = jiffies;
@@ -660,8 +659,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
  		EL3WINDOW(4);
  		fifo_diag = inw(ioaddr + 4);
  		EL3WINDOW(1);
-		printk(KERN_WARNING "%s: adapter failure, FIFO diagnostic"
-		       " register %04x.\n", dev->name, fifo_diag);
+		dev_warn(&dev->dev, "adapter failure, FIFO diagnostic"
+		       " register %04x.\n", fifo_diag);
  		if (fifo_diag & 0x0400) {
  		    /* Tx overrun */
  		    tc589_wait_for_completion(dev, TxReset);
@@ -678,8 +677,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
  	}

  	if (++i > 10) {
-	    printk(KERN_ERR "%s: infinite loop in interrupt, "
-		   "status %4.4x.\n", dev->name, status);
+	    dev_err(&dev->dev, "infinite loop in interrupt, "
+		   "status %4.4x.\n", status);
  	    /* Clear all interrupts */
  	    outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
  	    break;
@@ -710,7 +709,7 @@ static void media_check(unsigned long arg)
      if ((inw(ioaddr + EL3_STATUS) & IntLatch) &&
  	(inb(ioaddr + EL3_TIMER) == 0xff)) {
  	if (!lp->fast_poll)
-	    printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name);
+	    dev_warn(&dev->dev, "interrupt(s) dropped!\n");

  	local_irq_save(flags);
  	el3_interrupt(dev->irq, dev);
@@ -747,25 +746,23 @@ static void media_check(unsigned long arg)
      if (media != lp->media_status) {
  	if ((media & lp->media_status & 0x8000) &&
  	    ((lp->media_status ^ media) & 0x0800))
-	    printk(KERN_INFO "%s: %s link beat\n", dev->name,
+	    dev_info(&dev->dev, "%s link beat\n",
  		   (lp->media_status & 0x0800 ? "lost" : "found"));
  	else if ((media & lp->media_status & 0x4000) &&
  		 ((lp->media_status ^ media) & 0x0010))
-	    printk(KERN_INFO "%s: coax cable %s\n", dev->name,
+	    dev_info(&dev->dev, "coax cable %s\n",
  		   (lp->media_status & 0x0010 ? "ok" : "problem"));
  	if (dev->if_port == 0) {
  	    if (media & 0x8000) {
  		if (media & 0x0800)
-		    printk(KERN_INFO "%s: flipped to 10baseT\n",
-			   dev->name);
+		    dev_info(&dev->dev, "flipped to 10baseT\n");
  		else
  		    tc589_set_xcvr(dev, 2);
  	    } else if (media & 0x4000) {
  		if (media & 0x0010)
  		    tc589_set_xcvr(dev, 1);
  		else
-		    printk(KERN_INFO "%s: flipped to 10base2\n",
-			   dev->name);
+		    dev_info(&dev->dev, "flipped to 10base2\n");
  	    }
  	}
  	lp->media_status = media;
@@ -875,7 +872,7 @@ static int el3_rx(struct net_device *dev)
  	tc589_wait_for_completion(dev, RxDiscard);
      }
      if (worklimit == 0)
-	printk(KERN_WARNING "%s: too much work in el3_rx!\n", dev->name);
+	dev_warn(&dev->dev, "too much work in el3_rx!\n");
      return 0;
  }

-- 
1.7.0

^ permalink raw reply related

* Re: [PATCH 2/2] ath: fix code readability in regd.c
From: Luis R. Rodriguez @ 2010-03-30 16:56 UTC (permalink / raw)
  To: Luis de Bethencourt
  Cc: linville@tuxdriver.com, Luis Rodriguez,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <1269963873-2070-1-git-send-email-luisbg@ubuntu.com>

On Tue, Mar 30, 2010 at 08:44:33AM -0700, Luis de Bethencourt wrote:
> This is a patch to the ath/regd.c file that fixes two code
> readability issues. A space between to separate two defines
> and the indentation inside the ath_redg_is_eeprom_valid
> function.

Acked-by: Luis R. Rodriguez <lrodriguez@atheros.com>

You can drop netdev and linux-kernel from future linux-wireless e-mails
like this one.

  Luis

^ permalink raw reply

* Re: [PATCH] gianfar: Fix a memory leak in gianfar close code
From: Laurent Chavey @ 2010-03-30 16:50 UTC (permalink / raw)
  To: Andy Fleming; +Cc: davem, netdev, eric.dumazet, Sandeep.Kumar
In-Reply-To: <1269913343-6566-1-git-send-email-afleming@freescale.com>

since free_skb_[rx | tx]_queue() expects rx_queue->rx_skbuff to not be NULL
what about moving the conditional if(rx_queue->rx_skbuff)
in free_skb_rx_queue() and  if(tx_queue->tx_skbuff) in free_skb_tx_queue()
OR put an assertion for not NULL in those functions ?



On Mon, Mar 29, 2010 at 6:42 PM, Andy Fleming <afleming@freescale.com> wrote:
> gianfar needed to ensure existence of the *skbuff arrays before
> freeing the skbs in them, rather than ensuring their nonexistence.
>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> ---
>  drivers/net/gianfar.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index b671555..ad59608 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -1638,13 +1638,13 @@ static void free_skb_resources(struct gfar_private *priv)
>        /* Go through all the buffer descriptors and free their data buffers */
>        for (i = 0; i < priv->num_tx_queues; i++) {
>                tx_queue = priv->tx_queue[i];
> -               if(!tx_queue->tx_skbuff)
> +               if(tx_queue->tx_skbuff)
>                        free_skb_tx_queue(tx_queue);
>        }
>
>        for (i = 0; i < priv->num_rx_queues; i++) {
>                rx_queue = priv->rx_queue[i];
> -               if(!rx_queue->rx_skbuff)
> +               if(rx_queue->rx_skbuff)
>                        free_skb_rx_queue(rx_queue);
>        }
>
> --
> 1.6.5.2.g6ff9a
>
> --
> 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
>

^ permalink raw reply

* RE: UDP path MTU discovery
From: Templin, Fred L @ 2010-03-30 15:58 UTC (permalink / raw)
  To: Andi Kleen, Edgar E. Iglesias
  Cc: Eric Dumazet, Rick Jones, Glen Turner, netdev@vger.kernel.org
In-Reply-To: <20100330061952.GO20695@one.firstfloor.org>



> -----Original Message-----
> From: Andi Kleen [mailto:andi@firstfloor.org]
> Sent: Monday, March 29, 2010 11:20 PM
> To: Edgar E. Iglesias
> Cc: Andi Kleen; Templin, Fred L; Eric Dumazet; Rick Jones; Glen Turner; netdev@vger.kernel.org
> Subject: Re: UDP path MTU discovery
> 
> > If you don't want to hassle with all of that, the app can stick to
> > 1280 (or I guess for the extreme/lazy cases turn on fragmentation)..
> 
> See the early mails in this thread. This is about apps who can't
> limit themselves to 1280, but still don't want full blown PMTU.
> [They probably should, but it can be a lot of work]

Right. Some apps may need to send isolated packets that
are larger than the path MTU without invoking path MTU
discovery.
 
> The MTU would allow to force fragmentation on the sending host
> as a workaround similar to IPv4.

Right again. Unlike IPv4, however, IPv6 does not allow
in-the-network fragmentation. So when in doubt, apps
that need to send isolated packets that may violate the
path MTU should really perform host-based fragmentation
with a maximum fragment size of 1280. Isn't there a
socket option "IPV6_USE_MIN_MTU" that apps can use to
force fragmentation on large packets (RFC3542)?

Caveat - the app may have no way of knowing whether
the destination is capable of reassembling fragmented
packets larger than 1500...

Fred
fred.l.templin@boeing.com

> -Andi
> --
> ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply

* [PATCH v3 12/12] l2tp: Update documentation
From: James Chapman @ 2010-03-30 16:18 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20100330161725.9628.69994.stgit@bert.katalix.com>

This patch adds documentation about the L2TPv3 functionality.

Signed-off-by: James Chapman <jchapman@katalix.com>
Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
---
 Documentation/networking/l2tp.txt |  233 ++++++++++++++++++++++++++++++++-----
 1 files changed, 199 insertions(+), 34 deletions(-)

diff --git a/Documentation/networking/l2tp.txt b/Documentation/networking/l2tp.txt
index 63214b2..8b5a7b7 100644
--- a/Documentation/networking/l2tp.txt
+++ b/Documentation/networking/l2tp.txt
@@ -1,44 +1,95 @@
-This brief document describes how to use the kernel's PPPoL2TP driver
-to provide L2TP functionality. L2TP is a protocol that tunnels one or
-more PPP sessions over a UDP tunnel. It is commonly used for VPNs
+This document describes how to use the kernel's L2TP drivers to
+provide L2TP functionality. L2TP is a protocol that tunnels one or
+more sessions over an IP tunnel. It is commonly used for VPNs
 (L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
-network infrastructure.
+network infrastructure. With L2TPv3, it is also useful as a Layer-2
+tunneling infrastructure.
+
+Features
+========
+
+L2TPv2 (PPP over L2TP (UDP tunnels)).
+L2TPv3 ethernet pseudowires.
+L2TPv3 PPP pseudowires.
+L2TPv3 IP encapsulation.
+Netlink sockets for L2TPv3 configuration management.
+
+History
+=======
+
+The original pppol2tp driver was introduced in 2.6.23 and provided
+L2TPv2 functionality (rfc2661). L2TPv2 is used to tunnel one or more PPP
+sessions over a UDP tunnel.
+
+L2TPv3 (rfc3931) changes the protocol to allow different frame types
+to be passed over an L2TP tunnel by moving the PPP-specific parts of
+the protocol out of the core L2TP packet headers. Each frame type is
+known as a pseudowire type. Ethernet, PPP, HDLC, Frame Relay and ATM
+pseudowires for L2TP are defined in separate RFC standards. Another
+change for L2TPv3 is that it can be carried directly over IP with no
+UDP header (UDP is optional). It is also possible to create static
+unmanaged L2TPv3 tunnels manually without a control protocol
+(userspace daemon) to manage them.
+
+To support L2TPv3, the original pppol2tp driver was split up to
+separate the L2TP and PPP functionality. Existing L2TPv2 userspace
+apps should be unaffected as the original pppol2tp sockets API is
+retained. L2TPv3, however, uses netlink to manage L2TPv3 tunnels and
+sessions.
 
 Design
 ======
 
-The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by
-which PPP frames carried through an L2TP session are passed through
-the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all
-PPP interaction with the peer. PPP network interfaces are created for
-each local PPP endpoint.
-
-The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP
-control and data frames. L2TP control frames carry messages between
-L2TP clients/servers and are used to setup / teardown tunnels and
-sessions. An L2TP client or server is implemented in userspace and
-will use a regular UDP socket per tunnel. L2TP data frames carry PPP
-frames, which may be PPP control or PPP data. The kernel's PPP
+The L2TP protocol separates control and data frames.  The L2TP kernel
+drivers handle only L2TP data frames; control frames are always
+handled by userspace. L2TP control frames carry messages between L2TP
+clients/servers and are used to setup / teardown tunnels and
+sessions. An L2TP client or server is implemented in userspace.
+
+Each L2TP tunnel is implemented using a UDP or L2TPIP socket; L2TPIP
+provides L2TPv3 IP encapsulation (no UDP) and is implemented using a
+new l2tpip socket family. The tunnel socket is typically created by
+userspace, though for unmanaged L2TPv3 tunnels, the socket can also be
+created by the kernel. Each L2TP session (pseudowire) gets a network
+interface instance. In the case of PPP, these interfaces are created
+indirectly by pppd using a pppol2tp socket. In the case of ethernet,
+the netdevice is created upon a netlink request to create an L2TPv3
+ethernet pseudowire.
+
+For PPP, the PPPoL2TP driver, net/l2tp/l2tp_ppp.c, provides a
+mechanism by which PPP frames carried through an L2TP session are
+passed through the kernel's PPP subsystem. The standard PPP daemon,
+pppd, handles all PPP interaction with the peer. PPP network
+interfaces are created for each local PPP endpoint. The kernel's PPP
 subsystem arranges for PPP control frames to be delivered to pppd,
 while data frames are forwarded as usual.
 
+For ethernet, the L2TPETH driver, net/l2tp/l2tp_eth.c, implements a
+netdevice driver, managing virtual ethernet devices, one per
+pseudowire. These interfaces can be managed using standard Linux tools
+such as "ip" and "ifconfig". If only IP frames are passed over the
+tunnel, the interface can be given an IP addresses of itself and its
+peer. If non-IP frames are to be passed over the tunnel, the interface
+can be added to a bridge using brctl. All L2TP datapath protocol
+functions are handled by the L2TP core driver.
+
 Each tunnel and session within a tunnel is assigned a unique tunnel_id
 and session_id. These ids are carried in the L2TP header of every
-control and data packet. The pppol2tp driver uses them to lookup
-internal tunnel and/or session contexts. Zero tunnel / session ids are
-treated specially - zero ids are never assigned to tunnels or sessions
-in the network. In the driver, the tunnel context keeps a pointer to
-the tunnel UDP socket. The session context keeps a pointer to the
-PPPoL2TP socket, as well as other data that lets the driver interface
-to the kernel PPP subsystem.
-
-Note that the pppol2tp kernel driver handles only L2TP data frames;
-L2TP control frames are simply passed up to userspace in the UDP
-tunnel socket. The kernel handles all datapath aspects of the
-protocol, including data packet resequencing (if enabled).
-
-There are a number of requirements on the userspace L2TP daemon in
-order to use the pppol2tp driver.
+control and data packet. (Actually, in L2TPv3, the tunnel_id isn't
+present in data frames - it is inferred from the IP connection on
+which the packet was received.) The L2TP driver uses the ids to lookup
+internal tunnel and/or session contexts to determine how to handle the
+packet. Zero tunnel / session ids are treated specially - zero ids are
+never assigned to tunnels or sessions in the network. In the driver,
+the tunnel context keeps a reference to the tunnel UDP or L2TPIP
+socket. The session context holds data that lets the driver interface
+to the kernel's network frame type subsystems, i.e. PPP, ethernet.
+
+Userspace Programming
+=====================
+
+For L2TPv2, there are a number of requirements on the userspace L2TP
+daemon in order to use the pppol2tp driver.
 
 1. Use a UDP socket per tunnel.
 
@@ -86,6 +137,35 @@ In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided
 to retrieve tunnel and session statistics from the kernel using the
 PPPoX socket of the appropriate tunnel or session.
 
+For L2TPv3, userspace must use the netlink API defined in
+include/linux/l2tp.h to manage tunnel and session contexts. The
+general procedure to create a new L2TP tunnel with one session is:-
+
+1. Open a GENL socket using L2TP_GENL_NAME for configuring the kernel
+   using netlink.
+
+2. Create a UDP or L2TPIP socket for the tunnel.
+
+3. Create a new L2TP tunnel using a L2TP_CMD_TUNNEL_CREATE
+   request. Set attributes according to desired tunnel parameters,
+   referencing the UDP or L2TPIP socket created in the previous step.
+
+4. Create a new L2TP session in the tunnel using a
+   L2TP_CMD_SESSION_CREATE request.
+
+The tunnel and all of its sessions are closed when the tunnel socket
+is closed. The netlink API may also be used to delete sessions and
+tunnels. Configuration and status info may be set or read using netlink.
+
+The L2TP driver also supports static (unmanaged) L2TPv3 tunnels. These
+are where there is no L2TP control message exchange with the peer to
+setup the tunnel; the tunnel is configured manually at each end of the
+tunnel. There is no need for an L2TP userspace application in this
+case -- the tunnel socket is created by the kernel and configured
+using parameters sent in the L2TP_CMD_TUNNEL_CREATE netlink
+request. The "ip" utility of iproute2 has commands for managing static
+L2TPv3 tunnels; do "ip l2tp help" for more information.
+
 Debugging
 =========
 
@@ -102,6 +182,55 @@ PPPOL2TP_MSG_CONTROL  userspace - kernel interface
 PPPOL2TP_MSG_SEQ      sequence numbers handling
 PPPOL2TP_MSG_DATA     data packets
 
+If enabled, /proc/net/l2tp can be used to dump kernel state about L2TP
+tunnels and sessions. However, this should not be used by applications
+to obtain L2TP state because the file format is subject to
+change. Instead, use the netlink API.
+
+Unmanaged L2TPv3 Tunnels
+========================
+
+Some commercial L2TP products support unmanaged L2TPv3 ethernet
+tunnels, where there is no L2TP control protocol; tunnels are
+configured at each side manually. New commands are available in
+iproute2's ip utility to support this.
+
+To create an L2TPv3 ethernet pseudowire between local host 192.168.1.1
+and peer 192.168.1.2, using IP addresses 10.5.1.1 and 10.5.1.2 for the
+tunnel endpoints:-
+
+# modprobe l2tp_eth
+# modprobe l2tp_netlink
+
+# ip l2tp add tunnel tunnel_id 1 peer_tunnel_id 1 udp_sport 5000 \
+  udp_dport 5000 encap udp local 192.168.1.1 remote 192.168.1.2
+# ip l2tp add session tunnel_id 1 session_id 1 peer_session_id 1
+# ifconfig -a
+# ip addr add 10.5.1.2/32 peer 10.5.1.1/32 dev l2tpeth0
+# ifconfig l2tpeth0 up
+
+Choose IP addresses to be the address of a local IP interface and that
+of the remote system. The IP addresses of the l2tpeth0 interface can be
+anything suitable.
+
+Repeat the above at the peer, with ports, tunnel/session ids and IP
+addresses reversed.  The tunnel and session IDs can be any non-zero
+32-bit number, but the values must be reversed at the peer.
+
+Host 1                         Host2
+udp_sport=5000                 udp_sport=5001
+udp_dport=5001                 udp_dport=5000
+tunnel_id=42                   tunnel_id=45
+peer_tunnel_id=45              peer_tunnel_id=42
+session_id=128                 session_id=5196755
+peer_session_id=5196755        peer_session_id=128
+
+When done at both ends of the tunnel, it should be possible to send
+data over the network. e.g.
+
+# ping 10.5.1.1
+
+
 Sample Userspace Code
 =====================
 
@@ -158,12 +287,48 @@ Sample Userspace Code
         }
         return 0;
 
+Internal Implementation
+=======================
+
+The driver keeps a struct l2tp_tunnel context per L2TP tunnel and a
+struct l2tp_session context for each session. The l2tp_tunnel is
+always associated with a UDP or L2TP/IP socket and keeps a list of
+sessions in the tunnel. The l2tp_session context keeps kernel state
+about the session. It has private data which is used for data specific
+to the session type. With L2TPv2, the session always carried PPP
+traffic. With L2TPv3, the session can also carry ethernet frames
+(ethernet pseudowire) or other data types such as ATM, HDLC or Frame
+Relay.
+
+When a tunnel is first opened, the reference count on the socket is
+increased using sock_hold(). This ensures that the kernel socket
+cannot be removed while L2TP's data structures reference it.
+
+Some L2TP sessions also have a socket (PPP pseudowires) while others
+do not (ethernet pseudowires). We can't use the socket reference count
+as the reference count for session contexts. The L2TP implementation
+therefore has its own internal reference counts on the session
+contexts.
+
+To Do
+=====
+
+Add L2TP tunnel switching support. This would route tunneled traffic
+from one L2TP tunnel into another. Specified in
+http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08
+
+Add L2TPv3 VLAN pseudowire support.
+
+Add L2TPv3 IP pseudowire support.
+
+Add L2TPv3 ATM pseudowire support.
+
 Miscellaneous
-============
+=============
 
-The PPPoL2TP driver was developed as part of the OpenL2TP project by
+The L2TP drivers were developed as part of the OpenL2TP project by
 Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
 designed from the ground up to have the L2TP datapath in the
 kernel. The project also implemented the pppol2tp plugin for pppd
 which allows pppd to use the kernel driver. Details can be found at
-http://openl2tp.sourceforge.net.
+http://www.openl2tp.org.


^ permalink raw reply related

* [PATCH v3 11/12] l2tp: Add support for static unmanaged L2TPv3 tunnels
From: James Chapman @ 2010-03-30 16:18 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20100330161725.9628.69994.stgit@bert.katalix.com>

This patch adds support for static (unmanaged) L2TPv3 tunnels, where
the tunnel socket is created by the kernel rather than being created
by userspace. This means L2TP tunnels and sessions can be created
manually, without needing an L2TP control protocol implemented in
userspace. This might be useful where the user wants a simple ethernet
over IP tunnel.

A patch to iproute2 adds a new command set under "ip l2tp" to make use
of this feature. This will be submitted separately.

Signed-off-by: James Chapman <jchapman@katalix.com>
Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
---
 net/l2tp/l2tp_core.c    |  115 +++++++++++++++++++++++++++++++++++++++++++----
 net/l2tp/l2tp_core.h    |    7 +++
 net/l2tp/l2tp_netlink.c |   18 ++++++-
 3 files changed, 126 insertions(+), 14 deletions(-)

diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 1dd9dc7..994e1d2 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1256,6 +1256,82 @@ void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_free);
 
+/* Create a socket for the tunnel, if one isn't set up by
+ * userspace. This is used for static tunnels where there is no
+ * managing L2TP daemon.
+ */
+static int l2tp_tunnel_sock_create(u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct socket **sockp)
+{
+	int err = -EINVAL;
+	struct sockaddr_in udp_addr;
+	struct sockaddr_l2tpip ip_addr;
+	struct socket *sock;
+
+	switch (cfg->encap) {
+	case L2TP_ENCAPTYPE_UDP:
+		err = sock_create(AF_INET, SOCK_DGRAM, 0, sockp);
+		if (err < 0)
+			goto out;
+
+		sock = *sockp;
+
+		memset(&udp_addr, 0, sizeof(udp_addr));
+		udp_addr.sin_family = AF_INET;
+		udp_addr.sin_addr = cfg->local_ip;
+		udp_addr.sin_port = htons(cfg->local_udp_port);
+		err = kernel_bind(sock, (struct sockaddr *) &udp_addr, sizeof(udp_addr));
+		if (err < 0)
+			goto out;
+
+		udp_addr.sin_family = AF_INET;
+		udp_addr.sin_addr = cfg->peer_ip;
+		udp_addr.sin_port = htons(cfg->peer_udp_port);
+		err = kernel_connect(sock, (struct sockaddr *) &udp_addr, sizeof(udp_addr), 0);
+		if (err < 0)
+			goto out;
+
+		if (!cfg->use_udp_checksums)
+			sock->sk->sk_no_check = UDP_CSUM_NOXMIT;
+
+		break;
+
+	case L2TP_ENCAPTYPE_IP:
+		err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_L2TP, sockp);
+		if (err < 0)
+			goto out;
+
+		sock = *sockp;
+
+		memset(&ip_addr, 0, sizeof(ip_addr));
+		ip_addr.l2tp_family = AF_INET;
+		ip_addr.l2tp_addr = cfg->local_ip;
+		ip_addr.l2tp_conn_id = tunnel_id;
+		err = kernel_bind(sock, (struct sockaddr *) &ip_addr, sizeof(ip_addr));
+		if (err < 0)
+			goto out;
+
+		ip_addr.l2tp_family = AF_INET;
+		ip_addr.l2tp_addr = cfg->peer_ip;
+		ip_addr.l2tp_conn_id = peer_tunnel_id;
+		err = kernel_connect(sock, (struct sockaddr *) &ip_addr, sizeof(ip_addr), 0);
+		if (err < 0)
+			goto out;
+
+		break;
+
+	default:
+		goto out;
+	}
+
+out:
+	if ((err < 0) && sock) {
+		sock_release(sock);
+		*sockp = NULL;
+	}
+
+	return err;
+}
+
 int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp)
 {
 	struct l2tp_tunnel *tunnel = NULL;
@@ -1266,14 +1342,21 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
 	enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP;
 
 	/* Get the tunnel socket from the fd, which was opened by
-	 * the userspace L2TP daemon.
+	 * the userspace L2TP daemon. If not specified, create a
+	 * kernel socket.
 	 */
-	err = -EBADF;
-	sock = sockfd_lookup(fd, &err);
-	if (!sock) {
-		printk(KERN_ERR "tunl %hu: sockfd_lookup(fd=%d) returned %d\n",
-		       tunnel_id, fd, err);
-		goto err;
+	if (fd < 0) {
+		err = l2tp_tunnel_sock_create(tunnel_id, peer_tunnel_id, cfg, &sock);
+		if (err < 0)
+			goto err;
+	} else {
+		err = -EBADF;
+		sock = sockfd_lookup(fd, &err);
+		if (!sock) {
+			printk(KERN_ERR "tunl %hu: sockfd_lookup(fd=%d) returned %d\n",
+			       tunnel_id, fd, err);
+			goto err;
+		}
 	}
 
 	sk = sock->sk;
@@ -1366,7 +1449,10 @@ err:
 	if (tunnelp)
 		*tunnelp = tunnel;
 
-	if (sock)
+	/* If tunnel's socket was created by the kernel, it doesn't
+	 *  have a file.
+	 */
+	if (sock && sock->file)
 		sockfd_put(sock);
 
 	return err;
@@ -1378,13 +1464,22 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
 int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
 {
 	int err = 0;
+	struct socket *sock = tunnel->sock ? tunnel->sock->sk_socket : NULL;
 
 	/* Force the tunnel socket to close. This will eventually
 	 * cause the tunnel to be deleted via the normal socket close
 	 * mechanisms when userspace closes the tunnel socket.
 	 */
-	if ((tunnel->sock != NULL) && (tunnel->sock->sk_socket != NULL))
-		err = inet_shutdown(tunnel->sock->sk_socket, 2);
+	if (sock != NULL) {
+		err = inet_shutdown(sock, 2);
+
+		/* If the tunnel's socket was created by the kernel,
+		 * close the socket here since the socket was not
+		 * created by userspace.
+		 */
+		if (sock->file == NULL)
+			err = inet_release(sock);
+	}
 
 	return err;
 }
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index c5f2cc9..7e3387b 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -146,6 +146,13 @@ struct l2tp_tunnel_cfg {
 	int			debug;		/* bitmask of debug message
 						 * categories */
 	enum l2tp_encap_type	encap;
+
+	/* Used only for kernel-created sockets */
+	struct in_addr		local_ip;
+	struct in_addr		peer_ip;
+	u16			local_udp_port;
+	u16			peer_udp_port;
+	int			use_udp_checksums:1;
 };
 
 struct l2tp_tunnel {
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index e051c13..115ea01 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -129,11 +129,21 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
 	}
 	cfg.encap = nla_get_u16(info->attrs[L2TP_ATTR_ENCAP_TYPE]);
 
-	if (!info->attrs[L2TP_ATTR_FD]) {
-		ret = -EINVAL;
-		goto out;
+	fd = -1;
+	if (info->attrs[L2TP_ATTR_FD]) {
+		fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]);
+	} else {
+		if (info->attrs[L2TP_ATTR_IP_SADDR])
+			cfg.local_ip.s_addr = nla_get_be32(info->attrs[L2TP_ATTR_IP_SADDR]);
+		if (info->attrs[L2TP_ATTR_IP_DADDR])
+			cfg.peer_ip.s_addr = nla_get_be32(info->attrs[L2TP_ATTR_IP_DADDR]);
+		if (info->attrs[L2TP_ATTR_UDP_SPORT])
+			cfg.local_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_SPORT]);
+		if (info->attrs[L2TP_ATTR_UDP_DPORT])
+			cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]);
+		if (info->attrs[L2TP_ATTR_UDP_CSUM])
+			cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]);
 	}
-	fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]);
 
 	if (info->attrs[L2TP_ATTR_DEBUG])
 		cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);


^ permalink raw reply related

* [PATCH v3 10/12] l2tp: Add L2TP ethernet pseudowire support
From: James Chapman @ 2010-03-30 16:18 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20100330161725.9628.69994.stgit@bert.katalix.com>

This driver presents a regular net_device for each L2TP ethernet
pseudowire instance. These interfaces are named l2tpethN by default,
though userspace can specify an alternative name when the L2TP
session is created, if preferred. When the pseudowire is established,
regular Linux networking utilities may be used to configure the
interface, i.e. give it IP address info or add it to a bridge. Any
data passed over the interface is carried over an L2TP tunnel.

Signed-off-by: James Chapman <jchapman@katalix.com>
Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
---
 net/l2tp/Kconfig    |   24 +++
 net/l2tp/Makefile   |    1 
 net/l2tp/l2tp_eth.c |  371 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 396 insertions(+), 0 deletions(-)
 create mode 100644 net/l2tp/l2tp_eth.c

diff --git a/net/l2tp/Kconfig b/net/l2tp/Kconfig
index 0a11ccf..a292270 100644
--- a/net/l2tp/Kconfig
+++ b/net/l2tp/Kconfig
@@ -68,3 +68,27 @@ config L2TP_IP
 
 	  To compile this driver as a module, choose M here. The module
 	  will be called l2tp_ip.
+
+config L2TP_ETH
+	tristate "L2TP ethernet pseudowire support for L2TPv3"
+	depends on L2TP_V3
+	help
+	  Support for carrying raw ethernet frames over L2TPv3.
+
+	  From RFC 4719 <http://www.ietf.org/rfc/rfc4719.txt>.
+
+	  The Layer 2 Tunneling Protocol, Version 3 (L2TPv3) can be
+	  used as a control protocol and for data encapsulation to set
+	  up Pseudowires for transporting layer 2 Packet Data Units
+	  across an IP network [RFC3931].
+
+	  This driver provides an ethernet virtual interface for each
+	  L2TP ethernet pseudowire instance. Standard Linux tools may
+	  be used to assign an IP address to the local virtual
+	  interface, or add the interface to a bridge.
+
+	  If you are using L2TPv3, you will almost certainly want to
+	  enable this option.
+
+	  To compile this driver as a module, choose M here. The module
+	  will be called l2tp_eth.
diff --git a/net/l2tp/Makefile b/net/l2tp/Makefile
index 2c4a14b..bddbf04 100644
--- a/net/l2tp/Makefile
+++ b/net/l2tp/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_L2TP) += l2tp_core.o
 obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
 obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
 obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o
+obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_ETH)) += l2tp_eth.o
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
new file mode 100644
index 0000000..3c4f254
--- /dev/null
+++ b/net/l2tp/l2tp_eth.c
@@ -0,0 +1,371 @@
+/*
+ * L2TPv3 ethernet pseudowire driver
+ *
+ * Copyright (c) 2008,2009,2010 Katalix Systems Ltd
+ *
+ *	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/skbuff.h>
+#include <linux/socket.h>
+#include <linux/hash.h>
+#include <linux/l2tp.h>
+#include <linux/in.h>
+#include <linux/etherdevice.h>
+#include <net/sock.h>
+#include <net/ip.h>
+#include <net/icmp.h>
+#include <net/udp.h>
+#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
+#include <net/tcp_states.h>
+#include <net/protocol.h>
+#include <net/xfrm.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
+#include "l2tp_core.h"
+
+/* Default device name. May be overridden by name specified by user */
+#define L2TP_ETH_DEV_NAME	"l2tpeth%d"
+
+/* via netdev_priv() */
+struct l2tp_eth {
+	struct net_device	*dev;
+	struct sock		*tunnel_sock;
+	struct l2tp_session	*session;
+	struct list_head	list;
+};
+
+/* via l2tp_session_priv() */
+struct l2tp_eth_sess {
+	struct net_device	*dev;
+};
+
+/* per-net private data for this module */
+static unsigned int l2tp_eth_net_id;
+struct l2tp_eth_net {
+	struct list_head l2tp_eth_dev_list;
+	rwlock_t l2tp_eth_lock;
+};
+
+static inline struct l2tp_eth_net *l2tp_eth_pernet(struct net *net)
+{
+	BUG_ON(!net);
+
+	return net_generic(net, l2tp_eth_net_id);
+}
+
+static int l2tp_eth_dev_init(struct net_device *dev)
+{
+	struct l2tp_eth *priv = netdev_priv(dev);
+	struct l2tp_session *session = priv->session;
+	__be32 sid = htonl(session->session_id);
+
+	priv->dev = dev;
+
+	/* Derive a MAC address for the new interface. We use the L2TP
+	 * session's session-id to guarantee a system-wide unique
+	 * address. This MAC is only visible within the L2TP session.
+	 */
+	dev->dev_addr[0] = 0x02; /* IEEE 802 local */
+	dev->dev_addr[1] = 'L';
+	memcpy(&dev->dev_addr[2], &sid, 4);
+	memset(&dev->broadcast[0], 0xff, 6);
+
+	return 0;
+}
+
+static void l2tp_eth_dev_uninit(struct net_device *dev)
+{
+	struct l2tp_eth *priv = netdev_priv(dev);
+	struct l2tp_eth_net *pn = l2tp_eth_pernet(dev_net(dev));
+
+	write_lock(&pn->l2tp_eth_lock);
+	list_del_init(&priv->list);
+	write_unlock(&pn->l2tp_eth_lock);
+	dev_put(dev);
+}
+
+static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct l2tp_eth *priv = netdev_priv(dev);
+	struct l2tp_session *session = priv->session;
+
+	l2tp_xmit_skb(session, skb, session->hdr_len);
+
+	dev->stats.tx_bytes += skb->len;
+	dev->stats.tx_packets++;
+
+	return 0;
+}
+
+static struct net_device_ops l2tp_eth_netdev_ops = {
+	.ndo_init		= l2tp_eth_dev_init,
+	.ndo_uninit		= l2tp_eth_dev_uninit,
+	.ndo_start_xmit		= l2tp_eth_dev_xmit,
+};
+
+static void l2tp_eth_dev_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+
+	dev->netdev_ops		= &l2tp_eth_netdev_ops;
+	dev->destructor		= free_netdev;
+}
+
+static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+{
+	struct l2tp_eth_sess *spriv = l2tp_session_priv(session);
+	struct net_device *dev = spriv->dev;
+
+	if (session->debug & L2TP_MSG_DATA) {
+		unsigned int length;
+		int offset;
+		u8 *ptr = skb->data;
+
+		length = min(32u, skb->len);
+		if (!pskb_may_pull(skb, length))
+			goto error;
+
+		printk(KERN_DEBUG "%s: eth recv: ", session->name);
+
+		offset = 0;
+		do {
+			printk(" %02X", ptr[offset]);
+		} while (++offset < length);
+
+		printk("\n");
+	}
+
+	if (data_len < ETH_HLEN)
+		goto error;
+
+	secpath_reset(skb);
+
+	/* checksums verified by L2TP */
+	skb->ip_summed = CHECKSUM_NONE;
+
+	skb_dst_drop(skb);
+	nf_reset(skb);
+
+	if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) {
+		dev->last_rx = jiffies;
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += data_len;
+	} else
+		dev->stats.rx_errors++;
+
+	return;
+
+error:
+	dev->stats.rx_errors++;
+	kfree_skb(skb);
+}
+
+static void l2tp_eth_delete(struct l2tp_session *session)
+{
+	struct l2tp_eth_sess *spriv;
+	struct net_device *dev;
+
+	if (session) {
+		spriv = l2tp_session_priv(session);
+		dev = spriv->dev;
+		if (dev) {
+			unregister_netdev(dev);
+			spriv->dev = NULL;
+		}
+	}
+}
+
+#ifdef CONFIG_PROC_FS
+static void l2tp_eth_show(struct seq_file *m, void *arg)
+{
+	struct l2tp_session *session = arg;
+	struct l2tp_eth_sess *spriv = l2tp_session_priv(session);
+	struct net_device *dev = spriv->dev;
+
+	seq_printf(m, "   interface %s\n", dev->name);
+}
+#endif
+
+static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
+{
+	struct net_device *dev;
+	char name[IFNAMSIZ];
+	struct l2tp_tunnel *tunnel;
+	struct l2tp_session *session;
+	struct l2tp_eth *priv;
+	struct l2tp_eth_sess *spriv;
+	int rc;
+	struct l2tp_eth_net *pn;
+
+	tunnel = l2tp_tunnel_find(net, tunnel_id);
+	if (!tunnel) {
+		rc = -ENODEV;
+		goto out;
+	}
+
+	session = l2tp_session_find(net, tunnel, session_id);
+	if (session) {
+		rc = -EEXIST;
+		goto out;
+	}
+
+	if (cfg->ifname) {
+		dev = dev_get_by_name(net, cfg->ifname);
+		if (dev) {
+			dev_put(dev);
+			rc = -EEXIST;
+			goto out;
+		}
+		strlcpy(name, cfg->ifname, IFNAMSIZ);
+	} else
+		strcpy(name, L2TP_ETH_DEV_NAME);
+
+	session = l2tp_session_create(sizeof(*spriv), tunnel, session_id,
+				      peer_session_id, cfg);
+	if (!session) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	dev = alloc_netdev(sizeof(*priv), name, l2tp_eth_dev_setup);
+	if (!dev) {
+		rc = -ENOMEM;
+		goto out_del_session;
+	}
+
+	dev_net_set(dev, net);
+	if (session->mtu == 0)
+		session->mtu = dev->mtu - session->hdr_len;
+	dev->mtu = session->mtu;
+	dev->needed_headroom += session->hdr_len;
+
+	priv = netdev_priv(dev);
+	priv->dev = dev;
+	priv->session = session;
+	INIT_LIST_HEAD(&priv->list);
+
+	priv->tunnel_sock = tunnel->sock;
+	session->recv_skb = l2tp_eth_dev_recv;
+	session->session_close = l2tp_eth_delete;
+#ifdef CONFIG_PROC_FS
+	session->show = l2tp_eth_show;
+#endif
+
+	spriv = l2tp_session_priv(session);
+	spriv->dev = dev;
+
+	rc = register_netdev(dev);
+	if (rc < 0)
+		goto out_del_dev;
+
+	/* Must be done after register_netdev() */
+	strlcpy(session->ifname, dev->name, IFNAMSIZ);
+
+	dev_hold(dev);
+	pn = l2tp_eth_pernet(dev_net(dev));
+	write_lock(&pn->l2tp_eth_lock);
+	list_add(&priv->list, &pn->l2tp_eth_dev_list);
+	write_unlock(&pn->l2tp_eth_lock);
+
+	return 0;
+
+out_del_dev:
+	free_netdev(dev);
+out_del_session:
+	l2tp_session_delete(session);
+out:
+	return rc;
+}
+
+static __net_init int l2tp_eth_init_net(struct net *net)
+{
+	struct l2tp_eth_net *pn;
+	int err;
+
+	pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+	if (!pn)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&pn->l2tp_eth_dev_list);
+	rwlock_init(&pn->l2tp_eth_lock);
+
+	err = net_assign_generic(net, l2tp_eth_net_id, pn);
+	if (err)
+		goto out;
+
+	return 0;
+
+out:
+	kfree(pn);
+	return err;
+}
+
+static __net_exit void l2tp_eth_exit_net(struct net *net)
+{
+	struct l2tp_eth_net *pn;
+
+	pn = net_generic(net, l2tp_eth_net_id);
+	/*
+	 * if someone has cached our net then
+	 * further net_generic call will return NULL
+	 */
+	net_assign_generic(net, l2tp_eth_net_id, NULL);
+	kfree(pn);
+}
+
+static __net_initdata struct pernet_operations l2tp_eth_net_ops = {
+	.init = l2tp_eth_init_net,
+	.exit = l2tp_eth_exit_net,
+	.id   = &l2tp_eth_net_id,
+	.size = sizeof(struct l2tp_eth_net),
+};
+
+
+static const struct l2tp_nl_cmd_ops l2tp_eth_nl_cmd_ops = {
+	.session_create	= l2tp_eth_create,
+	.session_delete	= l2tp_session_delete,
+};
+
+
+static int __init l2tp_eth_init(void)
+{
+	int err = 0;
+
+	err = l2tp_nl_register_ops(L2TP_PWTYPE_ETH, &l2tp_eth_nl_cmd_ops);
+	if (err)
+		goto out;
+
+	err = register_pernet_device(&l2tp_eth_net_ops);
+	if (err)
+		goto out_unreg;
+
+	printk(KERN_INFO "L2TP ethernet pseudowire support (L2TPv3)\n");
+
+	return 0;
+
+out_unreg:
+	l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH);
+out:
+	return err;
+}
+
+static void __exit l2tp_eth_exit(void)
+{
+	unregister_pernet_device(&l2tp_eth_net_ops);
+	l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH);
+}
+
+module_init(l2tp_eth_init);
+module_exit(l2tp_eth_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
+MODULE_DESCRIPTION("L2TP ethernet pseudowire driver");
+MODULE_VERSION("1.0");


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox